Twilio语音-允许当前呼叫者收听先前呼叫者记录的语音邮件

时间:2020-08-09 12:01:44

标签: twilio

希望有人可以指出我正确的方向。我希望能够通过Twilio Studio做到这一点。如果没有,我可以学习TwiML。那大约是我的大脑可以伸展的程度。

我在Twilio Studio中做了一个简单的流程,使呼叫者可以记录语音邮件。我想为当前呼叫者添加一个选项,使其能够播放先前呼叫者记录的语音邮件。我认为我需要为此使用说/播放小部件。我需要为“音频文件的URL”使用什么,以便播放以前录制的语音邮件?我假设每次呼叫者离开语音邮件时,此URL都会更改,因此需要自动更新。我可以以某种方式使用“ RecordingURL”吗?有使用TwiML的解决方案吗?任何帮助表示赞赏

谢谢!

1 个答案:

答案 0 :(得分:0)

无法在两次调用之间保持状态,这是不可能的。最好的方法是拥有某种类型的数据库,您可以存储记录SID并在以后的流程中引用它。您可以使用Twilio Sync之类的工具来进行此操作,也可以使用Airtable之类的工具,但它确实需要代码。

我想不出一种方法,而无需进行一些编码。

另一种方法是列出录制记录并将最新的记录从列表中拉出,但这并不理想,因为您不知道最后一次录制何时发生。

另一种方法是修改与您的Twilio电话号码关联的webhook,以便该Studio Flow将最后一个Recording SID传递到您的流中,并使用该SID动态构造要回放的记录URL,如JSON流所示。 (您可以在创建新的Studio Flow时将其导入)。

别忘了将recordStatusStatus回调设置为上述Twilio函数,该函数将更新电话号码Webhook以传递到记录SID中。您可以将“录制语音邮件”小部件的“录制状态回调”设置为指向唯一的功能域和功能路径(当前设置为:https://magnolia-kitty-3234.twil.io/phUpdate)。

随时在下面进行改进并分享。

Twilio功能代码

exports.handler = function(context, event, callback) {
    
    let client = context.getTwilioClient();
    
    const telephoneNumAccountSid = "PN..."; \\ set this to your Phone Number SID
    const accountSid = event.AccountSid; 
    const studioFlowSid = "FW..."; \\ set this to your Studio Flow SID
    const webhookUrl = `https://webhooks.twilio.com/v1/Accounts/${accountSid}/Flows/${studioFlowSid}`;
    const recordingSid = event.RecordingSid;

    client
        .incomingPhoneNumbers(telephoneNumAccountSid)
        .update({ voiceUrl: `${webhookUrl}?recording=${recordingSid}`, voiceFallbackUrl: `${webhookUrl}?recording=${recordingSid}` })
        .then (result => {
             console.log(result.voiceUrl);
             callback(null, "success");
         })
         .catch(err => {
             console.log(err);
             callback("error");
         });
}; 

Studio Flow JSON

{
  "description": "A New Flow",
  "states": [
    {
      "name": "Trigger",
      "type": "trigger",
      "transitions": [
        {
          "event": "incomingMessage"
        },
        {
          "next": "set_variables_1",
          "event": "incomingCall"
        },
        {
          "event": "incomingRequest"
        }
      ],
      "properties": {
        "offset": {
          "x": 0,
          "y": 0
        }
      }
    },
    {
      "name": "split_1",
      "type": "split-based-on",
      "transitions": [
        {
          "next": "say_play_2",
          "event": "noMatch"
        },
        {
          "next": "gather_1",
          "event": "match",
          "conditions": [
            {
              "friendly_name": "{{trigger.call.recording}}",
              "arguments": [
                "{{trigger.call.recording}}"
              ],
              "type": "is_not_blank",
              "value": "Is Not Blank"
            }
          ]
        }
      ],
      "properties": {
        "input": "{{trigger.call.recording}}",
        "offset": {
          "x": 110,
          "y": 350
        }
      }
    },
    {
      "name": "say_play_1",
      "type": "say-play",
      "transitions": [
        {
          "event": "audioComplete"
        }
      ],
      "properties": {
        "play": "https://api.twilio.com/2010-04-01/Accounts/{{flow.variables.accountSid}}/Recordings/{{flow.variables.recording}}.mp3",
        "offset": {
          "x": 450,
          "y": 1110
        },
        "loop": 1
      }
    },
    {
      "name": "set_variables_1",
      "type": "set-variables",
      "transitions": [
        {
          "next": "split_1",
          "event": "next"
        }
      ],
      "properties": {
        "variables": [
          {
            "value": "{{trigger.call.recording}}",
            "key": "recording"
          },
          {
            "value": "{{trigger.call.AccountSid}}",
            "key": "accountSid"
          }
        ],
        "offset": {
          "x": 60,
          "y": 170
        }
      }
    },
    {
      "name": "say_play_2",
      "type": "say-play",
      "transitions": [
        {
          "next": "record_voicemail_1",
          "event": "audioComplete"
        }
      ],
      "properties": {
        "voice": "Polly.Joanna-Neural",
        "offset": {
          "x": -120,
          "y": 650
        },
        "loop": 1,
        "say": "Please leave a message at the beep!",
        "language": "en-US"
      }
    },
    {
      "name": "record_voicemail_1",
      "type": "record-voicemail",
      "transitions": [
        {
          "event": "recordingComplete"
        },
        {
          "event": "noAudio"
        },
        {
          "event": "hangup"
        }
      ],
      "properties": {
        "transcribe": false,
        "offset": {
          "x": -120,
          "y": 860
        },
        "trim": "trim-silence",
        "play_beep": "true",
        "recording_status_callback_url": "https://magnolia-kitty-3234.twil.io/phUpdate",
        "timeout": 5,
        "max_length": 3600
      }
    },
    {
      "name": "gather_1",
      "type": "gather-input-on-call",
      "transitions": [
        {
          "next": "split_2",
          "event": "keypress"
        },
        {
          "event": "speech"
        },
        {
          "event": "timeout"
        }
      ],
      "properties": {
        "number_of_digits": 1,
        "speech_timeout": "auto",
        "offset": {
          "x": 300,
          "y": 650
        },
        "loop": 1,
        "finish_on_key": "#",
        "say": "There is a previous recording, press 1 if you want to listen to it or 2 if you want to leave a new voicemail.",
        "stop_gather": true,
        "gather_language": "en",
        "profanity_filter": "true",
        "timeout": 5
      }
    },
    {
      "name": "split_2",
      "type": "split-based-on",
      "transitions": [
        {
          "event": "noMatch"
        },
        {
          "next": "say_play_1",
          "event": "match",
          "conditions": [
            {
              "friendly_name": "If value equal_to 1",
              "arguments": [
                "{{widgets.gather_1.Digits}}"
              ],
              "type": "equal_to",
              "value": "1"
            }
          ]
        },
        {
          "next": "say_play_2",
          "event": "match",
          "conditions": [
            {
              "friendly_name": "If value equal_to 2",
              "arguments": [
                "{{widgets.gather_1.Digits}}"
              ],
              "type": "equal_to",
              "value": "2"
            }
          ]
        }
      ],
      "properties": {
        "input": "{{widgets.gather_1.Digits}}",
        "offset": {
          "x": 280,
          "y": 870
        }
      }
    }
  ],
  "initial_state": "Trigger",
  "flags": {
    "allow_concurrent_calls": true
  }
}

艾伦