Twilio功能将无人接听的电话或办公时间以外收到的电话转移到语音邮件,否则拨打sip

时间:2019-07-29 11:29:34

标签: twilio twilio-api twilio-functions

尽管我不确定是从前一阵子复制粘贴它还是默认它,但我已经在“ Twilio函数”部分中拥有此函数了。

var moment = require('moment-timezone')

exports.handler = function(context, event, callback) {

  let now = moment().tz('Australia/Brisbane');

  let isWorkday = (now.isoWeekday() < 6);
  let isWorkingHour = (now.hour() > 7 && now.hour() < 17);
  let response = {};


  if(isWorkday && isWorkingHour) {
    callback(null, response);
  } else {
    callback("Service is closed");
  }  
};

我还找到了另一篇SO帖子,其中有人包含了基本功能,以在呼叫无人接听时转移到语音信箱:

exports.handler = function(context, event, callback) {
    const twiml = new Twilio.twiml.VoiceResponse();
    if (event.DialCallStatus === 'completed' || event.DialCallStatus === 'answered') {
        twiml.hangup();
    } else {
        twiml.say("Service is closed");
        twiml.record({
            transcribe: true,
            transcribeCallback: "http://twimlets.com/voicemail?Email=example@domain.com",
             action: "/hangup"
        });
    }
    callback(null, twiml);
};

我想要做的基本上是将这两个结合在一起:

  1. 如果在!isWorkday || !isWorkingHour处收到呼叫,则直接发送到语音信箱。根本不要打电话。
  2. 如果在isWorkday && isWorkingHour处收到呼叫,则运行如下所示的Twiml bin:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Sip>
      me@myuniqueid.sip.us1.twilio.com;region=au1
    </Sip>
  </Dial>
</Response>
  1. 如果20秒钟内未接听电话,则发送至语音信箱(在步骤1中使用不同的问候语)。

奖金问题:显然,我还需要能够收听语音邮件,因为我怀疑抄写是否会非常准确。创建新的语音邮件时,是否可以在我收到的电子邮件中包含语音邮件(或语音邮件mp3本身)的链接?或者我可以为拨出电话创建一个功能/收件箱,让我拨打一个号码并收听我的语音邮件,就像普通语音邮件的工作原理一样?

1 个答案:

答案 0 :(得分:2)

Heyo,Twilio开发人员推广人员。 ?

我只是设置并在一个函数中构建了您的用例。这个功能里面有很多事情(我可能建议将工作分成几个功能)。

我也很乐意回答您的奖励问题,但请单独打开它以使答案集中。 :)

让我们看一个可行的例子!

const moment = require('moment-timezone');

function isServiceOpen() {
  let now = moment().tz('Australia/Brisbane');
  let isWorkday = now.isoWeekday() < 6;
  let isWorkingHour = now.hour() > 7 && now.hour() < 17;

  return isWorkday && isWorkingHour;
}

exports.handler = function(context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();

  console.log(event);

  const callIncludesRecording = !!event.RecordingUrl;
  const callWasAnswered = event.DialCallStatus === 'completed';
  const callWasNotAnswered = event.DialCallStatus === 'no-answer';
  const serviceIsOpen = isServiceOpen();

  if (callWasAnswered) {
    twiml.hangup();
  } else if (callIncludesRecording) {
    console.log('Call includes recording!');

    // do something with the recording URL here
    console.log(event.RecordingUrl);

    twiml.say("Thank you! We'll come back to you shortly.");
    twiml.hangup();
  } else if (callWasNotAnswered) {
    console.log('Call was not answered...');

    twiml.say(
      'Unfortunately no one can answer right now. But you can leave a message.'
    );
    twiml.record({
      action: '/handle-call'
    });
  } else if (!serviceIsOpen) {
    console.log('Service is closed...');
    twiml.say('Service is closed but you can leave a message');
    twiml.record({
      action: '/handle-call'
    });
  } else {
    twiml.dial(
      {
        action: '/handle-call',
        method: 'POST',
        timeout: 5
      },
      '+4915...'
    );
  }

  callback(null, twiml);
};

您在/handle-call端点下可以使用上面看到的功能,并且可以应答所有呼叫的网络呼叫。

方案1-未接听电话

在函数结尾,您看到dial函数调用。对于这种情况,重要的一点是dial支持timeoutaction属性。

twiml.dial(
  {
    action: '/handle-call',
    method: 'POST',
    timeout: 30
  },
  '+49157...'
);

以上内容告诉Twilio尝试拨打数字+49157... 30秒(实际上接近35,您可以在the docs中阅读详细信息)。如果呼叫结束或在超时之前没有人应答呼叫,则Twilio将向定义的action URL询问其他TwiML配置。

action属性中的URL引用相同的函数路径(/handle-call),并且将再次执行相同的函数,但是这次event对象将包含一个{{1} DialCallStatus中的}(看看变量no-answer)。如果未接听电话,则可以返回TwiML说一条消息,并告诉API开始记录通话。

callWasNotAnswered

record verb还允许使用action attribute,它允许您定义在录制结束时应请求的URL(我们将在相同的// no one answered – let's record twiml.say( 'Unfortunately, no one can answer right now. But you can leave a message.' ); twiml.record({ action: '/handle-call' }); 端点下再次使用相同的功能)

对同一URL的调用将在/handle-call对象的内部包含一个RecordingUrl。如果存在此属性,则您知道它是记录的结果。在这个阶段,是时候对记录URL进行一些操作(发送消息,对其进行记录,...),说完“再见”后结束通话并挂断电话。

event

webhook流程如下:

  1. // do something with the recording URL here console.log(event.RecordingUrl); twiml.say("Thank you! We'll come back to you shortly."); twiml.hangup(); POST(初始Webhook)->拨打+49157 ...
  2. /handle-call POST(超时后致电)->说“很不幸,...”并录音
  3. /handle-call POST(录制完成)->说“谢谢”并挂断电话

方案2-通话时间不在工作时间

对于这种情况,我采用了您已经提供的逻辑并创建了/handle-call辅助函数。当工作时间以外打来电话时,该功能将通过TwiML进行响应,以定义一条消息和一条录音。

isServiceOpen

完成录制后,我们的函数将被称为( twiml.say('Service is closed but you can leave a message'); twiml.record({ action: '/handle-call' }); )。这次,请求将包含一个/handle-call,并且处理方式与方案1中相同(记录记录URL和挂断)。

webhook流程如下:

  1. RecordingUrl POST(初始Webhook)->说“服务已关闭”并记录
  2. /handle-call POST(录制完成)->说“谢谢”并挂断电话

方案3 –呼叫已接听

万一通话发生在营业时间并且被迅速接听,则无需录音。由于拨号动词包含/handle-call属性(我们在方案1中使用了该属性),因此在呼叫结束后将发送另一个Webhook。

此Webhook将包含带有action值的DialCallStatus参数。然后是时候结束通话并挂断电话了。

completed
  1. twiml.hangup(); POST(初始Webhook)->拨打“ +49157 ...”
  2. /handle-call POST(通话结束)->挂断

希望以上内容对您有所帮助。 initially如前所述,将功能分为/handle-call/handle-call和其他功能可能是个好主意。

让我知道是否有帮助,您还有其他问题。 :)