Twilio developer evangelist here.
Thanks for the extra detail in the comments. Your receptionist is dialed into a conference to deal with the incoming call using startConferenceOnEnter
to stop the hold music and make the connection. This is a good start.
You say you also have endConferenceOnExit
for the receptionist. I would remove that because in order to achieve this we are going to want to remove the receptionist from the conference and leave the caller in it while we sort out the transfer.
So, instead you're going to want to add hangupOnStar
to your receptionist's TwiML. When the receptionist hits *
the call with either request the action
attribute for the original <Dial>
or, if that is not present, will continue to the next TwiML verb after <Dial>
. Either way, this is where you want to include a <Gather input="dtmf">
. This will start Twilio listening for keypad tones.
Your receptionist can then dial the extension to connect to and press #
to finish (the default finishOnKey
. This will send a webhook to the action
attribute of the <Gather>
with the Digits
in the body of the request. You can then pick those Digits
out and initiate a new call to the user with that extension. When that call connects you can then drop them into the original conference.
So, that should look a bit like:
Receptionist TwiML:
<Response>
<Dial hangupOnStar="true">
<Conference startConferenceOnEnter="true" endConferenceOnExit="false">CALLERS_CONFERENCE_ID</Conference>
</Dial>
<Gather action="/transfer" input="dtmf" finishOnKey="#">
<Say>Please enter the extension you want to dial</Say>
</Gather>
</Response>
Then the /transfer
action should, in pseudo code, do something like:
/transfer
def transfer
extension = params["Digits"]
twilioClient.calls.create( to: getNumberFromExtension(extension), from: TWILIO_NUMBER, url: "https://example.com/connect" )
return "<Response><Hangup/></Response>" # this hangs up the receptionist
end
Finally, the /connect
endpoint referenced in the new call above should return TwiML to drop the new caller into the conference:
<Response>
<Dial>
<Conference startConferenceOnEnter="true" endConferenceOnExit="true">CALLERS_CONFERENCE_ID</Conference>
</Dial>
</Response>
You could even make the /connect
endpoint the same as the original receptionist TwiML, which would allow the next person on the call to also transfer out by pressing *
and dialling another extension.
Let me know if this helps at all.
<Dial><Sip>
or are they just registering to a SIP trunk? – philnash