Website Logo. Upload to /source/logo.png ; disable in /source/_includes/logo.html

Chris Meier

Software Developer and Co-founder of FoodChain

Hermes: A Jasper Module for Sending SMS Messages

Jasper is a great platform to develop voice-controlled applications. It has excellent developer documentation that makes it easy to create your own modules. Jasper is pretty cool so I decided to start programming some modules myself.

The first is called Hermes. This module will allow you to send SMS messages to your friends and family through the Twilio API. Let’s get started:

If you haven’t already, register an account with Twilio and install the Python module:

1
sudo pip install twilio

Then add your Twilio information in your profile.yml

1
2
3
TWILIO_ACCOUNT_SID: account sid
TWILIO_AUTH_TOKEN: auth token
TWILIO_PHONE_NUMBER: Phone number as a string

Create a new file titled Hermes.py We will need to import two modules for this project:

1
2
import re
from twilio.rest import TwilioRestClient

First we need to define the words that will activate Hermes:

1
WORDS = ["SEND","TEXT","MESSAGE"]

We then need to define an isValid() method that will allow Jasper to launch our module. Jasper will be looking for the words specified in the list above. We do this by using regular expressions:

1
2
def isValid(text):
    return bool(re.search(r'\bsend text message\b', text, re.IGNORECASE))

Here, Jasper is looking for the phrase “send text message” in our command.

Once our command is deemed valid, we need a way to handle it and take action:

1
def handle(text, mic, profile):

In this handle() method we will need to do a few things:

  1. Grab your Twilio keys
  2. Ask you who you want to send a message to and grab their number
  3. Retrieve your Twilio number
  4. Send the text message

In order to use Twilio, your Account SID and Auth Token must be available to Jasper. We will retrieve them and initialize the Twilio client:

1
2
3
4
def handle(text, mic, profile):
    account_sid = profile["TWILIO_ACCOUNT_SID"]
    auth_token = profile["TWILIO_AUTH_TOKEN"]
    client = TwilioRestClient(account_sid, auth_token);

Next, we need to decide who to send it to. We will use a contacts list in your profile.yml to store phone numbers. Due to inaccuracies with STT engines, you can only send messages to numbers in your contacts. This way we avoid issues with Jasper correctly hearing the number you want to send to. We will use a simple dictionary for the contacts list. The key will be the person’s name and the value will be the phone number as a string

Let’s start your contacts list with your Mom’s and your Dad’s numbers. Open your profile.yml and add the following:

1
TWILIO_CONTACTS{MOM: "+15555555555", DAD: "+14444444444"}

Just replace the numbers with their actual numbers. Be sure to include the country code prefix in the number (if you are in the US it it +1).

Jasper will ask who you want to send a message to and then get their number from your contacts list:

1
2
3
4
5
6
7
8
9
def handle(text, mic, profile):
    account_sid = profile["TWILIO_ACCOUNT_SID"]
    auth_token = profile["TWILIO_AUTH_TOKEN"]
    client = TwilioRestClient(account_sid, auth_token)

    #Ask who you want to message and get their number
    mic.say("Who would you like to send it to?")
    contact = mic.activeListen()
    contact_number = getContactNumber(contact, profile)

The method for retrieving the contact’s number:

1
2
def getContactNumber(contact, profile):
    return profile["TWILIO_CONTACTS"][contact]

We then must get your Twilio number from your profile.yml:

1
2
def getMyNumber(profile):
    return profile["TWILIO_PHONE_NUMBER"]

Add it to the handle() method:

1
2
3
4
5
6
7
8
9
10
11
def handle(text, mic, profile):
    account_sid = profile["TWILIO_ACCOUNT_SID"]
    auth_token = profile["TWILIO_AUTH_TOKEN"]
    client = TwilioRestClient(account_sid, auth_token)

    mic.say("Who would you like to send it to?")
    contact = mic.activeListen()
    contact_number = getContactNumber(contact, profile)

    #get your number
    my_number = getMyNumber(profile)

Finally we send the text message:

1
2
3
4
5
6
7
8
def sendSMS(mic, client, to_phone_number, from_phone_number):
    mic.say("What would you like to say?")

    #make it all lowercase so it doesn't seem like we're shouting 
    message = mic.activeListen().lower()
    client.messages.create(to=to_phone_number, from_=from_phone_number, body=message)

    mic.say("Text message sent")

We then add it to our handle() method:

1
2
3
4
5
6
7
8
9
10
11
12
13
def handle(text, mic, profile):
    account_sid = profile["TWILIO_ACCOUNT_SID"]
    auth_token = profile["TWILIO_AUTH_TOKEN"]
    client = TwilioRestClient(account_sid, auth_token)

    mic.say("Who would you like to send it to?")
    contact = mic.activeListen()
    contact_number = getContactNumber(contact, profile)

    my_number = getMyNumber(profile)

    #send the text message
    sendSMS(mic, client, contact_number, my_number)

This method is where all of the action happens. Jasper will ask you what you would like to say in your text message. We then use the Twilio client to create a message using the contact’s phone number, your phone number, and then the message that you specify. The message will then be sent through the Twilio API to your contact’s number. Jasper will then verbally confirm that the text message was sent. It’s really that easy! No more excuses to not send “Happy Birthday” wishes to your friends and family.

To use Hermes with Jasper, add it to your modules folder:

1
cp Hermes.py ~/jasper/client/modules/

This was my first module developed for Jasper. It turns out that it’s super easy to write modules for it. It took me under two hours to write Hermes. I’m pretty excited to explore it further especially in the home automation domain.

If you haven’t already, head on over to Github and check it out.