I have read all similar questions here on SO. The developer evangelist has said to use conference calls from the start or look for and modify the child leg of a call.
Conference calls:
Modifying the child leg doesn't work as it seems (as of at least June 2021) that there is no call sid created for the receiving party ("B" here) of a direct call. Modifying the direct call with new TwiML for instance changes the instructions for the caller ("A" here), dropping the receiving party (B) from the call.
Is there a way to accomplish A calls B then A transfers B to C without dropping B and then A hangs up (not dropping B or C)?
Twilio developer evangelist here.
I think this question and the comments headed off in a roundabout way that wasn't exactly how to solve the initial problem. Here is what I think the real question is and some options for how to solve it:
In this scenario I am guessing that A has placed the call to B using Twilio Client or the Twilio Voice SDK. And that you have a TwiML application that returns TwiML to <Dial>
caller B. To ensure you get the CallSid for caller B's leg you can use <Number>
(or <Client>
or <Sip>
) to provide a statusCallback
URL, like so:
<Response>
<Dial>
<Number statusCallback="WEBHOOK_URL">CALLER_B_NUMBER</Number>
</Dial>
</Response>
In the parameters of the webhook request for the status callbac you will receive a CallSid
, which identifies the outbound leg of the call to B, as well as a ParentCallSid
which identifies the initial leg of the call that A is connected to.
You can then use this CallSid
to update the call using the Calls resource and redirect caller B to new TwiML.
As a note, this will drop caller A, unless you provide further TwiML after the <Dial>
or in the response to a webhook to the URL action
attribute. For example:
<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>
Or
<Response>
<Dial action="/after-outbound-dial">
<Number statusCallback="WEBHOOK_URL">CALLER_B_NUMBER</Number>
</Dial>
</Response>
And then return this in /after-outbound-dial
:
<Response>
<Say>Caller B either hung up or you successfully transferred them away.</Say>
</Response>
The request to the action
URL will include a parameter for DialCallStatus
to let you know what the outcome of the call was so that you can return different results based on whether it was answered, busy, no-answer, etc.
We discussed in the comments using a conference to perform this action. While a conference is more expensive, it can give a much better experience to the person being transferred. In the case I describe above, transferring caller B will be an abrupt change from talking to caller A to whatever TwiML is next. Using a conference call and dialling a 3rd partner, C, into the call can allow for a warm transfer where caller A can introduce C and also fill in C on what is happening with caller B before dropping.
This does only apply in the case where your transfer is between people. If you need to transfer B to something automated, like a post call survey, then my answer above will suffice. It's just worth considering the conference in case there are warm transfer scenarios you want to explore in the future.