1. Run git clone and create and set your API credentials
- Open a shell session.
- If needed, create a directory where you want to deploy SMS Proxy.
- Change to the directory where you want to install SMS Proxy, and run the following:
- Switch to ./sms-proxy/sms_proxy.
- Using your preferred text editor, open settings.py. In this file, set your API credentials by replacing the FLOWROUTE_SECRET_KEY and FLOWROUTE_ACCESS_KEY with your own:
FLOWROUTE_SECRET_KEY = os.environ.get('FLOWROUTE_SECRET_KEY', None) FLOWROUTE_ACCESS_KEY = os.environ.get('FLOWROUTE_ACCESS_KEY', None)
You can also configure variables here that are used by the application, or alternatively these settings may be passed in as environment variables when you deploy the service. See Configure SMS Proxy for more information.
- Deploy the SMS Proxy service.
git clone https://github.com/flowroute/sms-proxy.git
The git clone command clones the sms-proxy repository as a sub-directory within the parent folder.
2. Deploy the microservice
Deploying the service can be done by either building and running a Docker container as specified by the provided Dockerfile, or by running the application locally with Flask's built-in web server. You can first run the application in test mode before running in production mode.
DEBUG mode
During development, DEBUG_MODE should be set to Truein settings.py in order to use the auto-generated test database. Testing can be performed on this database, which drops data in the tables each time the test module is run. Once the development cycle is over, set DEBUG_MODE to False in order to use the production database. Tests cannot be run when the production database is active.
To run the application using Docker:
- Run the following at the project's top level to build the service:
- Next, run the following:
- From your sms-proxy directory, run:
- Run the following to install the service dependencies at the root level of the project:
- Finally, run:
- In the ./sms-proxy/sms_proxy directory, open settings.py using a text editor.
- Modify any of the following values as needed:
- is assigned to a session to which the user is not a participant of, or
- is not assigned to any active session.
- A virtual phone number is selected at random from the pool. If no virtual phone numbers are available, the following message is returned:
- A session is created between the two participants using an available virtual phone number from the pool.
- The proxy will relay messages sent to the virtual phone number for the number of minutes specified for the expiry_window if set; otherwise, the session will persist indefinitely or until the session is ended through a DELETE request against the session endpoint.
- /
- POST handles the incoming messages received from Flowroute. / is the endpoint that sets the callback URL to the URL set in your Flowroute Manager API settings.
- /tn
POST adds a phone number to your pool of virtual phone numbers.
Example POST Request
- GET retrieves your entire virtual phone number pool. Example GET Request
- DELETE removes a phone number (TN) from your pool of virtual TNs. Example DELETE Request
- /session
- POST starts a new session between participant_a and participant_b. An optional expiration time, in minutes, can be passed indicating when a session should expire. If not passed, the session will not end until a DELETE request is sent. The following examples shows a POST request setting an expiration time of 10 (ten) minutes: Example POST Request
- GET lists all in-progress sessions. Example GET
- DELETE ends the specified session. Example DELETE Request
docker build -t sms_proxy:0.0.1 .
-t tags the image, allowing you to reference it by name instead of by image ID.
docker run -p 8000:8000 sms_proxy:0.0.1
-p binds the container port to the Docker host port. When using a virtualization layer, such as Docker-machine, the API should now be exposed on that host — for example, http://192.168.99.100:8000.
By default, the run command spawns four Gunicorn workers listening on port 8000. To modify the run command, edit the settings in the Docker entry file (Dockerfile) located in the project root.
To run the application locally:
pip install -r requirements.txt
pip install .
python -m sms_proxy.api
The service is set up at the root level.
Flask Documentation
See the Flask documentation for more information about the micro web framework.
3. Configure SMS Proxy
With the service now deployed, configure message settings by customizing settings.py. This allows you to customize session parameters, such as start and end messages, or organization name.
To configure message settings:
ORG_NAME = os.environ.get('ORG_NAME', 'Your Org Name')
SESSION_START_MSG = os.environ.get('SESSION_START_MSG', 'Your new session has started, send a message!')
SESSION_END_MSG = os.environ.get('SESSION_END_MSG', 'This session has ended, talk to you again soon!')
NO_SESSION_MSG = os.environ.get('NO_SESSION_MSG', 'An active session was not found. Please contact support@yourorg.com')
The following fields can be modified in settings.py:
Variable | Required | Data Type | Description |
---|---|---|---|
ORG_NAME | True | string | Sets your organization's name for use in system-generated SMS messages. If the ORG_NAME variable is not changed, Your Org Name is used as the default. |
SESSION_START_MSG | True | string | The message that is sent to both participants when their session has been created. |
SESSION_END_MSG | True | string | The message sent to both participants when a session has been terminated using the DELETE method. This message is not sent for an expired session. |
NO_SESSION_MSG | True | string | The message sent to a user who sends a message to a virtual phone number that |
4. Test it!
Docker commands
Depending on your Docker system configuration, you may be required to preface each docker command with sudo. Read more about it here.
In a test environment, invoke the docker run command with the test argument to run tests and see results. To change the docker run command options, modify the test, coverage, or serve options in the entry script located in the top-level sms-proxy directory.
Docker Entry Points
To learn more about Docker entry points, see Dockerfile Best Practices.
Run the following:
docker run -p 8000:8000 sms_proxy:0.0.1 test
A py.test command is invoked from within the container. When running coverage, a cov-report directory is created that contains an index.html file detailing test coverage results.
5. Add a virtual phone number (TN) and start a session
Once the application is up and running, you can begin adding one or more virtual phone numbers and creating sessions. SMS Proxy has a 1-to-1 mapping of number to session; the more numbers you add to your pool, the more simultaneous sessions you can create.
See Exposed HTTP Resources for more information.
Add a virtual phone number (POST)
To add a virtual phone number to your pool, use a curl POST command, as shown in the following examples:
cURL using Docker
curl -H "Content-Type: application/json" -X POST -d \
'{"value":"1XXXXXXXXXX"}' \
https://<DockerHost>:<port>/tn
cURL using SimpleHTTPServer
curl -H "Content-Type: application/json" -X POST -d \
'{"value":"1XXXXXXXXXX"}' \
http://0.0.0.0:8000/tn
Example Response
{
"message": "Successfully added TN to pool",
"value": "12061231234"
}
The statement takes the following arguments:
Key:Argument | Required | Data Type | Constraint |
---|---|---|---|
value: virtual_tn | True | integer | The 11-digit telephone number used during a session. Participants send and receive their messages from this phone number when it is in use during a session. Virtual phone numbers must be phone numbers that you have purchased from Flowroute. |
https:// |
True | string | The HTTP or HTTPS endpoint where the service is located. The URL path is the IP address of the service. When using a virtualization layer, such as Docker-machine, the API should be exposed on that host. e.g. http://192.168.99.100:8000. |
Important
When using the POST method with JSON, you must also include the complete "Content-Type:application/json" header.
Start a session (POST)
To start a session, use a curl POST command, as shown in the following example:
cURL
curl -H "Content-Type: application/json" -X POST -d \
'{"participant_a":"1XXXXXXXXXX", "participant_b":"1XXXXXXXXXX", "expiry_window": 10}' \
https://<DockerHost>:<port>/session
The statement takes the following arguments:
Key:Argument | Required | Data Type | Constraint |
---|---|---|---|
participant_a:phone_number | True | string | The 11-digit telephone number of the first participant in a session, in E.164 1XXXXXXXXXX format. |
participant_b:phone_number | True | string | The 11-digit telephone number of the second participant in a session, in E.164 1XXXXXXXXXX format. |
expiry_window | False | integer | The number of minutes the session should be active. Any messages received after this time will end the session. Participants will receive a system-generated SMS message indicating that the session has ended. Subsequent messages will trigger a NO_SESSION_MSG from settings.py. |
https:// |
True | string | The HTTP or HTTPS endpoint where the service is located. The URL path is the IP address of the service. When using a virtualization layer, such as Docker-machine, the API should be exposed on that host. e.g. http://192.168.99.100:8000. |
The following then occurs:
{"message": "Could not create session -- No virtual TNs available"}
6. End a session
Run the following DELETE statement to end a session:
cURL
curl -H "Content-Type: application/json" -X DELETE -d '{"session_id":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}' https://&lt;DockerHost&gt;<:port>.com/session
The statement takes the following arguments:
Key:Argument | Required | Data Type | Constraint |
---|---|---|---|
session_id | True | string | A 32-character alphanumeric session identifier. |
https://&lt;DockerHost&gt;:&lt;port&gt; | True | string | The HTTP or HTTPS endpoint where the service is located. The URL path is the IP address of the service. When using a virtualization layer, such as Docker-machine, the API should be exposed on that host. e.g. http://192.168.99.100:8000. |
Exposed HTTP Resources
The following URL resources are supported for the endpoints. The following examples show POST, GET, and DELETE HTTP methods for the applicable URL resource.
See Add a virtual phone number and start a session for descriptions of the fields passed in the request.
curl -H "Content-Type: application/json" \
-X POST -d '{"value":"12062992129"}' \
https://yourdomain.com/tn
Example Response
{
"message": "successfully added TN to pool",
"value": "12062992129"
}
curl -H "Content-Type: application/json" \
-X GET https://yourdomain.com/tn
Example response
{
"available": 0,
"in_use": 1,
"pool_size": 1,
"virtual_tns":
[{"session_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"value": "12062992129"}]
}
The following table describes the fields returned in the response:
Key | Description |
---|---|
available | The number of unreserved virtual phone numbers (TNs). |
in_use | The number of pool sessions currently being used. |
pool_size | The sum of both reserved and unreserved phone numbers (TNs). |
value | The pool identifier. |
curl -H "Content-Type: application/json" -X DELETE -d \
'{"value":"12062992129"}' \
https://yourdomain.com/tn
Example Response
{
"message": "successfully removed TN from pool",
"value": "12062992129"
}
curl -H "Content-Type: application/json" -X POST \
-d '{"participant_a":"1XXXXXXXXXX",
"participant_b":"1XXXXXXXXXX",
"expiry_window": 10}'
https://yourdomain.com/session
A response message is returned indicating a successful POST for the expiration time:
Example Response
{
"virtual_tn": "1XXXXXXXXXX",
"session_id": "366910827c8e4a6593943a28e4931668",
"expiry_date": "2016-05-19 22:19:58",
"participant_b": "12065551213",
"message": "created session",
"participant_a": "12065551212"
}
curl -H "Content-Type: application/json" -X GET https://yourdomain.com/session
Example Response
{
"total_sessions": 1,
"sessions": [
{
"virtual_tn": "1XXXXXXXXXX",
"expiry_date": "2016-05-19 22:19:58",
"participant_b": "12065551212",
"date_created": "2016-05-19 22:09:58",
"participant_a": "12065551213",
"id": "366910827c8e4a6593943a28e4931668"
}
]
}
curl -H "Content-Type: application/json" \
-X DELETE -d \
'{"session_id":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}' \
https://MyDockerHostIP/session
Example Response
{
"message": "successfully ended session",
"session_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}