How to receive SMS in Slack (using Twilio Functions)
One of Slack’s great features is that it integrates with just about every SaaS product that exists. I love hooking up notifications to Slack for pretty much everything, but one notably absent integration I’ve found is receiving SMS. There are a few examples floating around of sending SMS via slash commands, but I couldn’t find one going the other way.
Why would you want to receive SMS in Slack? There are a few reasons why I’ve wanted it:
- When you have an app that uses SMS as one of its notification channels, it can be helpful to hook up a few numbers so that your QA team can validate that SMS is being sent properly by the app without using physical phones.
- Unfortunately, there are a few SaaS vendors who offer 2FA, but only over SMS and they don’t allow users to have different logins to access the same billing account. Not only do teams end up having to share a password, they’re also either forced to disable 2FA or share a device. By setting up an SMS-to-Slack bridge, you can use this as your 2FA number. (There are a lot of security issues here, but this may be a helpful solution at times.)
- A SaaS product or legacy system you’re signed up for is not yet integrated with Slack but does send notifications via SMS and you want to receive them in Slack.
Enter serverless functions
This problem sounded like a perfect application for serverless functions — set up a serverless function to receive an SMS via a webhook, then in that function, format and forward the message to Slack.
I’ve now done this with Twilio and Plivo as SMS services and AWS Lambda and Google Functions for serverless functions. I had planned to write up how to do Twilio with Google Functions first, but then I discovered Twilio Functions, announced earlier this year. As it turns out, this is a perfect solution for this problem as it avoids a network hop and the need to write code to verify the webhook requests since that’s built in.
Setting up the SMS bridge
First off, you’ll need:
- A Slack team and channel on which you want to receive SMS
- A Twilio account and number where you’ll receive the SMS
Both have free trial plans (but neither seems to have referral programs, so I have no special links for you… 🤣).
In Slack, set up a “Custom Integration” (an incoming webhook). Select the channel you want to receive the SMS (or just send it directly to your user while testing and change it later). Make sure to copy the link to the webhook.
- Go to the Twilio Functions Configure page and add an environment variable
SLACK_WEBHOOK_PATHand paste the link from your incoming webhook above, except strip off everything before
/servicesin the URL. (In other words, just paste the path.)
- Create a new Twilio Function here. Just choose the “Blank” template.
- Copy the following into the function:
Save this function (I named mine “Relay SMS to Slack”), then go to the configuration of one of your incoming numbers. Under the “Messaging” section, configure Twilio to call your function when you receive an incoming SMS like so:
Now you should be able to send an SMS and receive it in Slack! It’s styled like the following:
I customized the avatar for the webhook and set the name to SMS, but you can set yours up however you like! 😊
Thoughts on the integration
This application is a perfect fit for Twilio Functions so I was glad to discover them in this process. Some of the pros of Twilio Functions I found were:
- They handle request authentication for you automatically (if you want).
- Quite reasonably priced.
- Very fast update and deploy.
- They provided a way to manage secrets for your functions via their configuration very nicely — no secrets in the scripts! (I was surprised that this was not as easy in Google Cloud Functions for example 😞).
They also had some drawbacks however:
- Looks like the only way to create a function is via their editor. Of course you can copy and paste, but this means that you can only have a single “file” and only rely on built-in Node.JS libraries (and of course Twilio 😁). Thus I had to use the built in
httpsmodule above instead of something more sophisticated like
fetchand I’d be wary of shipping larger functions to it.
- This also means code management, versioning, and deployment isn’t really automatable at this time.
- Yet another vendor to which you have to ship code.
- Only Node.JS is supported at the moment (tho it’s my preferred environment, so… 😎)
All things considered however, I ended up preferring using Twilio Functions for this use case! If anyone is interested (or possibly even if you’re not), I’ll also plan to publish how I accomplished the same thing with Google Cloud Functions. The deployment management and secrets handling end up being fascinating points of comparison.
If you liked this post and think it might help other people, please hit the 👏 button so other folks can find it more easily. I write on topics like this from time-to-time, so follow me too if you’d like to read more.