I have following scenario:
1) Application asks the user to input a phone number.
2) Number is verified on the fly using AddOutgoingCallerId.
3) Application store the number in a session.
All this code is written in a web page say:
http://www.mysite.com/CallNumber.aspx
4) Application now use twilio api to initiate call using InitiateOutboundCall.
5) Using verb Twilio api collects a number and transfers the call to the url mentioned "action" attribute of gather verb.
Imagine it like:
6) Now I want to pass the value stored in session (mentioned in step 3) to be used by http://www.mysite.com/targetpage.aspx.
7) Now even though CallNumber.aspx and targetpage.aspx are on same server, targetpage.aspx always receives session value as null, because call to CallNumber.aspx will be made by a User and call to targetpage.aspx will be made by twilio api server, so there are two different calls.
My ultimate target is to pass the phone number of the user who initiates the call (say Customer1) to the called number, collected by using verb (say Customer 2) .as callerId.
I am adding dropbox link of the image which shows the scenario:
DropBox Link
How can I pass the Customer1's phone number as caller id to Customer 2, as keeping the phone number in session doesn't work (Because calls are initiated from different locations I guess) ?
Twilio evangelist here.
You could pass the phone number received by CallReceived.aspx to targetpage.aspx by appending it to targetpage.aspx as a querystring value:
var result = client.InitiateOutboundCall("+15555555555","+15556666666","http://www.mysite.com/targetsite.aspx?number=%2B15557777777");
Then in targetpage.aspx, you just use the Request object to get the number:
string number = request["number"];
Hope that helps.
Related
I need to automatically make calls for customers and start a interaction with them through voice. Basically, when the customer pickup the phone, my "robot" will ask: "Hey, it seems you didn't finish your order. Would you like to finish by phone?" Customer will say YES, NO, or another phrase, and I will follow the flow.
My questions:
1) What is the best approach to solve this problem using Twilio?
2) It seems Twilio has this functionality (ASR) to understand only for inbound calls when I use functions. How can I do that with outbound calls?
3) Is Twilio ready to understand another languages except English? I need to use Portuguese, Brazil.
Thank you for your help.
Twilio developer evangelist here.
To automatically make calls you will need to use the Twilio Programmable Voice API. I note you're using C# according to the tags, so you can start with the Twilio C# library. Using the library you can make calls with the API like this:
using System;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
class Example
{
static void Main(string[] args)
{
// Find your Account Sid and Auth Token at twilio.com/console
const string accountSid = "your_account_sid";
const string authToken = "your_auth_token";
TwilioClient.Init(accountSid, authToken);
var to = new PhoneNumber("+14155551212");
var from = new PhoneNumber("+15017122661");
var call = CallResource.Create(to,
from,
url: new Uri("http://demo.twilio.com/docs/voice.xml"));
Console.WriteLine(call.Sid);
}
}
For a bit more detail on what all this means, check out the guide on making outbound phone calls with C#.
You will see in that example that we pass a URL to the method that makes the call. This URL can point anywhere, including at a Twilio Function (which is just a Node.js run in the Twilio infrastructure) or your own server. When the call connects to the user Twilio will make an HTTP request to that URL to find out what to do next. To tell Twilio what to do you will need to return TwiML.
To respond with the message that you want and then gather speech input from your user you will need to use the <Say> and <Gather> elements of TwiML. An example response might look like:
<Response>
<Gather input="speech" hints="yes, no" action="/gatherResponse">
<Say voice="alice">Hey, it seems you didn't finish your order. Would you like to finish by phone?</Say>
</Gather>
</Response>
In this case we start with <Gather> so that we can capture anything the user says while the call is speaking to them. We set the input attribute to "speech" so that we can use speech to text to recognise what they say. Also included is the hints attribute which can give hints to the service for the text you expect to hear. Finally, there is an action attribute which is a URL that will be called with the result of this.
You can change the language that the <Gather> expects to hear using the language attribute. There are a number of languages available including Brazilian Portuguese, which you would set with "pt-BR".
Nested inside the <Gather> is a <Say> which you use to read out your message. You can use the voice attribute to change available voices.
The next thing you need to do is respond to the result of the <Gather>. At this stage it depends on what web application framework you are using. The important thing is that when it has a result, Twilio will make an HTTP request to the URL set as the action attribute. In that request will be two important parameters, SpeechResult and Confidence. The SpeechResult has the text that Twilio believes was said and the Confidence is a score between 0.0 and 1.0 for how sure Twilio is about it. Hopefully your result will have "Yes" or "No" (or the Brazilian Portuguese equivalent). At this point you need to return more TwiML to tell Twilio what to do next with the call depending on whether the answer was positive, negative or missing/incorrect. For more ideas on how to handle calls from here, check out the Twilio voice tutorials in C#.
Let me know if that helps at all.
I want to know how can I use GMB API to fetch reviews. According to google documentation we have to make a GET request to https://mybusiness.googleapis.com/v3/{name=accounts/*/locations/*}/reviews
But what is meant by {name=accounts/*/locations/*} and from where we can get the value of accounts & locations.
Also this requires OAuth 2.0. If I get a access_token then GET request will be like this:-
https://mybusiness.googleapis.com/v3/{name=accounts/*/locations/*}/reviews?access_token=token
This is very confusing. Can somebody tell me how to use GMB API correctly to fetch google reviews.
Using Google OAuth 2 Playground
For testing acquisition of Google reviews
Create a project
Console.cloud.google.com
Sign in as {projectowner}#google.com
Select a project from the dropdown in the header or click new project
Go to APIs & Services in the left menu
Enable the Google My Business API; this requires validation by Google and may take a couple of days. They will email you.
Go to developers.google.com/oauthplayground
Using the settings gear, set OAuth flow to Client-side and click Use your own OAuth credentials
Get the client id from console.developers.google.com/apis and paste it in
Put this into scope: https://www.googleapis.com/auth/plus.business.manage and authorize it with {projectowner}#gmail.com
Exchange auth code for token
To get the account name:
Set Request URI to https://mybusiness.googleapis.com/v4/accounts and send a Get request
Copy the entire string value at “name”: not including quotes; it may be 20+ numeric digits
To get location names:
Set Request URI to https://mybusiness.googleapis.com/v4/accounts/{paste account name here}/locations where {paste ... here} is the account name you copied
The returned JSON contains all of your locations
Copy the location names including quotes and commas to a temporary holding document; they will be used in a JSON array in the next step
To get multiple locations’ reviews
a. Set Request URI to https://mybusiness.googleapis.com/v4/accounts/{account name here}/locations:batchGetReviews and the Method to Post
b. Set Request Body to
{
"locationNames": [
"accounts/999999999999999999999/locations/88888888888888888888",
"accounts/999999999999999999999/locations/77777777777777777777",
.
.
.
"accounts/999999999999999999999/locations/11111111111111111111"
],
"pageSize": 200,
"orderBy": "updateTime desc",
"ignoreRatingOnlyReviews": false
}
using the account names you saved from the location JSON for each line of the array
If you have more than 200 total reviews you will have to add "pageToken": string into the JSON body where string is a value returned in the preceding POST.
But what is meant by {name=accounts//locations/} and from where we can get the value of accounts & locations.
To get this details first get the account using the following API (https://mybusiness.googleapis.com/v4/accounts?access_token=#####)
Once you have the account list, fetch Account Location list using the following API (https://mybusiness.googleapis.com/v3/" + name + "/locations) in the response of this API you will get the {name=accounts/*/locations/*}.
Also this requires OAuth 2.0. If I get a access_token then GET request will be like this: https://mybusiness.googleapis.com/v3/{name=accounts/*/locations/*}/reviews?access_token=token
Yes, that is correct.
Let me know if this work's for you.
Is it possible to fetch user's phone number from Twitter Digits callback? I'm using http version and javascript to send SMS with twitter digits.
I only see next information response headers:
{"oauth_echo_headers":{"X-Verify-Credentials-Authorization":"OAuth oauth_consumer_key=\"gmoaaZhEG88hMQUdpWHnF1IAz\", oauth_nonce=\"3375731039-FmyAQgjhQG9rljUaXO3jBbiryF7dFQHeVL5oxu4gmoaaZhEG88hMQUdpWHnF1IAz1437035638029\", oauth_signature=\"TTbPlgipWdaNCSblfx0qznz%2B2Fc%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1437035638\", oauth_token=\"3375731039-FmyAQgjhQG9rljUaXO3jBbiryF7dFQHeVL5oxu4\", oauth_version=\"1.0\"","X-Auth-Service-Provider":"https://api.digits.com/1.1/sdk/account.json"}}
Once you receive the credentials authorization header, you can query the server directly to receive attributes from the Digits service. Per the docs:
/* Validate and log user in. */
function onLogin(loginResponse){
// Send headers to your server and validate user by calling Digits’ API
var oAuthHeaders = loginResponse.oauth_echo_headers;
var verifyData = {
authHeader: oAuthHeaders['X-Verify-Credentials-Authorization'],
apiUrl: oAuthHeaders['X-Auth-Service-Provider']
};
$.post('/verify', verifyData)
.done(function(){ window.reload(); });
}
You can see a sample of this in action in the Cannonball web demo.
May be its late but it can easily be achieved by putting following code wherever you want to fetch phone number:
String phone = Digits.getActiveSession().getPhoneNumber();
I'm using the twilio-csharp helper library. I have a Twilio number, and when someone calls that number, I want to call multiple phones or endpoints like a Twilio Client endpoint and a few phone numbers all at the same time. What is the best way to accomplish this?
The workflow for this functionality looks like this: caller calls a Twilio phone number, Twilio looks up the Voice Request URL associated with that phone number, Twilio sends a TwiML request to the resource at that URL, the resource responds with TwiML instructing Twilio to <Dial> out to several phone numbers, Twilio then calls the phone numbers and connects the caller with the first person to pick up. Note that if you simultaneously <Dial> numbers, when the first phone picks up, the rest of the calls are cancelled.
There are a couple ways to simultaneously <Dial> phone numbers using the twilio-csharp library . The first way to simultaneously <Dial> is to use the DialNumbers method. As the name suggests, DialNumbers will only dial phone numbers, and will only take an array of strings.
The second way to simultaneously <Dial> numbers is to use the Twilio.TwiML.TwilioResponse.Dial(params, Twilio.TwiML.IDialNoun[] dialTargets) method. One of the benefits of using this method is that one can call phone numbers, sip addresses, and/or Twilio Client instances. One can also modify the call attributes, setting the the action URL, timeout limit, or any other dial attribute. Here's a usage example:
public ActionResult SimulDial()
{
var response = new TwilioResponse();
var dialAttributes = new { timeout = 10 };
var dialTargets = new IDialNoun[]
{
new Number("8021111111"),
new Number("8022222222"),
new Client("clientName")
};
response.Dial(dialAttributes, dialTargets);
return TwiML(response);
}
When Twilio receives this TwiML, Twilio will dial out to the three specified endpoints (the two numbers and one client). If no one picks up within 10 seconds, all dialing will be cancelled.
On my page a users (internal staff members) can type a comma separated list of e-mail addresses. What I would like to do is every time a comma is typed it checks that the newly written e-mail address is in the address book.
Currently I have the address book stored as a Hashtable for O(1) search times but I can easily switch to another data structure if it is recommended.
You can do that with JavaScript and AJAX to communicate with the server side.
You can do the next steps:
Create a web service that gets the string from the client (which is the email the user has typed), checks it and returns true/false.
Add [ScriptService] attribute to the
web service class.
On the page, add an ASP.NET
ScriptManager control with
Scripts/ScriptReference that points to the web service from step 1.
On the page, add javascript code that hooks to the onkeydown event of the emails textbox
In this event handler, if the user types a comma, execute a web service request to the server with the textbox value. When the respond (true or false) is received, do whatever you need with it.
You can read more on MSDN here and here.
You might also find helpful the AutoComplete AJAX extender.
In order for it to be done on keypress there is going to be javascript (or client side vbscript if you're using IE) involved. This cannot be done without it if you're looking to do it based on keyed input.
If you were to do it when the user leaves that text box, then you could use AutoPostback and code it in C# on the server side - I have to say though, I think that approach is ugly. Requiring a synchronous postback to validate data is a huge imposition on the user in my opinion and therefore should only really be a last resort or a stopgap while you're getting asynchronous script to do the work. You could also do it at post time (when they're trying to submit the form) and validate them and give the user back a validation message if any of the addresses fail, but once again, this is synchronous and the user doesn't get the benefit of early feedback.
I would do this using either a Windows Service (or use RESTful service) using a javascript call (using the XmlHttpRequest object). Bind your textbox's keydown event to a JavaScript method.
<input type="text" onKeyDown="javascript:CheckInput(this)" />
Then set up your javascript call - this is the guts of what's going on:
(Disclaimer: This code is not production ready, it's merely an example that should give you some direction)
var req;
function CheckInput()
{
if (window.event) keycode = window.event.keyCode;
if (keycode == 188) //KeyCode 188 = Comma;
{
//I haven't provided code for this, you will need to code
//the extraction of the address you wish to test for yourself...
var addressToCheck = ParseLastAddressFromTextBox();
req = new XMLHttpRequest();
//Replace <SERVICEADDRESS> with the URL of your web service
//the 'true' parameter specifies that the call should be asynchronous
req.open("POST", "<SERVICEADDRESS>", true);
req.onreadystatechange = MatchSearchComplete; //This is the callback method
//Set up the post headers
req.setRequestHeader("Host", "localhost");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var params = addressToCheck;
req.setRequestHeader("Content-Length", params.length);
//Iitiate the call to the service
req.send(params); }
}
//The XMLHttpRequest object will fire this method when the
//onreadystatechange event fires...
function MatchSearchComplete()
{
//Check that the response has the correct state and status
//indicating that we've received a response from the server.
if (req.readyState == 4 && req.status == 200)
{
//Our call to the service is complete
var result = req.responseText;
if (result == "false")
alert('The address "'+ req.params +'" is not valid.);
}
}
So what you're doing here is setting up an XMLHttpRequest, pushing the data into it and firing it off to a web service.
Your ASP.NET web application will need a web service built in to it that will be doing the validation of the address.
I might also warn: What if there's only a single address and the user doesn't hit the comma? You should move the guts of the CheckInput() method out to it's own method which parses the addresses. The KeyDown method really should only check if the ',' was pushed. This way you can call the web service to check when the textbox loses focus also. I would also worry about modification of existing addresses without the user hitting the comma again. Therefore, I would wonder about this approach. I would consider that once an address is validated you should have a javascript that only allows that address to be deleted, it shouldn't be editable... whatever approach you take, I'm just warning you that there's some issue with just checking them using the entered ',' approach.
You have to do this with Javascript. After the comma is typed, only then you can pass the email back to C# backend for verification.