Using a Serverless framework like Fission.io is a quick, and portable way to create an application layer between highly-programmable services like Twilio and Slackβββcommon, but not always easily automated and integrated, services for developers to program communication services like SMS, voice, and chat services. Fission addresses this by allowing you to run lightweight programs that can consume and operate on request data, and in our scenario, act as an orchestrator or router for these communication tools.
What weβre going to create is two Fission tasks, small Python (in our case) programs, to receive a number and a message to go out through Slack to Twilio to the intended recipient, and when your Twilio SMS number receives a message, it is delivered to Slack.
Prerequisites
Youβll need from Slack an incoming webhook (to post messages to a channel) and a Slash Command (to have Fission trigger your function via POST requests from Slack on this webhook):
Make a note of the hooks.slack URL for your Fission task in a moment. Then, create your Slack app for a Slash Command, something like /twilio :
From Twilio, youβll just need your Account SID, API token, and an SMS-capable Twilio number:
you will also, once the tasks are deployed (because youβll need the Fission URL you end up creating), create a Twilio Webhook for any one of your numbers:
Configuring Phone Numbers to Receive and Respond to SMS and MMS Messages
Creating our Functions
In send.py weβre going to create the script that runs when your Slash Command is run (a POST request from Slack to Fission):
import json
import requests
import urllib
from flask import request, redirect
from twilio.rest import Client
CHANNEL\_NAME="twilio"
SLACK\_TOKEN=""
TWILIO\_SENDER="" #Number with Country code
LIMIT\_TO\_CC="" #i.e. +1
In this section, replace SLACK_TOKEN with your Slack App token, define the CHANNEL you want the response form the Slack API into (ideally the same one where the command will be run), and then optionally add the country code to limit SMS messages to (so you can have users provide a 10-digit phone number), and your Twilio number in TWILIO_SENDER .
In our main() function (Fissionβs default entrypoint for Python tasks), weβll need to do some setup so it can pick apart the body from Slack when a slash command like /twilio send:8325551900 hello, how are you hits your Fission task:
_def_ main():
params = urllib.parse.parse\_qs(_str_(request.get\_data()))
incoming\_token = params["b'token"][0]
channel\_name = params['channel\_name'][0]
response\_url = params['response\_url'][0]
message = params['text'][0]
Thereβs a couple of new pieces here, the incoming_token which weβll revisit in a moment to ensure it matches the desired token for the Slack app, and response_url which will give us a URL to POST a response back to with the status of the request.
Weβll, next, add some Help text, and then start slicing up the message:
jmarhee/fission-twilio-sms-slack
so weβre separating out the number from the message text, and then handing it to our twilio_conn function (which Iβll cover in a second) and send that response back to the Slack response URL so you can see if your message was sent properly or not in slack_callback :
jmarhee/fission-twilio-sms-slack
At this point, we can create this function:
fission function create --name twilio\_send --env python3 --route /twilio\_send --method POST --code send.py
and give the URL http://$FISSION_ROUTER/twilio_send to your Slack appβs Slash Command to POST to.
Our next step will be to create an endpoint for Twilio to send requests to, so weβll do similar setup on our recv.py script. For this, youβll just need your Incoming Webhook URL from Slack:
jmarhee/fission-twilio-sms-slack
Before we go any further, letβs take a look at the sort of data Twilio sends over this webhook. In our example, weβll get GET requests from Twilio that look like this:
"GET /twil?ToCountry=US&ToState=CO&SmsMessageSid=&NumMedia=0&ToCity=&FromZip=&SmsSid=&FromState=TX&SmsStatus=received&FromCity=&Body=Dhdhdhdhsh&FromCountry=US&To=%&ToZip=&NumSegments=1&MessageSid=&AccountSid=&From=%&ApiVersion=2010-04-01 HTTP/1.1"
and weβre mostly concerned with the From , To , and Body fields in the payload from Twilio, so in our recv.py entrypoint, weβll want to handle these, and pass them to a slack_callout function like we did in send.py in a much simpler workflow:
jmarhee/fission-twilio-sms-slack
Weβre grabbing these fields from the request.args object containing the above formatted payload, and converting the values to strings, and passing it to a similar Slack callout function that just POSTs directly to the webhook URL to dump the message, and its sender, into the channel.
Once you create your task:
fission function create --name twilio\_recv --env python3 --route /twilio\_recv --method GET --code recv.py
go back over to the Twilio Console, and in the SMS field for your number, youβll specify that youβd like a Webhook, and that the data be sent as a GET request to that endpoint, your http://$FISSION_ROUTER/twilio_recv URL:
Further Reading
You can take a look at the completed scripts here:
Top comments (0)