希望有人可以指出我正确的方向。我希望能够通过Twilio Studio做到这一点。如果没有,我可以学习TwiML。那大约是我的大脑可以伸展的程度。
我在Twilio Studio中做了一个简单的流程,使呼叫者可以记录语音邮件。我想为当前呼叫者添加一个选项,使其能够播放先前呼叫者记录的语音邮件。我认为我需要为此使用说/播放小部件。我需要为“音频文件的URL”使用什么,以便播放以前录制的语音邮件?我假设每次呼叫者离开语音邮件时,此URL都会更改,因此需要自动更新。我可以以某种方式使用“ RecordingURL”吗?有使用TwiML的解决方案吗?任何帮助表示赞赏
谢谢!
答案 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
}
}
艾伦