Just wondering if any Twilio experts can shed some light onto how I might handle having multiple conferences attached to the same Twilio number happening at once.
In the simplest case I would be looking to handle 2 person conferences (so basically just a regular call).
E.g. lets say I have two 2-person conferences scheduled for 1:00 and those two calls are waiting in a queue to be set up. At 1:00 Twilio would pull the first call from the queue and send out outbound calls to connect User A and User B in the first conference, then it would pull the second call from the queue and send out outbound calls to User C and User D to connect them in a second separate conference. Apart from Twilio’s 1-second per call limit is there anything stopping me from using the same Twilio number to connect both separate conferences?
Is it simply the fact that when my app pulls the second call from the queue it is making separate HTTP requests that keeps the two conferences separate even though they're attached to the same number? I’m working in Rails but I’d appreciate input from anyone as to how I might need to handle that in my code.
Twilio developer evangelist here.
As Akhil says, there's no limit on making multiple conferences from the same caller id.
What you might do to accomplish this is set a URL parameter in the URL you pass to the create call method that indicates which conference your users will join. For example:
client = Twilio::REST::Client.new(ACCOUNT_SID, AUTH_TOKEN)
client.calls.create(
:from => YOUR_TWILIO_NUMBER,
:to => user.phone_number,
:url => "/conference?conference_room=#{user.current_conference}"
)
Then, in your route you can look up the conference name and add the user to it.
def conference
conf_room = params[:conference_room]
twiml = Twilio::TwiML::Response.new do |r|
r.Dial do
r.Conference conf_room
end
end
render :xml => twiml.to_xml
end
Let me know if that helps at all!
There is no limitation in making multiple conferences at once from the same caller ID. You can have any number of simultaneous calls from the same number at a time (Respecting twilio's 1 call per second limit).
The key here is to have a unique name for a conference and join users to the correct conference.
Related
I am using twilio gem for making calls in my rails app. Everything is working fine, now I want to add a conference functionality(adding conference functionality is easy) which should ask for pin before joining call, I don't want to add PIN logic manually. If suppose I will add code for entering PIN, how twilio will work to add all those clients to conference who entered PIN correctly. Does twilio support any thing like this? Any body have any idea about this kind of functionality?
Twilio developer evangelist here.
The URL that usha shared is a good start for adding PIN functionality for conferences. There's no automatic way to do it, you need to use a combination of <Gather> and your own logic for the correct PIN to make this work.
In Rails that might look a bit like this:
Initial webhook for incoming calls to the conference number:
def start_conference
response = Twilio::TwiML::VoiceResponse.new
response.gather(:action => conference_gather_url, :num_digits => 4) do |gather|
gather.say("Please enter the code for the conference", :voice => 'alice')
end
return :xml => response.to_xml
end
In this example, when the user enters 4 digits the call will automatically cause a request to the conference_gather_url with the digits that were entered sent as the Digits parameter in the body of the request.
Then the action needs to check that the PIN is correct and allow access to the conference if it is. I have included a pin_is_correct? method below, it is up to you to implement this.
def conference_gather
pin = params["Digits"]
response = Twilio::TwiML::VoiceResponse.new
if pin_is_correct?(pin)
response.dial do |dial|
dial.conference("CONFERENCE_NAME")
end
else
response.say("Your pin was incorrect. Goodbye.")
response.hangup
end
return :xml => response.to_xml
end
Let me know if that helps at all.
I have integrated Twilio through twilio-ruby
with my Rails app. The basic SMS and voice capabilities are working as expected, but now I want to extend my functionality. I would like to be able to generate TwiML in my controller dynamically, save it somewhere (either locally or to a service), and then have Twilio access this XML. For example, a customer makes an order through my app, TwiML is generated and saved, and then Twilio makes a voice call to my supplier with the new order data. Keeping concurrent orders in mind, what might the solution look like for this? What is the best solution for storing the TwiML/XML and then having Twilio access it? Thank you.
Dynamically generating the TwiML during the call does seem like it would be the preferred method.
An example of generating TwimL content dynamically from the docs where we greet a caller by name:
https://www.twilio.com/docs/quickstart/ruby/twiml/greet-caller-by-name#twiml-quickstartrb
require 'rubygems'
require 'sinatra'
require 'twilio-ruby'
get '/hello-monkey' do
people = {
'+14158675309' => 'Curious George',
'+14158675310' => 'Boots',
'+14158675311' => 'Virgil',
'+14158675312' => 'Marcel',
}
name = people[params['From']] || 'Monkey'
Twilio::TwiML::Response.new do |r|
r.Say "Hello #{name}"
end.text
end
Instead of a people array your application would have to parse incoming message bodies (if using SMS) for the order and then make the appropriate call to the supplier.
If however, your use case truly requires creating hosted TwiML on the fly, TwiML Bins in the Twilio Console will soon allow you to do this with interpolation.
That means you would be able to do something like:
curl -X POST api.twilio.com/..../Calls -d 'Url=https://hander.twilio.com/EHxxx?message=hello+world' -u Cxxx:yyyy
And your TwiML Bin would contain the necessary TwiML:
<Response><Say>{{message}}</Say></Response>
This way, you would not need to make two rest calls and wouldn't amass thousands (or more) of redundant bins that will be unwieldy to maintain or clean up.
My app has some heavy callback validations when I create a new customer. Basically I check multiple APIs to see if there's a match before creating a new customer record. I don't want this to happen after create, because I'd rather not save the record in the first place if there aren't any matches.
I have a webhook setup that creates a new customer. The problem is that, because my customer validations take so long, the webhook continues to fire because it doesn't get the immediate response.
Here's my Customer model:
validates :shopify_id, uniqueness: true, if: 'shopify_id.present?'
before_validation :get_external_data, :on => :create
def get_external_data
## heavy API calls that I don't want to perform multiple times
end
My hook:
customer = shop.customers.new(:first_name => first_name, :last_name => last_name, :email => email, :shopify_url => shopify_url, :shopify_id => id)
customer.save
head :ok
customer.save is taking about 20 seconds.
To clarify, here's the issue:
Webhook is fired
Heavy API Calls are made
Second Webhook is fired (API calls still being made from first webhook). Runs Heavy API Calls
Third Webhook is fired
This happens until finally the first record is saved so that I can now check to make sure shopify_id is unique
Is there a way around this? How can I defensively program to make sure no duplicate records start to get processed?
What an interesting question, thank you.
Asynchronicity
The main issue here is the dependency on external web hooks.
The latency required to test these will not only impact your save times, but also prevent your server from handling other requests (unless you're using some sort of multi processing).
It's generally not a good idea to have your flow dependent on more than one external resource. In this case, it's legit.
The only real suggestion I have is to make it an asynchronous flow...
--
Asynchronous vs synchronous execution, what does it really mean?
When you execute something synchronously, you wait for it to finish
before moving on to another task. When you execute something
asynchronously, you can move on to another task before it finishes.
In JS, the most famous example of making something asynchronous is to use an Ajax callback... IE sending a request through Ajax, using some sort of "waiting" process to keep user updated, then returning the response.
I would propose implementing this for the front-end. The back-end would have to ensure the server's hands are not tied whilst processing the external API calls. This would either have to be done using some other part of the system (not requiring the use of the web server process), or separating the functionality into some other format.
Ajax
I would most definitely use Ajax on the front-end, or another asynchronous technology (web sockets?).
Either way, when a user creates an account, I would create a "pending" screen. Using ajax is the simplest example of this; however, it is massively limited in scope (IE if the user refreshes the page, he's lost his connection).
Maybe someone could suggest a way to regain state in an asynchronous system?
You could handle it with Ajax callbacks:
#app/views/users/new.html.erb
<%= form_for #user, remote: true do |f| %>
<%= f.text_field ... %>
<%= f.submit %>
<% end %>
#app/assets/javascripts/application.js
$(document).on("ajax:beforeSend", "#new_user", function(xhr, settings){
//start "pending" screen
}).on("ajax:send", "#new_user", function(xhr){
// keep user updated somehow
}).on("ajax:success", "#new_user", function(event, data, status, xhr){
// Remove "pending" screen, show response
});
This will give you a front-end flow which does not jam up the server. IE you can still do "stuff" on the page whilst the request is processing.
--
Queueing
The second part of this will be to do with how your server processes the request.
Specifically, how it deals with the API requests, as they are what are going to be causing the delay.
The only way I can think of at present will be to queue up requests, and have a separate process go through them. The main benefit here being that it will make your Rails app's request asynchronous, instead of having to wait around for the responses to come.
You could use a gem such as Resque to queue the requests (it uses Redis), allowing you to send the request to the Resque queue & capture its response. This response will then form your response to your ajax request.
You'd probably have to set up a temporary user before doing this:
#app/models/user.rb
class User < ActiveRecord::Base
after_create :check_shopify_id
private
def check_shopify_id
#send to resque/redis
end
end
Of course, this is a very high level suggestion. Hopefully it gives you some better perspective.
This is a tricky issue since your customer creation is dependant on an expensive validation. I see a few ways you can mitigate this, but it will be a "lesser of evils" type decision:
Can you pre-call/pre-load the customer list? If so you can cache the list of customers and validate against that instead of querying on each create. This would require a cron job to keep a list of customers updated.
Create the customer and then perform the customer check as a "validation" step. As in, set a validated flag on the customer and then run the check once in a background task. If the customer exists, merge with the existing customer; if not, mark the customer as valid.
Either choice will require work arounds to avoid the expensive calls.
I'm trying to build a call tracking app to learn twilio and rails. Right now, I'm adding the functioanlity to buy phone numbers.
I want to do an if/else statement in my create action, where if the phone number was saved to the database, and the twilio number was actually purchased, than do this, else do that.
But, the twilio number doesn't return true or false. Here's what they say in their docs :
HTTP POST
Purchases a new phone number for your account. If a phone number is
found for your request, Twilio will add it to your account and bill
you for the first month's cost of the phone number. If Twilio cannot
find a phone number to match your request, you will receive an HTTP
400 with Twilio error code 21452.
So, what I'd like to do is to build an if statement where, if the return is HTTP 400, then do x.
Here's the code I have at present
#This saves the Twilio number to the database, and buys it.
def create
#user = current_user
#phone = #user.phones.build(params[:phone])
client = Twilio::REST::Client.new(#user.twilio_account_sid, #user.twilio_auth_token)
number = client.account.incoming_phone_numbers.create({:phone_number => #phone.twilio_number, :voice_url => VOICE_URL, :voice_method => "POST"})
if #phone.save && number.true
flash[:success] = "Phone Number Created!"
redirect_to user_path
else
render new_phone_path
flash[:error] = "It looks like there were errors with the submission"
end
end
What would I need to change && number.true with, to reference the HTTP 400 Error?
I'm not sure if this is even possible -- so if you have ideas, I'm all ears :).
Three years later and I just wanted to share that we have a fully featured Call Tracking tutorial in Rails to help you get up and running more quickly:
https://www.twilio.com/docs/tutorials/walkthrough/call-tracking/ruby/rails
The application has three main features:
It purchases phone numbers from Twilio to use in different marketing campaigns (like a billboard or a bus advertisement)
It forwards incoming calls for those phone numbers to a salesperson
It displays charts showing data about the phone numbers and the calls they receive
And you'll want to make sure to grab the Ruby helper library before you get started.
I am building an app in Rails 3, using twilio to verify a businesses existance. Basically, when you create a new buisiness I randomly generate a 6 digit number and then call the business phone number with this verification code and the user needs to enter it back in the system to finish the signup process. I am having trouble finding any relevant examples as to how to get this set up. I've found this, but it seems horribly outdated and doesn't work with Rails 3 seemingly. The documentation for the twilio-rb gem is confusing as well.
Does anyone know of any examples or have any code samples that could point me in the right direction?
As I said in the comment on your question itself, I am the author of the twilio-rb gem you mention. Off the top of my head, I would implement a verifications resource that you post a telephone number to.
POST /verifications.voice { telephone_number: '+12125551234' }
In the create action use Twilio::Call.create to create a new call with Twilio
def create
#verification = Verification.new params[:verification]
if #verification.save
Twilio::Call.create to: #verification.telephone_number,
from: YOUR_CALLER_ID, url: verification_url(#verification, format: :voice)
# 201 created and return verification code etc
else
# Handle errors
end
end
You will also want to rescue any API errors that twilio-rb might raise. The url refers to the show action of the verification resource instance. Twilio will then dial the supplied telephone number, and when the call is connected will request the url, e.g. GET /verifications/1.voice so you'll need a show view that asks for the verification code and collects the digits with the <Gather> verb:
res.gather num_digits: 4, action: twilio_hack_verification_url(#verification, :format => :voice), method: 'POST' do |form|
form.say 'Please enter the your 4 digit verification code'
end
Since Twilio currently does not implement the PUT verb, you'll to add a member to your resource
resources :verifications do
member { post 'twilio_hack' }
end
Then in your controller update the object with the user input:
def twilio_hack
#verification = Verification.find(params[:id]).tap do |v|
v.user_input params['Digits']
v.save
end
if #verification.confirmed?
# handle success
else
# handle failure
end
end
Finally in your model you'll need code that generates the verification code, and verifies if it is confirmed
class Verification < ActiveRecord::Base
before_save -> { self[:confirmed] = true if user_input == verification_code }, if: user_input
before_create -> { self[:verification_code] = rand.to_s[2..5] }
end
This is all untested and off the top of my head with about 2 minutes thought, but it should get you started.
When you wish to verify a Business:
Generate a verification code.
Use the Twilio REST API to initiate an outbound call, passing a URL for a callback to a controller which will handle the verification logic. Docs at Twilio are here and an example is here.
This means that you need to pass the verification code into your controller via the callback URL. Use a non-resourceful route with a bound parameter. See here.
Write a controller that handles the call and processes the verification:
Emit TwiML that challenges the user to enter the verification code. I have found using Nokogiri to build the TwiML myself to be the most straightforward approach. (See the method phone_greeting in this simple app I wrote: here.)
If it's correct, flag the Business as verified, congratulate the user, and hang up.
If not, loop.
Hopefully that's enough information to point you in the right direction.
Have you considered using Twilio's Outgoing Caller IDs to help solve this problem?
When calling Twilio over REST to add a new caller id to your account, Twilio will return a 6 digit verification code (property ValidationCode) for you to display in your UI, and then Twilio will automatically call the number and prompt for the code. When the user verifies the number over the phone, their number will be added to your account's caller ids. You can then query Twilio for their phone number over REST (parameter PhoneNumber) to ensure the verification was successful.
See here for documentation:
Add a caller id: http://www.twilio.com/docs/api/rest/outgoing-caller-ids#list-post
Find a caller id: http://www.twilio.com/docs/api/rest/outgoing-caller-ids#list