How to Slow Down Twilio's TwiML “Say” Command For Programmatically Making Call From the API?

Viewed 154

How can I slow down a code or the entire message content inside the Say tag? Right now by default the speed must be set to x100 or something.

You can not understand a word of what the robot is saying.

The code that I am using to execute the call:

string accountSid = Configuration.AppSettings("TwilioAccountSID");
string authToken = Configuration.AppSettings("TwilioAuthToken");

TwilioClient.Init(accountSid, authToken);

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                                     | SecurityProtocolType.Tls11
                                     | SecurityProtocolType.Tls12
                                     | SecurityProtocolType.Ssl3;

char[] charCodeArr = code.ToString().ToCharArray();
string formattedCode = string.Join(" ", charCodeArr);

var message = CallResource.Create
(                    
    twiml: new Twilio.Types.Twiml("<Response><Say>Your code is " + formattedCode + "</Say></Response>"),
    from: new Twilio.Types.PhoneNumber(Configuration.AppSettings("TwilioPhoneNumber")),
    to: new Twilio.Types.PhoneNumber(phone)
);

I could possibly inject a bunch of commas after every character in the text but there must be a clean way of doing this.

2 Answers

Twilio developer evangelist here.

There are a few ways you can slow the speech down.

The option you posted is certainly one way. Using separate <Say> and <Pause> elements will place a pause between characters or sentences.

You can pause things within a <Say> element too. Punctuation will be used as natural pause, so you could separate your numbers with a period to read them out slower.

For more advanced use, AWS Polly voices support the use of SSML. To slow the rate of speech, you can use the prosody element with the rate attribute. For example:

<Say>
  This is normal speed and <prosody rate="slow">this is much slower</prosody>
</Say>

In your case you could do the following:

char[] charCodeArr = code.ToString().ToCharArray();
string formattedCode = "<prosody rate='slow'>" + string.Join(" ", charCodeArr) + "</prosody>";

var message = CallResource.Create
(                    
    twiml: new Twilio.Types.Twiml("<Response><Say voice='Polly.Matthew'>Your code is " + formattedCode + "</Say></Response>"),
    from: new Twilio.Types.PhoneNumber(Configuration.AppSettings("TwilioPhoneNumber")),
    to: new Twilio.Types.PhoneNumber(phone)
);

I was not able to slow down the voice but I was able to pause the robot in between each number to give the user time to type or write it down. I inserted the <Pause Length="2"/> tag in between each <Say>Digit</Say>.

public static bool VoiceMessage(string phone, int code)
{
        try
        {
            string accountSid = Configuration.AppSettings("TwilioAccountSID");
            string authToken = Configuration.AppSettings("TwilioAuthToken");

            TwilioClient.Init(accountSid, authToken);

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                                            | SecurityProtocolType.Tls11
                                            | SecurityProtocolType.Tls12
                                            | SecurityProtocolType.Ssl3;

            char[] charCodeArr = code.ToString().ToCharArray();
            List<string> charCodeList = new List<string>();                 

            foreach (var c in charCodeArr)
            {
                string charCode = "<Say>" + c + "</Say><Pause length=\"2\"/>";
                charCodeList.Add(charCode);                    
            }

            string formattedCode = string.Join("", charCodeList);

            var message = CallResource.Create(                    
                twiml: new Twilio.Types.Twiml("<Response><Say>Please write down your login code</Say>" + formattedCode + "</Response>"),
                from: new Twilio.Types.PhoneNumber(Configuration.AppSettings("TwilioPhoneNumber")),
                to: new Twilio.Types.PhoneNumber(phone)
            );

            return true;
        }
        catch (Exception exception)
        {
            Log.Exception(exception);

            return false;
        }
}
Related