我们如何将出站 Twilio 语音呼叫转移到另一个号码而不掉线?

问题描述 投票:0回答:2
  • A 向 B 拨打电话
  • A 希望将呼叫转接给 C,而不掉线 B
  • A 然后想挂断电话,让 B 和 C 继续通话

我已经阅读了所有类似的问题。开发人员布道者表示从一开始就使用电话会议或查找并修改通话的子分支。

电话会议:

  • A 创建会议(并隐式加入)
  • A 使用 Webhook 拨打 B,B 会响应加入同一会议的说明
  • A 和 B 正在参加会议
  • A 想要添加 TwiML 在 URL 处定义的 C——不支持
  • A 此时想挂断电话,让 B 和 C 继续参加电话会议

修改子分支不起作用,因为看起来(至少截至 2021 年 6 月)没有为直接呼叫的接收方(此处为“B”)创建呼叫 sid。例如,使用新的 TwiML 修改直接呼叫会更改呼叫者(此处为“A”)的指令,从而将接收方 (B) 从呼叫中删除。

有没有办法实现A呼叫B然后A将B转给C而不掉线B然后A挂断(不掉线B或C)?

twilio
2个回答
1
投票

这里是 Twilio 开发者布道者。

我认为这个问题和评论是以一种迂回的方式开始的,这并不完全是如何解决最初的问题。这是我认为真正的问题以及如何解决它的一些选项:

问题:在参与者 A 和 B 之间的两方通话中,其中 A 拨打 B,我如何向呼叫者 B 发送新的 TwiML 以重定向他们?

在这种情况下,我猜测 A 已使用 Twilio 客户端或 Twilio Voice SDK 向 B 发出了呼叫。并且您有一个 TwiML 应用程序,它将 TwiML 返回给

<Dial>
呼叫者 B。为了确保获得呼叫者 B 的 CallSid,您可以使用
<Number>
(或
<Client>
<Sip>
) ) 提供
statusCallback
URL
,如下所示:

<Response>
  <Dial>
    <Number statusCallback="WEBHOOK_URL">CALLER_B_NUMBER</Number>
  </Dial>
</Response>

在状态回调的 Webhook 请求的参数中,您将收到一个

CallSid
,它标识对 B 的呼叫的出站线路,以及
ParentCallSid
,它标识 A 连接的呼叫的初始线路到.

然后,您可以使用此

CallSid
使用呼叫资源更新呼叫,并将呼叫者 B 重定向到新的 TwiML。

请注意,这将删除呼叫者 A,除非您在

<Dial>
之后或在对 URL
action
属性
的 Webhook 的响应中提供进一步的 TwiML。例如:

<Response>
  <Dial>
    <Number statusCallback="WEBHOOK_URL">CALLER_B_NUMBER</Number>
  </Dial>
  <Say>Caller B either hung up or you successfully transferred them away.</Say>
</Response>

或者

<Response>
  <Dial action="/after-outbound-dial">
    <Number statusCallback="WEBHOOK_URL">CALLER_B_NUMBER</Number>
  </Dial>
</Response>

然后将其返回

/after-outbound-dial
:

<Response>
  <Say>Caller B either hung up or you successfully transferred them away.</Say>
</Response>

action
URL 的请求将包含 DialCallStatus
参数,让您知道呼叫的结果,以便您可以根据是否应答、繁忙、无人应答返回不同的结果。等等

替代品

我们在评论中讨论了使用会议来执行此操作。虽然会议费用更高,但它可以为被转接的人员提供更好的体验。在我上面描述的情况下,转接呼叫者 B 将会从与呼叫者 A 通话到接下来的任何 TwiML 发生突然的变化。使用电话会议并将第三个伙伴 C 拨入通话可以实现热转接,呼叫者 A 可以介绍 C,并在挂断之前向 C 填写与呼叫者 B 发生的事情。

这只适用于您在人与人之间转移的情况。如果您需要将 B 转移到自动化的东西,例如电话后调查,那么我上面的答案就足够了。如果您将来想探索一些温暖的转移场景,那么值得考虑参加这次会议。


0
投票

来自

的回调
await twilioClient.calls.create({
    statusCallback,
    statusCallbackMethod: 'POST',
    statusCallbackEvent: CALL_STATUS_EVENTS,
    machineDetection: 'Enable',
    // machineDetection: 'DetectMessageEnd',
    asyncAmd: 'true',
    asyncAmdStatusCallback,
    asyncAmdStatusCallbackMethod: 'POST',
    url,
    to,
    from,
  });

更新

 client.calls(event.CallSid ?? '')
        .update({ twiml: `<Response><Dial><Number>${process.env.AGENT1_PHONE_NUMBER}</Number></Dial></Response>` })
        .then(call => {
          console.log('==== update', call.to);
        });
© www.soinside.com 2019 - 2024. All rights reserved.