Master Your Calendar with Twilio Studio and a Little Bit of Mathe-Magic

February 28, 2020
Written by

Master your calendar with Twilio Studio and a little bit of Mathe-Magic

We spend a lot of time sorting out future plans, and there are some people who seem to have their whole calendar in mind at a moment’s notice. Whether it’s planning to hang out with friends or setting up meetings with colleagues, you can acquire a mystical air by knowing a quick mathematical trick to calculate the day of the week for any date. With a little practice, you can do it in a matter of seconds while others are still fumbling their phones out of their pockets.

In this post, I’ll explain the so-called Doomsday algorithm, and walk you through setting up an SMS chatbot for practising.

The Doomsday Algorithm

The Doomsday algorithm was invented by John Horton Conway as a way to work out what day of the week any date will fall on. Conway is better known as the inventor of the Game of Life but I think this is just as cool, and maybe even more useful.

The essential idea is that for any year we can find a day of the week which is called the “Doomsday” for that year, and there are memorable dates in every month which will fall on that day. From knowing that, you can count forward or backwards to a target date and be a calendar conjurer ⚗️.

Finding the Doomsday for 2020

In any year, the day you want to pay attention to is the last day of February. In 2020 this is a Saturday. There is a way to work it out for any given year, but for this post I will focus on 2020, so let's stick with Saturday.

Other dates which fall on a Doomsday

Every year there are certain anchor dates which will also fall on the same day.

To start with, look at April 4th, June 6th, August 8th, October 10th and December 12th. These will all be Saturdays, and are easily remembered as:

  • 4/4, 6/6, 8/8, 10/10 and 12/12

For odd-numbered months, remember the phrase Nine to Five at the Seven-Eleven to find more Saturdays on these dates:

  • 5/9, 9/5, 7/11 and 11/7

So far so good - and note that these dates work just wonderfully in US format (month/day) and rest-of-the-world (day/month).

We’re just left with January, February and March:

  • February - it’s the last day, this year the 29th
  • March - it’s the “zeroth”, so also the 7th, 14th, 21st and 28th
  • January - this depends if it’s a leap year. Leap years occur approximately every 4th year. On 3 years use Jan 3rd and on the 4th year use Jan 4th.

Once you have the anchor date for your month, count forward or backwards in 7s until you’re close then adjust for the few remaining days.

A couple of examples

International Day of the Programmer is on the 256th day of the year, which is September 12th this year:

  • September is the ninth month, so the anchor day is the 5th (remember: “nine to five”)
  • The 12th is 7 days after the 5th, so it’s also falling on Doomsday this year...
  • Saturday

Tau Day is the 28th of June:

  • June is the 6th month, so anchor on 6/6
  • The 28th is 22 days after that, which is 3 weeks and 1 day
  • Ignoring whole weeks, 1 day after Saturday is...
  • Sunday

With practice you can get fast and accurate at this, impressing friends and colleagues alike.

Animgif "Abracadabra"

Building a chatbot to practise

To become fast and accurate with the Doomsday algorithm you will need to practise, so here’s how to build a bot that can test you over SMS. You will need a Twilio account - if you have one already then GREAT! If not then sign up - this link contains a code to get $10 when you upgrade.

The goal is to send an SMS to the bot and it will send back a random date in 2020. You can reply with the day of the week and check whether you’re doing the Doomsday Algorithm correctly. Keep practising and you will improve.

Screenshot of an SMS conversation: "Test me", "what day is Jan 5th 2020", "Sunday", "That's right"

Ideally, we would like the bot to be usable by many people at once, and we need some way of storing the randomly-chosen date for the duration of each conversation. Twilio Studio is perfect for this because it maintains per-conversation state and can be used to create conversational workflows with branching logic and more.

We also need a way to generate a random date for each conversation, and Twilio Functions is a good fit because it enables  you to run JavaScript code on Twilio’s serverless platform, without running a webserver yourself. It also integrates perfectly with Studio.

Creating the Twilio Function

The Function will be used to choose a random date in 2020 and format the question and answer. Once you are logged into Twilio, head to the Functions Console. Click the + button to create a new function, and choose the “JSON Response” template:

Screenshot: New Function dialog, highlighting "JSON Response" template

You will be taken to the code editor where you should choose a Function Name and Path which make sense to you. I used “Random Date Chooser” as the name and /doomsday as the path. You should select "Check for valid Twilio signature" to make sure that your function is only callable by Twilio. Click the “Save” button once you’ve set these.

Screenshot: Function configuration with name "Random Date Chooser", path "/doomsday" and a highlight on the "Check for valid Twilio signature" checkbox.

Before writing the code, add the moment.js library to make working with dates a little easier. Select ‘Configure’ from the menu on the left, and add moment to the NPM dependencies - the latest version, which I used, is 2.24.0:

Screenshot: Functions config showing a dependency added of "moment" at version "2.24.0"

Don’t forget to click ‘Save’, then head back to the code editor.

Use the code below to replace the existing code in the function.

var moment = require('moment');

exports.handler = function(context, event, callback) {
        randomDayNumber = Math.floor(Math.random() * 366);
        randomDate = moment('2020-01-01', 'YYYY-MM-DD').add(randomDayNumber, 'days');
        let response = {
            "date": randomDate.format('LL'),         // eg: 'March 22, 2020'
            "day_of_week": randomDate.format('dddd') // eg: 'Sunday'
        callback(null, response);

The code above will return a JSON Object with keys of date for the question, and day_of_week for the answer:

  • on line 5 we choose a random number from zero to 365
  • on line 6 we use moment.js to add that many days on to Jan 1st 2020
  • lines 8-11 create the object, which is returned by passing it the callback on line 13.

Save your function, and now it’s time to create the Studio flow.

Creating the Studio Flow

On the Studio Dashboard, click the + to create a new Studio Flow. After choosing a name (I used ‘Doomsday by SMS’), choose to ‘Start from scratch’.

Studio is a visual designer for building conversational workflows. The Flow comes with a Trigger widget already on the canvas. You will hook onto the ‘Incoming Message’ event which will be triggered by an incoming SMS. The first thing to do is to call the function created above.

From the Widget Library on the right, drag Run Function onto the canvas. Call this widget Choose_a_date, and choose the function created above. Don’t forget to save the configuration of this widget, and connect it to the ‘Incoming Message’ trigger:

Screenshot: Twilio Studio canvas showing the Trigger's "Incoming Message" connected to a "Run Function" widget which is configured to call the "Random Date Chooser" function.

Later on in the flow, you will be able to refer to the values returned by the function as {{}} and {{widgets.Choose_a_date.parsed.day_of_week}}.

You’ll use the date value straight away because the next thing to do is reply to the incoming SMS with a challenging question. Drag in a Send & Wait for Reply widget, connect it to the Choose_a_date widget and configure the message to be "Hello 👋 Tell me, what day is {{}}?":

Screenshot: Studio canvas showing the "Run Function" widget connected to a "Send and Wait for Reply..." widget.

If a reply is received within the default 3600 seconds Studio will pick up the Flow from the ‘Reply’ connector on this widget. If it times out then any new message sent in will start at the ‘Incoming Message’ trigger again. This management of conversational state by Studio is just what we are using it for - without that it would be necessary to build an app to manage it, which would add a lot of complexity.

The next widget to use is Split Based On…, which can test whether the SMS response contained the right answer. Drag one from the library onto the canvas and call it was_it_right. From that you can either send congratulations or commiserations using two Send Message widgets. Drag these onto the canvas and name them it_was_right and it_was_not_right.

In the Split Based On… widget, which is called was_it_right, the variable to test is widgets.ask_initial_question.inbound.Body.

The test checks whether that variable contains {{widgets.Choose_a_date.parsed.day_of_week}}. If so, the it_was_right widget should be triggered, sending a message of “Congratulations 🎉🎉 That’s right” . If not then the it_was_not_right widget sends Sorry, {{}} is a {{widgets.Choose_a_date.parsed.day_of_week}}.

To achieve this, connect the No Condition Matches connector from the was_it_right widget to the it_was_not_right Send Message widget. Then connect the other connector to the it_was_right Send Message widget.

Don’t forget to save each widget once you are done configuring it. The configuration for the transitions looks like this:

Screenshot: Twilio Studio canvas with setup as described in the preceeding paragraph.

The Studio Flow is complete, but so far it’s only a draft. Publish it by clicking the button at the top of the designer:

Screenshot of Twilio Studio canvas highlighting the "Publish" button

You’ll see that the flow is now up-to-date, so it’s time to hook it up to a real phone number and get practising.

Connecting a Studio Flow to a phone number

Head over to the Phone Numbers management console, click the + to buy a new number.  Choose a number that you like, and on the phone number configuration screen choose the Studio Flow you created to be called when a message comes in:

Screenshot: Phone number configuration. "When a message comes in" is configured to run a Studio Flow called "Doomsday by SMS"

Save that configuration, and you’re good to go

Screenshot of an SMS conversation with one wrong answer and one correct answer.

Practice makes perfect 😉

Wrapping up

Now that you’ve got this far, you’ve:

  • created a serverless stateful conversation bot using Twilio Studio
  • added custom logic from a Twilio Function
  • created a cool chatbot to help you practise the Doomsday algorithm.

No mean feat, congratulations!

A neat feature of Studio is the ability to export and import Flows as JSON documents. You can find the JSON version of the flow from this post and a more complex one which allows more than one guess at this gist.

If you just want to test yourself, I’ve hooked up +44 7723 566306 and +1 (323) 375-DOOM (that’s 375-3666) to my Studio Flow so give it a go by sending an SMS with any message to one of those numbers. There’s also a shell script if you want to practise in the terminal.

If you’re building things with Twilio, whether it’s Studio, Functions or anything else, I’d love to hear about it. And if the Doomsday algorithm is helping you in real life, tell me about that, too. Happy hacking!