Twilio implement a voicemail with javascript sdk - ruby-on-rails

I am currently receiving a call with the use of dequeue command.
_onReservationCreated: (reservation) =>
reservation.dequeue(
null
null
'record-from-answer'
5
'https://myurl/webhooks/twilio/completed'
'completed'
"client:#{reservation.workerName}"
(error, r) =>
if error
console.log(error)
else
console.log(r)
)
I want to send the user to voicemail after the timeout.
on my rails code, I have the webhook which is successfully called.
def completed
message = 'We are currently not able to answer your call, please leave a message'
twiml = Twilio::TwiML::VoiceResponse.new do |response|
response.say(message: message)
response.record
response.hangup
end
render xml: twiml.to_xml
end
The above is not working, the webhook is been triggered but nothing happens.

Twilio developer evangelist here.
You have the webhook URL set up as the dequeueStatusCallbackUrl. Status Callback Webhooks like this are asynchronous, so you can't affect the call by returning TwiML.
The parameters of the callback should include the taskCallSid, so you can use that to call the TaskRouter REST API to update the task, move it to a different workflow or get the CallSid and redirect the call to an endpoint that does then set up the voicemail.

Related

How to ensure Twilio returns the correct event callback?

My calls are connecting fine to the client app, and I can chat over it. However, the status of the call sent during callback events seems to be wrong.
Below is my TwiML.
response = Twilio::TwiML::VoiceResponse.new do |r|
r.dial do |d|
d.client(identity: 'xx#gmail.com',
status_callback_event: 'initiated ringing answered completed',
status_callback: 'https://example.com/twilio_callbacks/call_status',
status_callback_method: 'POST')
end
end
After the call is completed, I receive a callback with parameter CallStatus of no-answer, but checking the logs on Twilio, I was connected, and the call should have a status of completed instead.
What am I doing wrong?
Twilio developer evangelist here.
The completed statusCallback event may have many different statuses, from "no-answer", "busy", "completed", "failed" or "cancelled".
If, however, you believe the call status is wrong, then you should get the call SID and contact Twilio support who can look into what happened with the call.

How do you forward Twilio calls to different URLs in the middle of a call? (Using Node)

I'd like the following functionality with Twilio/Node: either
my server receives incoming call and the call rings on our custom client; at some point during the call (ideally can work before answering or after answering) or if no one answers on the client, the call is transferred to a webhook on a different server (my CRM provider) so the CRM can deal with it. OR
same as above, but the incoming call posts the incoming call request to both my server & my CRM webhook for the incoming call; I think this might not be possible though, not sure
I'm able to receive a Twilio call on my server without problem, and able to receive Twilio calls in my CRM without problem. However, when I tried to forward a call to the CRM after first receiving it on my custom server/client, it seems to always disconnect abrubtly. Pls help!
The code I'm using to update the call is below. The url works normally if sending the call directly to the CRM webhook. The CallSid is from my custom client from the incoming call
client.calls(req.body.CallSid)
.update({method: 'POST', url: 'https://crm.crmprovider.com/ctiapi/xml/cticall/twilio?authtoken=abc'})
Appreciate any help!
Think I figured out the proper way to do this. Should be using an "action" with "dial" and then checking "DialCallStatus" in the action endpoint and dealing with various statuses as appropriate. Sample code:
// On server, receive call. This is the url Twilio is
// set to post webhook to when call comes in
app.post('/incomingCall', (req, res) => {
const twiml = new VoiceResponse();
// Dial client first; after, call /callAction
// I believe this will call /callAction if call is unanswered for 10 seconds or after a completed call or if there's no client open
const dial = twiml.dial({timeout:10, action: '/callAction'});
const client = 'whateverClientName'
dial.client(client)
res.type('text/xml')
res.send(twiml.toString())
})
app.post('/callAction',(req,res)=>{
const twiml = new VoiceResponse();
// Can set below if for other things like if call not completed, answered, or cancelled
// In this example we say if call's not completed, route call to 3rd party site's webhook to further deal with the ongoing call
if(req.body.DialCallStatus!=='completed'){
twiml.redirect({method: 'POST'},'https://thirdpartywebhook.com/abc')}
else {twiml.hangup()}
res.type('text/xml')
res.send(twiml.toString())
})
I didn't find Twilio docs super straightforward on this so hopefully this helps someone in the future!

Twilio - Using conference announce to update caller

My question: Can Twilio Announcements be used when there is only a single participant in the conference?
My Test Application: Is a simple node app that keeps a caller waiting while work is done in the background, with periodic updates on progress to the caller, before finally moving the call to a real person.
The problem: I saw Announcements and that this would excellent for my needs.
My node test app successfully dumps each incoming call into its own unique conference. I later attempt to announce an update on the background processing while the caller is waiting.
client.conferences(conferenceSid)
.update({announceUrl:'https://cccbae85.ngrok.io/twilio/announce'})
.then(result => console.log('success'))
.catch(error => console.log('conference error = ' + error));
The following results:
conference error = Error: The requested resource /2010-04-01/Accounts/ACX*/Conferences/CFb15222ac23964077e8161c819cd9dcca.json was not found
When I change this to use a conference AND participant:
client.conferences(conferenceSid)
.participants (particpantCallSid)
.update({announceUrl:'https://cccbae85.ngrok.io/twilio/announce'})
.then(result => console.log('success'))
.catch(error => console.log('conference error = ' + error));
The result is 'success', meaning the conferenceSid was accepted, but I never see any call to the announceUrl (no errors in Twilio, no attempts through ngok).
So back to my question, can Announcements be used in conferences that have a single participant, or do I need to go back to having a "bot" jump into the conference, say something, and jump back out.
OR - did I royally mess up my understanding of Announce....
Thanks!!

Not getting callback after task reservation fails

I'm using the Twilio TaskRouter. A call comes into our number, Twilio makes an API call to our incoming call endpoint. I send the following response:
<Response>
<Say voice="woman">Thank you for calling</Say>
<Enqueue waitUrl="/Call/HoldMusic" workflowSid="WW..."/>
</Response>
The call is successfully enqueued and my workflow kicks off. I get the workflow assignment callback and respond with the following JSON:
{
"instruction": "dequeue",
"to": "+18885551213",
"timeout": 10,
"status_callback_url": "/Workflow/Changed",
"status_callback_events": "initiated,ringing,answered,completed",
"from": "+18885551212"
}
The outbound call is successfully made to my "to" number. If I accept the call, I get the reservation.accepted event to my task router callback endpoint. If I don't accept the call (let it timeout), I don't get a notification. Because I don't get a notification the dequeue failed, I can't cancel the reservation and have the call ring down through the queue.
I also changed the workflow assignment callback to return a "call" instruction and set the "status_callback_url" but again I only receive a callback if the call is answered, not if the call times out.
Is there something I'm doing wrong, or something fundamental I'm not understanding?
To answer my own question. If you don't include the "status_callback_events" value, then Twilio will send an event for all events. The missing event was no-answer. I'm marking this as answered so that future people can see the list of Twilio events for the dequeue and call instruction.
Current known list of dequeue and call events:
queued
no-answer
initiated
ringing
answered
completed
in-progress
busy
canceled
failed

Instead of using two different phone numbers for a Twilio Queue, could I use one phone for users and the browser client for support reps?

I’m building a queue. I have one phone line, intended for users calling customer support, configured with a Voice URL of example.com/caller. That address returns TwiML that queues the call:
post '/caller' do
response = Twilio::TwiML::Response.new do |r|
r.Say "Welcome to Support, please hold!"
r.Enqueue 'Support Queue'
end
response.text
end
According to the official call queue example I need another phone line for customer support agents to call, that returns TwiML that dequeues a user in the queue. Is it possible for agents instead dequeue users using the browser client instead? Why doesn't this code work?
get '/'
capability = Twilio::Util::Capability.new account_sid, auth_token
# the TwiML app friendly-named 'Agent' has a voice URL set to example.com/agent
capability.allow_client_outgoing 'Agent'
token = capability.generate
erb :support, locals: { token: token }
end
post '/agent' do
response = Twilio::TwiML::Response.new do |r|
r.Dial do |d|
d.Queue 'Support Queue'
end
end
response.text
end
The actual error is that when I make a call from my browser using Twilio.Device.connect() the call hangs up immediately instead of connecting to the user in the queue.
Twilio evangelist here.
I think you need to change the value of the allow_client_outgoing parameter to a TwiML Application SID, which you can create in your account portal or via the REST API. This SID is what lets Twilio know what URL you want us to request when the instance of Client connects to Twilio.
Also, we recently released a new product called TaskRouter which will automatically route queued calls to an available agent, so you not longer have to have an agent dial into the Queue in order to get calls from it.
Hope that helps.

Resources