Receiving and Responding to SMS Directives

Pbmacintyre
RingCentral Developers
8 min readMay 16, 2024
a Person Sending SMS

In this article we will be looking at how to receive and respond to incoming contextual SMS messages. The easiest way to do this is by using Webhooks to subscribe to the instant message event Webhooks are used to allow applications to “listen” for certain events or actions and respond accordingly. For example, using SMS webhooks you could create an interactive appointment scheduling system that allows your customers or patients to schedule or reschedule their appointments instantly over SMS.

To demonstrate using SMS webhooks, we are going to build a small application in PHP that will listen for incoming SMS messages, check its contents, and respond appropriately with dictionary information showing the part of speech and the definition of the submitted word, and if available, a sample sentence that uses the submitted word.

Create the Webhook

The first part is to set up the “listening” side of the equation. Here is the sample code.

Figure 1 — Webhook creation code

Let’s review some of this code. On line 6 we are simply connecting to our SDK by calling a function of our own. Inside that function we would be using our SDK credentials and connecting to a RingCentral app that we created in the Developers platform. Within that function we would also be using a generated JWT key (How to generate a JWT Key). After that we would use the SDK connection to create a subscription with the post method (line 8) and send it an array of information. “eventFilters” will have a type of SMS (line 11). We designate SMS here as opposed to fax or voicemail, for example, so that the subscription will only trigger if an SMS message is received. “expiresIn”, on line 13, is a value in seconds that designates how long the subscription will be “alive”; so we are giving it a long life with 315,360,000 seconds (10 years).

The deliveryMode (Line 14) is another sub-array with some important information in it as well — transportType has to be “WebHook”, and the “address” value is the full URL location for the code to be run when this webhook is triggered, line 17. The file that is designated in the address value has to exist in order for the subscription to be activated. So if you run this code and dictionary_webhook.php does not yet exist, the subscription won’t be activated. If you want to set up the subscription and build your destination code later you can simply create the file with nothing in it yet and the subscription webhook should still activate. Keep in mind that if any SMS messages are received before you have the destination code ready either nothing will happen or you will have unexpected results. So it is a good idea to have both files coded properly before you make them live.

Line 21 then stores the newly created subscription id into a local variable called $webhook_id where you can store it in a database for future reference, if so desired. For example, if we ever wanted to delete the webhook subscription we would need this identifier to select it directly.

Here is a PHP function that can be used to display all the active subscriptions for an app. You can use it to identify a subscription if you don’t choose to store the id’s in a database.

Figure 2 — List subscriptions code

Here, on line 4, after connecting to the SDK, we call the get method to collect all the subscriptions into the $response variable. Then we get the JSON format of the data and put that into the $subscriptions variable and we traverse the array and output any information that we want on the subscriptions. Here we are only selecting information that we are interested in. The output looks like this:

Figure 3 — Sample output of List subscriptions code

We see our subscription id and the other information that we sent to the screen.

Creating a script to handle inbound SMS

Once we have the subscription in place we effectively just have to wait for an SMS event to occur. In our case, an SMS message sent to an SMS enabled mobile number that is connected to our RingCentral account. The same account where we have the JWT key active that we used to connect to the SDK. So the “listening” code is then placed in the file that we specified in the address array element above; namely “dictionary_webhook.php”. Following is a sample of that code, we will break it down into sections as the code is explained.

Figure 4 — Initial code for handling incoming SMS message

To ensure that the incoming message is indeed designated for RingCentral to use, RingCentral sends out a validation token within the HTTP header. This code checks that the header is indeed valid and is a match, lines 1 to 4. Line 6 takes the incoming SMS information and puts it into a variable called $incoming. It is then tested to see if there is indeed any information coming in that could be processed, lines 8 to 12.

Line 15 is commented out, but can be used to save the incoming data to a log file so that you can see what the incoming data may look like. See figure 5 for a friendly-formatted example of what the incoming data structure, or payload, looks like. The information that we really need is in the “to” and “from” numbers and the “subject”, or actual text content of the SMS message. The other information in the payload, like subscriptionId could be used to further validate the message, if desired.

Figure 5 — Sample payload of incoming SMS message

Getting back to the code for managing the incoming SMS message, what we want to do next is to decode the JSON formatted data and then validate that we can in fact use the data.

Figure 6 — More SMS management code

Lines 1 to 7 do that for us. Lines 12, 14, and 16 take the three data elements that we want out of the payload and store them into local variables for us to use later. They are the subject (SMS message itself), the “to” mobile number (Our RingCentral mobile number that is receiving the SMS) and the “from” mobile number (the mobile number that is the source of the SMS message). We then prepare an empty variable that we will be using for our outgoing response SMS message.

Respond Accordingly

With all the preparation code done we now have to process the actual incoming directive from our client. We are expecting directions to arrive with all capital letters in the format of [action word]. We have a total of 3 action directives that we are coding for, but once you see how a few of these are done you will be able to expand on the actions if you want to. The actions are STOP, HELP, and DEFINE. STOP and HELP are only one word each and must be in all capital letters with no trailing spaces. We are using regular expressions to manage the incoming directives so here is the expression for the STOP action — we also allow for the word UNSUBSCRIBE.

preg_match(‘/^(STOP|UNSUBSCRIBE)$/’, $message)

^(STOP|UNSUBSCRIBE) means that we are looking for these capital letters at the beginning of the message string. The “|” between the words means that it could be either of these strings of characters. The $ at the end denotes that there should be no more characters at the end of the message string. This is the same for the HELP (INFO) action.

preg_match(‘/^(HELP|INFO)$/’, $message)

preg_match(‘/^(DEFINE) [A-Z]+/’, $message)

^(DEFINE) means that we are looking for these capital letters at the beginning of the incoming message string. After that we are expecting a space followed by one or more capital alphabetical characters.

Here is the code for the whole process:

Figure 7 — Code to manage incoming actions

We follow this with sending out the responding SMS with the contents of $outbound_message, whatever that was determined to be. Ideally it would be a word’s part of speech, definition, and a sample sentence. The SMS sending code looks like this.

Figure 8 — SMS Sending code

Of course there can be a lot more done within each action area, for example in the STOP process you would need to find your client’s mobile number and remove them from your distribution list.

In the HELP process you would add more information for a helpful message, maybe a phone number to call, or a web site to visit. On line 7 of figure 7 as part of the DEFINE process there is a call to the function get_dictionary_data($word). Here we are passing the word from the incoming message that was asked to be defined to our function that looks up the information based on the provided word. That code looks like this and is based on the Free Dictionary API.

Figure 9 — get_dictionary_data function

You can find all the data points for this API at this URL. Be sure to add a valid word to the end of the URL. Here we are asking for the definition of the word “Stealing”

https://api.dictionaryapi.dev/api/v2/entries/en/stealing

It displays best in Firefox and looks like this:

Figure 10 — Dictionary API sample output

The ultimate result of all this code is the sending of a definition request to the “listening” number and having the response going back with a full definition of the submitted word. Here is an example of that exchange.

Figure 11 — SMS definition request and response.

I hope you enjoyed this article and that you find the sample code both helpful and useful. As you can see, extrapolating this to other more complex examples like the appointment reminder mentioned in the introduction is just a matter of doing more within the area of code that deciphers what the incoming request is; STOP, DEFINE, HELP, etc. This code could be expanded for educational institutions informing inquiring students where their class room is for the day, or to provide keen students with their most recent marks.

This could also be used in the real estate industry to inform potential buyers what an asking price is for a submitted civic address. The possibilities are really endless within this basic code structure, provided that the process is secure, industry regulations compliant, and legal. As well, always keep in mind that the participants in this type of SMS exchange have to give their consent, so be sure to collect that information when participants sign up for your messaging application.

The full code library for this Dictionary example can be found at
https://github.com/pbmacintyre/Dictionary-Blog-Repo. Learn more about RingCentral’s SMS API at https://developers.ringcentral.com/sms-api.

--

--

Pbmacintyre
RingCentral Developers

Peter has over 35 years of experience in IT, primarily in PHP. Author of PHP: The Good Parts; co-author: Programming PHP-4th Ed. Zend certified in PHP 5.3 & 4.0