This article is a continuation of the following article. There are some terms that are uniquely defined in the series of articles, so it is recommended that you read them first. Understanding how it works Twilio # 1-Introduction
This section describes the communication flow when using Twilio and the data structure sent and received.
―― 1. Introduction ―― 1. Definition of basic structure and terms when using Twilio ―― 2. Environment verified this time ―― 2. ** Communication flow data structure ← Now here ** -** 1. Authentication / Capability Token transfer ** -** 2. Call (Incoming Call) from an external phone to your Twilio client ** -** 3. Call from Twilio Client to External Phone (Outgoing Call) ** --3-1. AWS API Gateway + Lambda Implementation Walkthrough (Part 1) ―― 1. Implementation of API Server processing (Python on AWS Lambda) ―― 2. API Gateway settings --3-2. AWS API Gateway + Lambda Implementation Walkthrough (Part 2) --3. Implementing and deploying Twilio Client ―― 4. Operation check!
The Twilio Client we're launching this time aims to be able to do the same thing as a regular phone. The specific specifications are as follows.
――What you can do --From Twilio Client, you can specify any number to make a general call (outbound call) --You can make a call to Twilio Client from a regular phone (inbound call) --Twilio Client specifications --Hold only your Twilio phone number as a value to identify yourself. It does not retain its own Client Name. --Implemented in HTML / JavaScript and placed on S3.
It is assumed that the parameters such as the telephone number are as follows.
Parameters | value | Explanation / Remarks |
---|---|---|
Twilio phone number | 050-3123-4567 | The phone number you assigned to your Twilio Client. Please purchase in advance from the Twilio console. |
Client Name | DeviceId_0001 | A name for identifying and controlling the Twilio Client within Twilio Server. |
External phone | 090-5987-6543 | Phones outside of Twilio. Please use your own mobile phone. |
First, look at the figure below.
The processing flow is as follows.
--1-1. Request to obtain Capability Token --The Twilio Client makes a request to the API Server to get a Capability Token. --API Server authenticates and authorizes as needed based on the information sent by Twilio Client. --1-2. Return of Capability Token --API Server will generate a Capability Token and return it to the Twilio Client. ――At this time, information such as what you can do with the Capability Token (you can make / receive calls), the Client Name of the Twilio Client, and the expiration date will be given. --1-3. Twilio Client Setup --The Twilio Client will perform the necessary setup after successfully receiving the Capability Token. --For JavaScript, run Twilio.Device.setup. (https://www.twilio.com/docs/api/client/device#method-reference) --For Android, run Twilio # createDevice to create a Device object. (https://jp.twilio.com/docs/api/client/android/Twilio#createDevice_String__DeviceListener_) --It seems that the Capability Token is being passed to Twilio Server when performing the setup process. It seems that Twilio Server verifies the Capability Token and returns the success or failure to the Twilio Client. (* Details are unconfirmed)
The implementation of the communication method between 1-1 and 1-2 is entirely up to the user. It is also possible to use HTTP / HTTPS and other protocols for communication.
The data structure is also completely arbitrary. The information you send from Twilio Client can use your username, password, and other information to identify your Twilio Client. It is also possible to realize arbitrary authentication / authorization. Capability Token is required as the information returned from API Server, but any other information can be returned.
In this verification, both request and response are implemented in JSON. The specific data structure is as follows.
The request was simple, just a Twilio phone number. If the specified Twilio phone number has already been obtained, authentication is successful.
"+81-50-1234-9876"}
The response was the Capability Token and the success or failure of the process.
#### **`{"capabilityToken": capabilityToken, "success": True}`**
Communication 1-3 has not been verified. Details are unknown. In the case of JavaScript client, it seems that WebSocket is used to send information such as CapabilityToken to Twilio Server. The initial setup is done from various SDKs provided by Twilio, so you usually don't need to be aware of it. \ # However, I think there may be cases where this information is needed when troubleshooting.
API Server uses Twilio's Helper library to generate Capability Tokens.
The explanation is based on the implementation in Python 2.7. It is assumed that the required libraries are already installed and available. https://www.twilio.com/docs/libraries/python#help In addition, it is assumed that you have opened a Twilio account and have confirmed your Account SID and Auth Token, and that you have created a TwiML App and confirmed your App SID.
from twilio.util import TwilioCapability
import json
def generate_capability_token(twilio_phone_number):
#Set the required parameters.
twilio_account_sid = "{{twilio_accound_sid}}" #Specify the SID of your Twilio account.
twilio_auth_token = "{{twilio_account_auth_token}}" #Specify the Auth Token associated with your Twilio account.
twilio_app_sid = "{{twilio_app_sid}}" #Specify the App Sid created in advance.
expiration_time_for_capability_token = 3600 #Specifies the expiration date of the Capability Token.
#Generate a Capability Token and grant the required permissions.
capability = TwilioCapability(twilio_account_sid, twilio_auth_token)
capability.allow_client_incoming(get_client_name_by_phone_number(twilio_phone_number)) #Gets the Twilio Client Name based on the specified Twilio phone number. get_client_name_by_phone_number is a function that you implement individually.
capability.allow_client_outgoing(twilio_app_sid)
capabilityToken = capability.generate(expiration_time_for_capability_token)
#Convert to the default structure and return.
res = {"capabilityToken": capabilityToken, "success": True}
return json.dumps(res)
Basically, it will be implemented according to the following document. Generate Capability Tokens http://twilio-python.readthedocs.io/en/latest/usage/token-generation.html
After generating Twilio Capability based on your Twilio account SID and Auth Token, grant permissions with the allow_client_incoming and allow_client_outgoing methods. Finally, you can generate a Capability Token by executing the Twilio Capability generate method. You can specify the expiration date in seconds as an argument.
Details of Capability Token can be found in the following documents.
Twilio Client: Capability Tokens https://www.twilio.com/docs/api/client/capability-tokens
Capbility Token is in JWT (Json Web Token) format. No communication with Twilio Server is required for generation. Although it has not been verified, it is presumed that the necessary information is converted to JSON, an electronic signature is generated with Auth Token and given, and then Base64 decoding is performed.
The important points here are as follows. -** The authority to make a call from Twilio Client is different from the authority to receive a call from Twilio Client ** -** Permission to make calls from Twilio Client should be specified in the App sid of the TwiML app ** -** The authority to receive calls with Twilio Client must be specified by Client Name **
Next, let's take a look at how Twilio Client makes calls to other phones.
First, look at the figure below.
Also, remember the URL you set up when you set up your Twilio account and got your phone number. The URL specified in "A CALL COMES IN" will be used when receiving a call.
The processing flow is as follows. ** To get TwiML, the URL set in the recipient's Twilio phone number will be used. ** **
--2-1. Make a call to Twilio Client from an actual phone —— Make a call from your actual phone to the Twilio phone number associated with your Twilio Client. --Of course, you can't specify the Twilio Client Client Name when making a call. ―― 2-2. TwiML acquisition request from Twilio Server to API Server --Twilio Server will issue an HTTP request exactly as specified in "A CALL COMES IN" for the phone number you are calling. --The important parameters passed are the caller's phone number and the recipient's Twilio phone number. --2-3. Return TwiML from API Server to Twilio Server --API Server needs to get the Client Name associated with it based on the Twilio phone number passed as a parameter. --As soon as the Client Name is obtained, TwiML will be generated and returned. ―― 2-4. Twilio Server executes what is written in TwiML. --TwiML will instruct you to connect the phone to the specified Client Name. --Connect the calling phone to your Twilio Client.
The TwiML returned from API Server in No. 2-3 is as follows. This TwiML means to call the specified Twilio Client.
<?xml version="1.0\" encoding="UTF-8"?>
<Response>
<Dial timeout="60">
<Client>DeviceId_0001</Client>
</Dial>
</Response>
You can't specify the Twilio phone number itself in the \
Therefore, API Server needs to get the Client Name based on the recipient's Twilio phone number information in No. 2-3. It is better to save the association information in DB etc. in advance and acquire it when TwiML is generated.
In addition, TwiML can perform various controls. See the official documentation for details.
https://www.twilio.com/docs/api/twiml/dial https://www.twilio.com/docs/api/twiml/client
Requests from Twilio Server to API Server are a bit special. Also, I couldn't find any detailed information in the official documentation. The following is an explanation based on the packet capture information.
The figure above is a packet capture of an HTTP POST request from Twilio Server. The points are as follows.
--Content-Type: must be application / x-www-form-urlencoded --The parameter is a Key Value pair concatenated with "&" in the HTTP request Body and specified on one line (format like GET parameter). --Each parameter in the HTTP request Body must be URL-encoded
Let's look at the details of each parameter. The caller's phone number is "090-5987-6543" and the recipient's Twilio phone number is "050-3123-4567".
Parameters | Description (guess-based) |
---|---|
AccountSid=AC3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | The SID of your Twilio account. |
ApiVersion=2010-04-01 | Is it the API version of Twilio? |
Called=%2B815031234567 | The recipient's Twilio phone number. E.164 format. It seems that the same value as To will be entered. |
CalledCity= | |
CalledCountry=JP | |
CalledState= | |
CalledVia=05031234567 | unknown. Is it used when the call is forwarded within Twilio? |
CalledZip= | |
Caller=%2B819059876543 | The phone number of the calling phone. It seems that the same value as From is entered. |
CallerCity= | |
CallerCountry=JP | |
CallerState= | |
CallerZip= | |
CallSid=CA86nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn | Is it a Unique ID given to the call? |
CallStatus=ringing | |
Direction=inbound | Is it the direction of the call? |
ForwardedFrom=05031234567 | unknown. Is it used when the call is forwarded within Twilio? |
From=%2B819059876543 | The phone number of the calling phone. E.164 format. It seems that the same value as Caller will be entered. |
FromCity= | |
FromCountry=JP | |
FromState= | |
FromZip= | |
To=%2B815031234567 | The recipient's Twilio phone number. It seems that the same value as Called will be entered. |
ToCity= | |
ToCountry=JP | |
ToState= | |
ToZip= |
There are four important parameters here: Caller / From / Called / To. Within the API Server, generate TwiML based on this information.
Python's Quick Start app seems to use Caller as source information and To as recipient information. Therefore, the implementation of the TwiML return API for Incoming Call should also use this parameter.
https://github.com/TwilioDevEd/client-quickstart-python
First, look at the figure below.
Also, remember the URL you set up when you set up your Twilio account and created your TwiML App.
The processing flow is as follows. ** To get TwiML, the URL set in TwiML App will be used. ** **
--3-1. Make an outgoing request from Twilio Client --From Twilio Client, make a request to make a call. --At this time, you can add any parameter from Twilio Client. --For Android, execute the connect method of the Device object generated during setup. (https://www.twilio.com/docs/api/client/android/device#connect_java_util_Map__ConnectionListener_) --For JavaScript, execute the Twilio.Device.connect method. (https://www.twilio.com/docs/api/client/device#connect) --3-2. TwiML acquisition request from Twilio Server to API Server --Twilio Server will issue an HTTP request as specified in the "REQUEST URL" of the TwiML App associated with the CapabilityToken. --The important parameters passed are the Twilio Client Client Name, the called phone number, and the parameters passed by the Twilio Client. --3-3. Return TwiML from API Server to Twilio Server. --API Server needs to get the source Twilio phone number and the destination phone number based on the information passed as a parameter. --As soon as you get the information you need, TwiML will be generated and returned. ―― 3-4. Twilio Server executes what is written in TwiML. --Connect the phone from Twilio Client to the actual phone.
The TwiML returned from API Server in No. 3-3 is as follows. The calling Twilio phone number is "050-3123-4567" and the calling phone number is "090-5987-6543".
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial timeout="60" callerId="+81-50-3123-4567">
<Number>+81-90-5987-6543</Number>
</Dial>
</Response>
In the \
No detailed information was found in the official documentation. The following is an explanation based on the packet capture information.
Let's look at the details of each parameter. The following parameters are added when connect is executed from Twilio Client.
--callerPhoneNumber: The calling phone number associated with you. --callOutgoingPhoneNumber: The actual phone number to call.
Parameters | Description (guess-based) |
---|---|
AccountSid=AC3exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | The SID of your Twilio account. |
ApiVersion=2010-04-01 | Is it the API version of Twilio? |
ApplicationSid=AP75zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz | SID of TwiML App associated with CapabilityToken |
Called= | |
Caller=client%3ADeviceId_0001 | The Client Name of the source Twilio Client. |
CallSid=CA06nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn | Is it a Unique ID given to the call? |
CallStatus=ringing | |
Direction=inbound | |
From=client%3ADeviceId_0001 | The Client Name of the source Twilio Client. It seems that the same value as Caller will be entered. |
To= | |
callerPhoneNumber=%2B81-50-3123-4567 | Custom parameters specified in Twilio Client |
callOutgoingPhoneNumber=%2B81-90-5987-6543 | Custom parameters specified in Twilio Client |
By default, the Client Name is set for Caller and From. If you prefer, you can specify the required parameters in your Twilio Client implementation. As mentioned above, API Server can return any value in the communication when Twilio Client acquires Capability Token, so you can also pass the necessary parameters at the time of connect here.
This concludes the communication flow data structure. From the next, we will finally start implementing. AWS API Gateway + Lambda Implementation Walkthrough (Part 1)