Twilo How to Handle the Timeout in Dial - go

I need to record a voice of my clients who is try to reach one of our advisors. This should happen when there is timeout
User calls -->Number-----> If timeout --> say(Record your message)--> on end of the recording it should call the recordingStatusCallBack
User Call --> Number --> answer call success --> On end of the call it should call method. Not sure where should we put the action either on number (statuscallback) or on the dial Action verb?
To achieve this I am try with the below twiML
<Response>
<Dial callerId="+123124" record="true" timeout="10">
<Number
statusCallback="https://<123134>.ngrok.io/ttwilio/callStatusCallBack"
statusCallbackEvent="completed"
statusCallbackMethod="POST">+1232424/Number>
</Dial>
<Say>Please Record you message</Say>
<Record
recordingStatusCallback=
"https://<123134>.ngrok.io/ttwilio/callStatusCallback"
recordingStatusCallbackMethod="POST"/>
</Response>
This works fine when there is a timeout but when the call is successfully ended twilio still ask for the user to "Please Record you message"
How to achieve this task?

Twilio developer evangelist here.
The behaviour of <Dial> when there is no action attribute is to continue with the TwiML below it once the call is finished, whether by timeout or through a successful call.
If you add a URL as the action attribute, then the behaviour changes and <Dial> will always make a request to the action URL once the call is completed. The important difference here though, is that the URL will be called with a DialCallStatus parameter that will be one of "completed", "answered", "busy", "no-answer", "failed" and "canceled". This way you can check if the call was busy or not answered and return the TwiML for recording a message. Or if the call was completed successfully, you can just return <Hangup/>.
Let me know if that helps at all.

Related

Handling Asynchronous API Call in Jmeter

I am using Jmeter for functional Testing, below is a problem that I am facing and need some help/suggestion on how to overcome that.
I have a thread-group that consists of 2 requests, 1st is API call and 2nd is sending message to Active MQ.
Now the flow is that I need to do first the API call (this will wait for response), then send the message to a particular Active MQ queue and then only I will get the response for the API.
But since jmeter does sequential execution of requests, its get stuck at the API call waiting for the reply and never executes the second part.
I worked on the below solution but even that did not help.
1 Use a parallel controller and put both the API and ACtive MQ call under the same.
2 Add a Timer to the Active MQ call, so that it just did after the API call (2 Sec)
But when I checked in details I see that both the requests are sent at the same time and the timer does not come into effect anywhere.
Any way I can handle this scenario?
Please note I will get a response to the API only when I send message to the particular Active MQ Queue, else it will timeout in a minute.
Your Parallel Controller approach will work, however you need to amend the configuration a little bit, something like:
You could put your ActiveMQ Request under a different Thread Group and use Inter-Thread Communication Plugin for synchronization between threads
You can keep the current setup but replace the JMS Sampler with the JSR223 Sampler and send the message to ActiveMQ programmatically:
Textual code representation for your convenicence:
sleep(2000)
def connectionFactory = new org.apache.activemq.ActiveMQConnectionFactory('your activemq URL')
def connection = connectionFactory.createConnection()
connection.start()
def session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
def destination = session.createQueue('your queue name')
def producer = session.createProducer(destination)
def message = session.createTextMessage('your message body')
producer.send(message)
connection.close()
For your Problem statement, following design will work.
Use 2 Thread Groups, add API call to first Thread group and Message to Active MQ call to second Thread Group
Add a delay to second Thread Group so that it should not run before first Thread Group
Run Test Plan
Use while controller. It will keep on executing till the desired outcome then the next request will be executed.
Hope this helps.
Update:-
While Loop controller execute its samplers until the condition specified is not set to False. The condition can be any variable or function that eventually evaluates to the string 'false'.
So, you need to specify a variable or function in While Loop, that has value 'true' and becomes 'false' somewhere else in the script. Once it changes to 'false', JMeter will exit the While loop.
For example if you are using a X-Path extractor in your script which have a variable named Status and its value changes from 'Start' to 'Finish' during the execution and you want to execute your script till 'Finish' has not been met, then you can use the expression ${__javaScript("'${imp_Status}'!='finish'",)} in your While loop and it will execute the samplers under While controller till the status = finish is met.
It is sort of polling based on certain condition. In your first API reponse, consider one value to be appear as the condition upon which first api call is successful.
It sounds that you just need to define timeout for HTTP Request,
If you define Response Timeout as 60000 (milliseconds), and it will only wait for a minute and then continue to next request
Connect Timeout Connection Timeout. Number of milliseconds to wait for a connection to open. No
Response Timeout Response Timeout. Number of milliseconds to wait for a response. Note that this applies to each wait for a response. If the server response is sent in several chunks, the overall elapsed time may be longer than the timeout.

How to End a "group call" in Sinch

I'm basically following the tutorial on https://www.sinch.com/docs/video/javascript/#groupcalling.
I'm able to get things working, however I am unable to end the call. Right now I have 2 browser tabs pretending to be different users joining the same group chat. "onGroupLocalMediaAdded" and "onGroupRemoteCallAdded" do get called, and I can display things fine. But I can't figure out how a user can leave the group chat and ultimately trigger a call to "onGroupRemoteCallRemoved"
The Call class has a "hangup" method, but GroupCall does not.
any ideas?
Use call conference, it will be with a media server, callgroup will try to set up media to each client and will most likely impact your callquality.
http://download.sinch.com.s3.amazonaws.com/docs/javascript/latest/reference/classes/CallClient.html#method_callConference
I think I figured it out. Group Calling is really peer to peer calling. So hanging up means iterating through each call object you received from a peer and calling hangup.
My terminate connection function now contains:
this.remoteCallsMap.forEach( (call) => {
call.hangup();
});
I'm going to play around with call conference as mentioned in the other responses, but figured I'd post the answer in case anyone else plays around with call group and can't figure out how to end the call.

How Can I Use xmpp4r To Detect The Online/Offline Status Of A Given Jabber ID?

What is the proper xmpp4r way to know if a given contact is online before sending them a message?
Can you post sample xmpp4r code for doing this?
Here is my use case:
If contact online, send :normal message
Else, email contact
Here are things I have working code for:
Send messages of various types
Get a roster/contact list
Register a call back to detect changes in presence
However, I can't find a place that directly addresses a work flow like this:
Loop through each JID in your roster
If jid.is_online? == true, send IM
Else, send email
I've read that you should send a JID a message of type :headline and if that fails, you know the user is offline. In my tests, if the user is ONLINE, they'll receive a message of type headline. This is suboptimal, as users should only receive messages to read, not noise to determine online status.
I've read that on sign on, all of your contacts will bounce a presence status back at you, and that status is the sole indication that they are online - assuming that there isn't a disconnect or presence change you've yet to receive. So you should register a presence call back, record the initial users who ping you back, and then add or remove from the list based on your running roster presence callback.
If this is truly the way to do it:
Can I get some example code of how to collect all the "I'm here" presence confirmations on sign on via xmpp4r?
Why, oh why, was xmpp designed this way and why is this better than offering an "is_online_and_available" method?
So the answer here is adding a message call back and checking inside the block for the type:
m = Message.new(to, body)
cl.send(m)
cl.add_message_callback do |m|
if m.type == :error
puts "type: #{m.type}"
else
puts "not an error"
end
end
This requires threading as you have to be listening for the response.

Twilio: Ruby: Callback status URL for calls running in parallel: Which call completed?

I have a list of phones which must be called by my Twilio app every so often. I have a cron job which runs every minute which makes a list of all phones scheduled to be called in the next minute. The list comprises calls which are scheduled to run in the next minute along with calls which did not complete properly in the last hour.
For each phone in the list, I have code which looks like this (in Ruby) to start off list of phone calls (the list "phones") which will run in parallel, and this snippet runs every minute.
phones.each do |phone|
callbackurl="http://myapp.com/twiliocallback?phone=#{phone.id}"
data={:from=>'16135551234',
:to=>phone.number,
:url=>callbackurl
}
client=Twilio::REST::Client.new(ACCOUNT_SID, ACCOUNT_TOKEN, :ssl_verify_peer => false)
client.account.calls.create data
end
However, if a phone call takes longer than a minute, I don't want the cron job to trigger a call to the same number while it is already in conversation with Twilio. Also, if a person hangs up the phone in the middle of a call before I can update the status, I want that number to be called again triggered by a subsequent cron.
I know that I need a status attribute for the phone call (e.g. phone.status) with the values NOT_STARTED, IN_PROGRESS, and SUCCESSFULLY_COMPLETED, and a twilio_status attribute (e.g. phone.twilio_status), with the values TWILIO_NOT_STARTED, TWILIO_IN_PROGRESS, and TWILIO_COMPLETED.
Calls start off as
phone.status="NOT_STARTED"
phone.twilio_status="TWILIO_NOT_STARTED"
and, and as soon as I create the phone call, I can update the status of the call:
phone.status="IN_PROGRESS"
phone.twilio_status="TWILIO_IN_PROGRESS"
If the call completes properly within the success path, I can set the status
phone.status="SUCCESSFULLY_COMPLETED"
If I can figure out when the call has disconnected from Twilio , then I can tell if a call was aborted by doing this
is_aborted? = twilio.status=="IN_PROGRESS" && twilio.twilio_status=="TWILIO_COMPLETED"
However, I don't know how to run the code
phone.twilio_status="TWLIO_COMPLETED"
for a particular phone call when the phone call hangs up in the middle of a Twilio call workflow or even at the end of a workflow.
Twilio seems to have a callback URL which can be called when a phone call completes, but it is not clear how the callback handler can figure out which of the parallel calls completed. Is there a way to do this so that I can tag the right call with the right status?
In every request to your server throughout the call and in the status callback URL request Twilio passes the unique CallSid value to your server to identify a call. This is also returned to you in the call XML or JSON data that you get back when you first initiate the call.
https://www.twilio.com/docs/api/twiml/twilio_request
https://www.twilio.com/docs/api/rest/making-calls
You can store this CallSid value to track status throughout the call's lifecycle.

Using the xmpp4r Ruby gem, how can I synchronously discover if a contact is online?

I'm new to XMPP and the xmpp4r library, so please forgive my noob question if this is obviously documented somewhere.
What's the most straightforward way, in a synchronous manner, to find out if a given JID is online? (so that I can call something like is_online?(jid) in an if statement)
My details:
I'm writing a Sinatra app that will attempt to send a message to a user when a particular url gets requested on the web server, but it should only try to send the message to the user if that user is currently online. Figuring out if a given JID is online is my problem.
Now, I know that if I connect and wait a few seconds for all the initial presence probe responses to come back to the Roster helper, then I can inspect any of those presences from my Roster and call #online? on them to get the correct value. But, I don't know when all of the presence updates have been sent, so there's a race condition there and sometimes calling #online? on a presence from my roster will return false if I just haven't received that presence probe response yet.
So, my current thinking is that the most straightforward way to find out if someone is online is to construct a new Presence message of type :probe and send that out to the JID that I'm interested in. Here's how I'm doing it right now:
#jabber is the result of Client::new
#email is the jid I'm interested in polling
def is_online?(jabber, email)
online = false
p = Presence.new
p.set_to(email)
p.set_from(jabber.jid)
p.set_type(:probe)
pres = jabber.send(p) do |returned_presence|
online = returned_presence.nil?
end
return online
end
Now, this works in cases where the user is actually online, but when the user is offline, it looks like the presence probe message that comes back is being caught by some other presence_callback handler that doesn't know what to do with it, and my is_online? function never finishes returning a value.
Can anyone help me by providing a simple example is_online? function that I can call, or point me in the right direction for how I can detect when the roster is done getting all the initial presence updates before I try checking a presence for #online?
As it turns out, there's not a synchronous way to ask for a JID presence. You've just got to ask for what you want, then wait for your response handler to fire when the response arrives.

Resources