A very common use case for Functions is implementing time of day routing in your application. For example, varying your application's response to incoming calls based on what time and day a customer is calling, or which path to take in an IVR being written with Twilio Studio.
Before getting deeper into the example, first create a Service and Function so that you have a place to write and test your Function code.
In order to run any of the following examples, you will first need to create a Function into which you can paste the example code. You can create a Function using the Twilio Console or the Serverless Toolkit as explained below:
If you prefer a UI-driven approach, creating and deploying a Function can be done entirely using the Twilio Console and the following steps:
https://<service-name>-<random-characters>-<optional-domain-suffix>.twil.io/<function-path>
test-function-3548.twil.io/hello-world
.Your Function is now ready to be invoked by HTTP requests, set as the webhook of a Twilio phone number, invoked by a Twilio Studio Run Function Widget, and more!
One potential implementation is to simply respond to callers with a different message depending on the day and time that they are calling. Suppose your business is located on the East coast of the US, and has hours 9am-5pm, Monday-Friday. Calls on those days and between those hours should receive a response indicating that the business is open, while calls on the weekend or outside of business hours should receive a closed message.
This can be accomplished purely by leveraging built-in JavaScript methods, courtesy of the Internationalization API's Intl.DateTimeFormat object. By providing the specific timeZone
of your business in the accepted tz format, you can derive the current day and time, and perform any necessary logic to determine your response.
To test this code out, paste the code into the Function that you just created earlier, and set it as the A Call Comes In webhook handler for the Twilio phone number you wish to test. The following instructions will show you how to do so.
Remember that methods such as new Date()
return the local time of the machine that your deployed code is being executed on, not your local time. Functions are typically executing in the UTC time zone. This is why all examples are using Intl.DateTimeFormat instead of just the Date
object directly.
We highly recommend using built-in objects such as Intl.DateTimeFormat to implement your application logic, or the date-fns library if you need more robust date utilities.
Moment.js is end of life and should not be used for handling time zone shifts, formatting, etc.
1exports.handler = (context, event, callback) => {2// Create a new voice response object3const twiml = new Twilio.twiml.VoiceResponse();4// Grab the current date and time. Note that this is the local time where the5// Function is being executed, not necessarily the time zone of your business!6const now = new Date();7// Print the timezone of the instance that's running this code8const functionTz = Intl.DateTimeFormat().resolvedOptions().timeZone;9console.log(`This Function is being executed in the ${functionTz} time zone`);10// You should see: 'This Function is being executed in the UTC time zone'1112// Configure Intl.DateTimeFormat to return a date in the specified13// time zone and in this format for parsing, for example: 'Monday, 18'14const formatOptions = {15hour: 'numeric',16hour12: false,17weekday: 'long',18timeZone: 'America/New_York',19};20const formatter = new Intl.DateTimeFormat('en-US', formatOptions);2122// Get the current time and day of the week for your specific time zone23const formattedDate = formatter.format(now).split(', ');24const day = formattedDate[0]; // ex. 'Monday'25const hour = Number(formattedDate[1]); // ex. 1826// Since we're given days as strings, we can use Array.includes to check27// against a list of days we want to consider the business closed28const isWeekend = ['Sunday', 'Saturday'].includes(day);2930// Here the business is considered open M-F, 9am-5pm Eastern Time31const isOpen = !isWeekend && hour >= 9 && hour < 17;32// Modify the stated voice response depending on whether the business is open or not33twiml.say(`Business is ${isOpen ? 'Open' : 'Closed'}`);34return callback(null, twiml);35};
In order for your Function to react to incoming SMS and/or voice calls, it must be set as a webhook for your Twilio number. There are a variety of methods to set a Function as a webhook, as detailed below:
You can use the Twilio Console UI as a straightforward way of connecting your Function as a webhook:
Log in to the Twilio Console's Phone Numbers page.
Click on the phone number you'd like to have connected to your Function.
If you want the Function to respond to incoming SMS, find the A Message Comes In option under Messaging. If you want the Function to respond to Voice, find the A Call Comes In option under Voice & Fax.
Select Function from the A Message Comes In or A Call Comes In dropdown.
ui
unless you have created
custom domains
), and finally
Function Path
of your Function from the respective dropdown menus.
This logic can also be applied in the context of a Studio Flow, such as in an IVR. For example, a Function can return an isOpen
property as a Boolean (or a more advanced data structure if you like), and a subsequent Split Based On... Widget could then perform pattern matching on that value to determine how the Flow should advance. The following code sample would generate a Boolean that can be consumed in a Split Based On... Widget by referencing {{widgets.<widget-name>.parsed.isOpen}}
.
Check out this section of the Run Function widget example to better understand consuming parsed values and generally how to execute this sample via the Run Function widget.
1exports.handler = (context, event, callback) => {2// Grab the current date and time. Note that this is the local time where the3// Function is being executed, not necessarily the time zone of your business!4const now = new Date();5// Configure Intl.DateTimeFormat to return a date in the specified6// time zone and in this format for parsing, for example: 'Monday, 18'7const formatOptions = {8hour: 'numeric',9hour12: false,10weekday: 'long',11timeZone: 'America/New_York',12};13const formatter = new Intl.DateTimeFormat('en-US', formatOptions);1415// Get the current time and day of the week for your specific time zone16const formattedDate = formatter.format(now).split(', ');17const day = formattedDate[0]; // ex. 'Monday'18const hour = Number(formattedDate[1]); // ex. 1819// Since we're given days as strings, we can use Array.includes to check20// against a list of days we want to consider the business closed21const isWeekend = ['Sunday', 'Saturday'].includes(day);2223// Here the business is considered open M-F, 9am-5pm Eastern Time24const isOpen = !isWeekend && hour >= 9 && hour < 17;25// Return isOpen in an object that can be parsed and then26// used by the Split Based On... Widget for Flow routing27return callback(null, { isOpen });28};