Twilio REST + Rails task without waiting for a response - ruby-on-rails

I have a rake task that on a cron job sends out a bulk of the messages via Twilio (using their Twilio REST client):
def self.twilio_client
Twilio::REST::Client.new(ENV['TWILIO_ACCOUNT_ID'], ENV['TWILIO_TOKEN'])
end
scheduled_messages.each do |scheduled_message|
MessagesSender.twilio_client.messages.create(
:to => scheduled_message.phone_number,
:messaging_service_sid => ENV['TWILIO_MSID'],
:body => scheduled_message.body
)
end
It works totally fine. However, my task waits for each response from Twilio and is not progressing to the next one until previous is finished. As I use Twilio's messaging service, I think I'm not utilising simultaneous sendout using my multiple numbers. As a result, when I have to send 10000 messages, it takes a very very long time to send them all out.
How can I speed up the process? Is it possible at all not to wait for the response? Do I need to do it in threads to utilise the messaging service?
Thanks

Twilio developer evangelist here.
You are being rate limited, even if you're using multiple numbers to send the messages using the messaging service. When you've got that many messages to send its always going to take a long time.
I recommend setting up a background job to process all the messages. That has a couple of benefits: you'd be able to tweak the number of workers you use to get the best possible performance and if a message fails in the middle, the remaining batch of messages will still be sent (which isn't the case with your current code).
I wrote a blog post a while back on how to set up Rails' ActiveJob for sending messages in the background. You could also use a gem like Textris which handles that for you too.
Let me know if this helps.

You are rate limited based on the plan that you have with Twilio.
https://www.twilio.com/help/faq/twilio-basics/how-many-calls-and-sms-messages-per-second-can-my-twilio-account-make?baseUrl=%2Fhelp%2F
Your best bet is to setup delayed processing like delayed job and then just delay each send so that it is processed by your queue.

Related

Handling 3 call queues in twilio in an elegant way

I'd love some advice on my twilio setup for a problem I'm trying to solve.
Overview
A client can call our twilio number and have one of three cases to handle:
- is our client and has a question - should be transfered to CC queue (2ppl),
- wants to buy our services - should be transfered to Sales queue (7ppl),
- has some other case - should be transfered to a different queue, lets call it Other (1 person)
Current solution
The client calls:
welcome message
we gather his digit input
enqueue a call to the appropiate queue
assign a task to an available worker with the conference instruction
Problem with the current solution
If there are no workers in the office to handle the call the client will wait forever until he hangs-up by himself. The wroker who answers doesn't know the clients phone number so he isn't able to fallow-up if neccesary.
Questions
After the client picks a queue i would like to check if I have any workers in the office in that queque (not in Offline mode). If everybody is on offline mode redirect to voicemail and a an email is sent to a specified email address with the caller phone number and voicemail recording url.
After the worker picks-up (accepts the reservation) send him a message with the clients phone number.
If no worker answers within a specified amount of time (for example 5 minutes) the call gets redirected to voicemail and a an email is sent to a specified email address with the caller phone number and voicemail recording url.
Twilio developer evangelist here.
Answers in order, parts 1 and 3 need to talk about voicemail which I'll cover at the bottom:
You can use a skip_if expression to skip a queue if there are no available workers.
I assume this is using the reservation.conference instruction in the JavaScript SDK. You can actually inspect the reservation object at this stage too, check out reservation.task.attributes for all the task attributes, which should include the call attributes. You can use this to show your agent on screen or send them a message some other way.
For this, you should set a timeout on your queue. When the timeout fires the task should drop through to the next queue in the workflow.
Voicemail
For parts 1 and 3 we are ejecting a task from one queue, but it needs to go somewhere else to be dealt with. You want to send the calls to voicemail, which doesn't require an agent to deal with it. Currently, the best way to deal with this is direct the task to a queue that has one bot worker in it. The job of the worker is to redirect incoming reservations straight to some TwiML. You achieve this by instantly responding to an assignment callback with the redirect instruction.
To create voicemail, you can combine <Say> and <Record>. Make sure you set the recordingStatusCallback attribute to a URL in your application, you can then use the results to email the link to the voicemail recording.
Let me know if this helps at all.
thank you for yout time to answer my questions. Below please find my reply:
1. It seems that this does not work in console - I find this information in the documentation "skip_if cannot be configured through the console - it must be posted on the workflow API". As I am not using the workflow API this is probably not a solution for me.
2. I using this tutorial: https://www.twilio.com/docs/quickstart/php/taskrouter/twiml-dequeue-call but instead of using dequeue instruction i use conference. I don't quit get how to "inspect the reservation" - maybe you have a tutorial on that? While looking for other solutions I came up with workspace event calback, but I am not sure if this would work.
3) How can I do that in the console?

How Make Multiple Phone Call in Twilio

i don't know if this question is already asked before because i didn't see any.
I would like to make multiple phone call to my client at fixed time every day. Every day i like to wake up my client at 9.00AM . I have successful to call one number using click-to-call example by using rails.
But i don't an have idea how can i send request to twilio to make multiple call at once without queueing all my call. How can i do so ? I don't want my call to be in queue. Please guide me.
Twilio developer evangelist here.
You can make multiple calls at the same time with Twilio, but there will be an amount of queueing as each account can make one outgoing call per second.
To make the calls at 9am every morning, you could write a Ruby script that runs through a list of numbers that you want to call (you could hardcode this, get numbers from your database or store them any way you want) and initiates a call using the REST API with them.
To schedule the script to run, you could use a cron job to run the script regularly. If you want to use cron in a Ruby way, then check out the whenever gem. Alternatively, if you are using a platform as a service, like Heroku, they tend to have job schedulers too.

Sending SMS from rails app

I am building a medication reminder system using Ruby on Rails to be deployed on heroku.
Using this system a doctor will enter a patient's medication details including medication name, dose as well as timing details and the app will then notify the patient via sms when its time to take his/her medicine.
I have developed the application but I am stuck on the sms part since that involves running a process over and over again until the medication's period has elapsed.
I want to be able to run a script from a rails app that will repeatedly query the database and when it is time to send a sms it will dispatch it to the patient. This cannot function in the normal request/response web cycle.
I explored rubygems that allow developers to create background jobs such as rufus scheduler and resque but I can't seem to figure out how to go about doing this.
Please help I am open to all types of suggestions. I am using Twilio for sending sms
I don't know about resque/rufus, but I know that sidekiq has the ability to queue jobs, but have them delayed till a certain time.
https://github.com/mperham/sidekiq/wiki/Delayed-Extensions#advanced-options
You'd need to look into how exact the delay is (ie. what sidekiq's polling frequency is) depending on your needs, but I would suspect this would work well.
It would require another dynamo or whatever heroku calls it these days.
I use delayed_job using the run_at param to send scheduled SMS via Twilio from Heroku.
I have a send_message method on my message model that does the actual send with the Twilio API. I chose to create a custom job with Delayed Job so when I schedule the message:
Delayed::Job.enqueue my_custom_job, :run_at => TIME_I_WANT_TO_SEND
Using a the heroku worker to run the background task of sending has been very reliable.
Since you're deploying to Heroku, reading their documentation about scheduling jobs is a must for you:
https://devcenter.heroku.com/articles/scheduler

How to notify an API user once a process has been finished?

I have an API where users can create, what I call, orders.
I enqueue those orders and process them via Sidekiq gem. When the process is done, I currently send an email to the user. However, I am looking on how to notify him programatically.
So, sending the user a POST request to a particular endpoint, telling him that the order has been processed.
I am wondering which kind of security or other technical things I should take into account when doing this, or if there is any kind of gem that would help me on developing this.
you can check pub/sub pattern to do this...
when sidekiq finish processing then you publish an event... and you register the browser to listen to this event... which is better than sending the user a POST request to a particular endpoint, telling him that the order has been processed.
there are many libraries out there that can help you implementing the pub/sub pattern check the following...
PubNub
Pusher
Bunny
RabbitMQ
Redis
please note that you will have to use the rails app as the publisher and the front end as the subscriber ( you can check equivalent libs for JS )
and if you are interested in implementing the pub/sub within the same rails app... i've looked a lot and found that only those are the working solutions ( for app to publish and listen to his published events without getting locked in the process )
EventBus
Event_BG_Bus
Wisper
this is a post on how to use those gems to implement pub/sub pattern

Triggering a SWF Workflow based on SQS messages

Preamble: I'm trying to put together a proposal for what I assume to be a very common use-case, and I'd like to use Amazon's SWF and SQS to accomplish my goals. There may be other services that will better match what I'm trying to do, so if you have suggestions please feel free to throw them out.
Problem: The need at its most basic is for a client (mobile device, web server, etc.) to post a message that will be processed asynchronously without a response to the client - very basic.
The intended implementation is to for the client to post a message to a pre-determined SQS queue. At that point, the client is done. We would also have a defined SWF workflow responsible for picking up the message off the queue and (after some manipulation) placing it in a Dynamo DB - again, all fairly straightforward.
What I can't seem to figure out though, is how to trigger the workflow to start. From what I've been reading a workflow isn't meant to be an indefinite process. It has a start, a middle, and an end. According to the SWF documentation, a workflow can run for no longer than a year (Setting Timeout Values in SWF).
So, my question is: If I assume that a workflow represents one message-processing flow, how can I start the workflow whenever a message is posted to the SQS?
Caveat: I've looked into using SNS instead of SQS as well. This would allow me to run a server that could subscribe to SNS, and then start the workflow whenever a notification is posted. That is certainly one solution, but I'd like to avoid setting up a server for a single web service which I would then have to manage / scale according to the number of messages being processed. The reason I'm looking into using SQS/SWF in the first place is to have an auto-scaling system that I don't have to worry about.
Thank you in advance.
I would create a worker process that listens to the SQS queue. Upon receiving a message it calls into SWF API to start a workflow execution. The workflow execution id should be generated based on the message content to ensure that duplicated messages do not result in duplicated workflows.
You can use AWS Lambda for this purpose . A lambda function will be invoked by SQS event and therefore you don't have to write a queue poller explicitly . The lambda function could then make a post request to SWF to initiate the workflow

Resources