I am trying to set up a call transfer workflow using Twilio's Outbound Conference Call API. I want the flow to be as follows:
Call PersonA
Initiate a timer via callback when PersonA answers
After introducing myself to PersonA, put them on hold and dial PersonB
Talk to PersonB and let them know I'll be connecting them with PersonA
Merge PersonA and PersonB call together
Leave the phone call and let PersonA and PersonB continue talking.
Looking at the docs here: https://www.twilio.com/docs/api/rest/participant#list-post it appears that this should be doable with a StatusCallback. I am having some trouble getting the callback to work and was wondering if anyone has an example of setting up a call using the Outbound Conference Call API.
Currently I am trying to start the call like so (from and to are the from and to numbers):
params = {
'From' => from,
'To' => to,
'EarlyMedia' => true,
'ConferenceStatusCallbackEvent' => 'start',
'ConferenceStatusCallback' => Rails.application.routes.url_helpers.call_twilio_conference_callback_url(#call, sid: #call.call_sid, host: DEFAULT_DOMAIN)
}
HTTParty.post("https://api.twilio.com/2010-04-01/Accounts/#{TWILIO['account_sid']}/Conferences/#{#call.browser_call_room_key}/Participants",
body: URI.encode_www_form(params),
basic_auth: {username: TWILIO['account_sid'], password: TWILIO['auth_token']})
When I check the twilio debugger I see:
15003 Call Progress: Error Response to Callback URL
If anyone has an example of using the Outbound Conference API and with a callback to your own endpoint that would be awesome! It is a pretty new feature and there does not seem to be much out there as far as examples of it being used.
Twilio developer evangelist here.
Twilio error 15003 means that Twilio received a 4xx or 5xx response from your application. So, Twilio is making a request to your application but it can't reach it for some reason.
Are you having these problems in development because you haven't exposed your local application to Twilio? Have you tried using ngrok for example?
If you have opened up your application, are you seeing errors in your Rails log when the callback occurs?
Related
Ok guys, I've been viewing twilio tutorials for the last couple hours and I seem to just not get it. Can someone give me a basic rundown on how to do the following?
I want to create an app that uses the microphone/speaker of my computer to receive a call.
I have a twilio account with a twilio voice phone # but I just don't seem to get how to connect a JS Device object to a phone #. I think it has something to do with a capability/auth token but can someone give me a step by step on how a phone # can be called and the headset will receive a voice call and begin the conversation. The tutorials show how you can make twilio speak a written statement in twiML but I don't understand how to make it make an actual voice call.
My current guess is that I need to do the following in the browser to accept a call. But I'm not sure what needs to be inside the token.
//I don't know what needs to be in the token in order to connect this
//web page twilio 'Device' to. I use c# but if you have a node.js or php example that would be fine
fetch('https://mybackend/getPhoneToken').then((token) => {
const device = new Device(token);
device.on('incoming', call => {
call.accept();
});
});
Thank you for your help.
This is my first answer, let's see if I can help.
First you have to generate the access token by giving the Voice grant.
Generate access token with your account sid, API key ,API key secret and identity.
access_token = AccessToken(<Account_sid>, <api_key>,<api_secret>, identity=identity)
Note: Identity Should be unique for each user. You can put identity as twiliophonenumber_userid
Grant the Voice incoming Access.
voice_grant = VoiceGrant(outgoing_application_sid=<twiml_sid>,incoming_allow=True)
Add grant to the access_token
access_token.add_grant(voice_grant)
Initialise the Twilio device with this access_token. Then you can make the incoming call to the twilio number and receive the call on browser.
You just need only one Twiml App for all the twilio phone numbes. Create a Twiml App with Request Url and method. (Whenever the js device make/receive calls, then twilio will send a request to this URL to get further instructions)
In the above Request URL function, you have to tell twilio what needs to do with the request. Here is a sample function
function handle_calls():
if outgoing_call:
dial.number(customer_phone_number)
else:
# handle incoming call
dial.client(identity) # This is the same identity which we have given while generating access_token. This will trigger "incoming" event on Js device.
To differentiate between outgoing / incoming calls, you can send extra parameters to twilio while making outgoing calls and handle the request accordingly in the above function (pt. 6). See below sample function.
var params = {"direction":"Outgoing"} # Based on this parameter you can differentiate between outgoing/incoming calls.
device.connect(params)
You can setup status_callback events to better handle the call progress. have a look at this article...https://www.twilio.com/docs/voice/twiml/number#attributes-status-callback-event
Have a look at this article, you can get some more information - https://www.twilio.com/blog/generate-access-token-twilio-chat-video-voice-using-twilio-functions
I'm using the Twilio API to create a Service that will send SMS. The Service should have its own unique webhook endpoint to receive replies (incoming SMS).
var service = ServiceResource.Create(
friendlyName: Campaign.SMSCampaignDisplayName,
usecase: "marketing",
stickySender: true,
useInboundWebhookOnNumber: false,
inboundRequestUrl: new Uri($"<my site>/Admin/twilio/receive/{Campaign.SMSCampaignGuid}")
);
var message = MessageResource.Create(
body: Campaign.SMSCampaignBody,
from: new PhoneNumber(fromNumber),
to: new PhoneNumber(Campaign.SMSCampaignTo),
messagingServiceSid: service.Sid
);
The Service is created and the SMS is successfully sent. In the Twilio console I can see the service has the correct webhook URL:
But when I respond to the SMS, the webhook is not sent. In fact, the incoming message no longer appears in the Twilio console's Monitor > Messaging logs. Note that webhooks and incoming SMS logging was working fine when I was not using a Service and the incoming SMS webhook was defined on the sender phone number.
What am I missing, or is this some issue with Services? Do I need to add a Sender to the Service even though it's sending fine? How do I get the phoneNumberSid?
Edit
I'm dumb, I could have just tested adding the phone number to the Service manually. That indeed did work, but I need to do it programmatically. I'm not having much luck finding the API/endpoint to get the correct phoneNumberSid for this call, does it not exist?
You can use the IncomingPhoneNumber resource, as documented below, to get the Phone Number SID.
List all IncomingPhoneNumber resources for your account
I'm new to twilio. I have the "ultimate sms" plugin from codecanyon set up on my domain and connected to a twilio #. Is there a way to use the same # to set up a studio flow? I'd like to have people be able to send a text like "join" to my current twilio # and I can add them to a distribution list. As far as I can tell, I seem to only be able to set up 1 kind of messaging configuration for incoming messages. If possible, I'd like to use the same # for both workflows. Thank you!
Twilio developer evangelist here.
Twilio numbers process incoming messages by sending a webhook (HTTP request) to a URL. I have not used "Ultimate SMS", but I would assume the plugin requires you to set the Twilio webhook to your application so that it can manage the incoming requests.
Twilio Studio flows like to control the entire conversation, so is probably not a good idea for dealing with this.
You might be able to put some code between the incoming message and the webhook to do things based on whether the body starts with "join". Using a Twilio Function, you could write something like this:
exports.handler = async (context, event, callback) => {
if (event.Body.startsWith("join") {
// Subscribe the user to your list
const response = new Twilio.twiml.MessagingResponse()
response.message("You have subscribed to the list");
callback(null, response);
} else {
// Send the parameters on to the Ultimate SMS webhook URL and respond with the received response
const response = await getResponseFromWebhook(event)
callback(null, response.body);
}
}
This code is just a rough example, but hopefully you get the idea. You can proxy the webhook request through a Function like this (or an API endpoint written in any language if you don't want to use JavaScript or Twilio Functions) and peel off messages you want to by inspecting the body.
Apologies if I've missed something obvious, but...
I'm currently trying to use the Twilio REST API to create a call between a conference call and a video room - ie:
There exists a TwiML app to connect into a conference call (A)
There exists a video room (B)
There exists a SIP Domain (xxx.sip.twilio.com) with its Request URL set to a web service that produces TwiML to connect to the conference call A
I am attempting to join the two with an outgoing SIP call that calls the SIP endpoint and joins the video room
To create the call, I'm using the following code extract to create the call:
var call = CallResource.Create(
to: new Twilio.Types.PhoneNumber($"sip:xxx.sip.ie1.twilio.com?X-FriendlyName={FriendlyName}"),
from: new Twilio.Types.PhoneNumber("username2"),
sipAuthUsername: "xxx",
sipAuthPassword: "xxx",
url: new Uri("https://handler.twilio.com/twiml/<xxx>") // TwiML to connect to the video room
);
...which fails with: Error - 32009 - Dialing SIP Endpoint failure - User not registered
Not sure where to go from here - given the advice on the Twilio debugger indicates that it's the lack of a SIP client registered to the endpoint that's a problem... But there shouldn't be a SIP client involved? I'm just hoping to use the Twilio as a SIP endpoint in the same way as a phone number would be used - ie: to accept incoming calls and execute TwiML instructions.
Hopefully it's clear what I'm trying to ask :)
Twilio Registered SIP end-points must use the US1 region, so you need to modify the URL to be sip:xxx.sip.us1.twilio.com.
You can find more details on how to register a SIP end-point directly to Twilio HERE. The Voice URL for your SIP Domain would return TwiML which would add the SIP end-point as a voice participant using the Connect Verb (Connect a Call to a Room Code Example).
I have a bot that I've built that's running on the Azure Bot Service with a Twilio Channel. I'm sending Proactive activities via my Twilio channel. Everything is working fine. I just got a request that a customer wants to have their own phone number. I would like to just have 1 bot service running but have multiple Twilio phone numbers go into this.
My thought was that I could setup an API service which would then be the incoming message call back / webhook from Twilio which then would use the Directline API to the Bot Framework. It would essentially just replace the https://sms.botframework.com/api/sms service. The problem is that I'm not sure I could still have the proactive messages working - it seems like the Directline 3.0 API works only when a conversation is started first with it.
Does anyone have any thoughts on this if this would work or have any other ideas?
Thanks
Yes, the approach which you mentioned above would be ideal. Each Web App Bot/Bot Channels Registration can only be associated with one Twilio number. I will elaborate on the steps which you mentioned above:
Create a server running the Twilio SMS API code which forwards the messages to the bot via the DirectLine API. The user sends a message to this server.
For every activity sent to the bot, make sure to include the number: Activity.ChannelData = new { fromNumber: <123-456-7890> }. The Server forwards the message to the bot.
You will need to re-attach the fromNumber to the bot's outgoing activity so that your Twilio API server knows where to send the outgoing message to. The Bot sends the reply to the server.
The Twilio API server sends Activity.Text to the user. The Server forwards message from bot to user.
For the proactive messages part, you can add a conversation property to the address param, and set the id to the user's phone number.
Example:
bot.beginDialog(
{
user: { id: '+1234567890' },
bot: { id: '+9876543210' },
conversation: { id: '+1234567890' },
channelId: 'sms',
serviceUrl: 'https://sms.botframework.com'
},
);
Hope this helps.