提问者:小点点

如何捕获从twilio发出的呼叫的dtmf代码?


我通过构建一个包含twiml标记的html文件来发送呼叫,并使用php lib向传出号码发出呼叫(参见例如)

$tw_call = $twilio_client->calls->create(
        "+1".$recipient['address'], "+1".$org['twilio_number'], 
        array(
            'Url' => VOICE_CALL_LINK.'/'.$file, (this contains the SAY verbs and text)
            'Timeout' => '30',
            'StatusCallback' => CALLBACK_LINK.'/voice_call_handler.php',
            'StatusCallbackEvent' => array('initiated', 'ringing', 'answered', 'completed')
            )

我想知道是否可以通过我用于拨打电话的方法记录呼叫接收者的dtmf代码?

可以在文本文件中放置额外的回调url吗?如果是这样,我将如何捕获哪个调用正在返回?调用sid是否可用于文本文件中可能的回调url?

好吧,我一定错过了什么。我尝试了以下方法:

<Response>
    <Pause length='1'/>
    <Say voice='alice'>$intro</Say>
    <Pause length='1'/>
    <Say voice='alice'>$msg_body</Say>
    <Pause length='1'/>
    <Gather action='absolute html path' numDigits='1'>
        <Say Please respond by selecting 1 for I can come.  Select 2 for I cannot come.</Say>
    </Gather>
</Response>";

我从Twilio回来“发生了应用程序错误”。如果我删除收集标签和收集标签中的说标签,我会收到一个完美的呼叫。

如果我离开标签并删除操作和路径,也会发生同样的错误。

你能收集呼出电话的回复吗?我问是因为所有twilio文档都指呼入电话。


共2个答案

匿名用户

Twilio开发者布道者在这里。

为了从呼叫中捕获DTMF音调,您可以使用

TwiML可能看起来像这样:

<Response>
  <Gather action="/gather_result.php" numDigits="1">
    <Say>Welcome to the free beer hotline, dial 1 for free beer, dial 2 for other beverages.</Say>
  </Gather>
</Response>

然后,当用户拨打号码时(您可以使用numDigits属性控制有多少数字),Twilio将向action属性中的URL发出请求。该请求中将包含一个Digits参数,该参数将包含用户按下的数字。调用SID也将在参数中。

如果有帮助,请告诉我。

匿名用户

我也遇到过类似的问题,Gather TwiML没有从twilio发出的呼叫中捕获用户dtmf输入。由于某些原因,它无法捕获我的输入数字。我确实按了1#,但语音消息一直在播放并重复相同的消息。有时它有效,twilio能够获得我输入的数字,但我尝试的次数超过80%,它无法捕获输入的数字。下面是节点js中的TwiML如下所示:

var promise = new Parse.Promise();

twilioClient.calls.create({
    to: phoneNumber,
    from:'+6598124124',
    url: hosturl + '/gather_user_dial',
    body: callParam,
    statusCallback: hosturl + '/callback_user',
    statusCallbackMethod: 'POST',
    statusCallbackEvent: ["completed", "busy", "no-answer", "canceled", "failed"]
}).then(function(call) {
    if (res) res.success(call);
    promise.resolve(call);
}, function(error) {
    console.error('Call failed!  Reason: ' + error.message);
    if (res) res.error(error);
    promise.reject(error);
});
app.post('/gather_user_dial', (request, response) => {
  const twiml = new VoiceResponse();

  const gather = twiml.gather({
    numDigits: 1,
    timeout: 5,
    actionOnEmptyResult: true,
    action: '/gather',
  });
  gather.say('You are receiving a call from company A because you press the emergency button. Press 1 if you are okay or Press 9 if you need help, followed by the pound sign.');

  twiml.redirect('/gather_user_dial');
  response.type('text/xml');
  response.send(twiml.toString());
});

app.post('/gather', (request, response) => {
  const twiml = new VoiceResponse();
  if (request.body.Digits) {
    switch (request.body.Digits) {
      case '1':
        twiml.say('User has been notified!');
        userPressOne(request.body.Called);
        break;
      case '9':
        twiml.say('User has been notified!');
        userPressNine(request.body.Called);
        break;
      default:
        twiml.say("Sorry, I don't understand that choice.").pause();
        twiml.redirect('/gather_user_dial');
        break;
    }
  } else {
      twiml.redirect('/gather_user_dial');
  }
  response.type('text/xml');
  response.send(twiml.toString());
});