Earlier this year I built an affirmations button with Twilio Internet of Things. When I’m feeling insecure or anxious (which is often), the button lets me ground myself with a physical gesture and receive a reassuring text message in return.
The box holding the button looks cool but it's not as portable as I’d like, since it contains a Raspberry Pi. As a Twilio Developer Evangelist, I’m on the road writing code fairly often. I needed something that takes up less space in my luggage.
Today I’ll show you how to build a more portable affirmations button with Flic.
What is a Flic button?
Flic buttons are hardware buttons that are small enough to fit in a pocket. Out of the box, they can be configured to do various things when pushed, such as:
- control Philips Hue lights
- start a Pomodoro timer
- make a phone call
You can also make HTTP requests with a Flic button, which opens up a lot more possibilities. Flic buttons pair with your phone via Bluetooth to communicate with the rest of the Internet. Today we’ll write some code to fetch an affirmation and send an SMS message. Also, we’ll create a URL where we can send a POST request and kick things off. To avoid the hassle of standing up a server, we’ll use Twilio Functions. Using the Serverless Toolkit allows us to develop and test our function locally.
Prerequisites
- A Twilio account - sign up for a free one here
- A Twilio phone number with SMS capabilities - configure one here
- A Flic button and an IOS or Android phone to pair it with
- Node.js installed on your local machine. The Serverless Toolkit uses version 8.10 at the time of this writing.
Tip: you can use nvm to switch between Node.js versions on a per-project basis.
Coding time
Install the Twilio CLI if you haven’t already. From the terminal, run twilio login
. You’ll be prompted to enter your Twilio credentials which can be found in the console.
Create a project called affirmations-function
by running the following command:
npx create-twilio-function@next affirmations-function
If you have Twilio account credentials in your local environment, you’ll be asked if you want to import them into your project. If so, do that. If not, you’ll be prompted to add them.
cd affirmations-function/
The boilerplate functions created by the serverless plugin can be removed. Open the project in your editor of choice.
Tip: if you’re using VSCode, check out the Twilio Functions editor extension.
Create a file in the functions
folder. Let’s call it affirmations-response.js
. This filename becomes a part of the function URL, so avoid anything too long.
Now we’re going to make a request to the affirmations.dev API to get our affirmation. Although there are many ways to make requests from Node.js. Today we’ll use request-promise. Run npm install request-promise
from the command line to install this library.
Copy the following code into functions/affirmations-response.js
. Replace the “to” phone number with the number you want to send the affirmation to, and the “from” number with your Twilio phone number:
const rp = require('request-promise');
exports.handler = function(context, event, callback) {
// Fetch already initialized Twilio REST client
const twilioClient = context.getTwilioClient();
rp('http://affirmations.dev').then(response => {
const affirmation = JSON.parse(response).affirmation;
twilioClient.messages.create({
from: '+1 555 555 5555', // replace this with your Twilio phone number
to: '+1 666 666 6666', // replace with this the number you want to send the message to
body: affirmation,
}, (err, result) => {
callback(null, result);
}).catch(err => {
callback(err);
});
});
}
When callback()
is called the outer function immediately returns, killing any asynchronous processes that are running. Since the affirmation is fetched asynchronously, in the code above the callback is invoked after we’ve finished fetching the affirmation data.
Run twilio serverless:start --live
to test things out.
This command will give you a URL, which you can copy and paste into your browser to execute the function from your localhost. You should see some output in the browser:
{
"accountSid": "xxxx",
"apiVersion": "2010-04-01",
"body": "10x engineers are a myth",
"dateCreated": "2019-11-26T01:03:13.000Z",
"dateUpdated": "2019-11-26T01:03:13.000Z",
"dateSent": null,
"direction": "outbound-api",
"errorCode": null,
"errorMessage": null,
"from": "+5555555555",
"messagingServiceSid": null,
"numMedia": "0",
"numSegments": "1",
"price": null,
"priceUnit": "USD",
"sid": "xxxx",
"status": "queued",
"subresourceUris": {
"media": "/2010-04-01/Accounts/xxx/Messages/xxxx/Media.json"
},
"to": "+16666666666",
"uri": "/2010-04-01/Accounts/xxxx/Messages/xxxx.json"
}
Also, you should receive an SMS affirmation!
Next, deploy your function from the terminal by running twilio serverless:deploy
. In the Twilio console, you should see your function listed here. The URL for your function is the domain name under “Environment” plus the filename of the file your function lives in.
Configuring the Flic button
Download and install the Flic app, and follow the instructions for pairing the button with your phone. Tap the large Flic button icon on the main screen.
On the next screen, tap on the “Click” option, unless you wanna use a double click or hold instead. Who am I to stop you?
On the next screen scroll to “Tools” and then select “Internet Request.”
We are going to make a POST request to the URL of our function, which we noted in the previous section. Type the URL in the box, click “POST”, and then hit “SAVE ACTION” at the bottom of the screen.
Well done. Reward yourself for all this hard work by clicking the button and sending yourself an affirmation. 💝
What’s Next
Let’s review what we’ve learned today:
- How to fetch asynchronous data within a Twilio Function
- How to use the Twilio CLI with our Serverless Plugin to create, test, and deploy Twilio Functions
- How to configure the Flic button to make a post request to a URL
If you want to learn about other cool things you can do with Twilio and Flic, check out Chloe Condon’s fake boyfriend or Fernando Larranaga’s panic button.
If you build something fun after reading this post, I’d love to hear about it! Hit me up in the comments below or on Twitter.