This tutorial guides you through the process of building a plugin that sends text messages when a record is created. We will use Twillio to send the text messages and Zengine webhooks to trigger the messages to sends on record creation.
Before developing the plugin, you will need a Twillio account, which can be created for free, if you don’t have one yet. Once you have an account, log into Twillio and go to the account settings page to view your API Credentials. For the purposes of this tutorial, you can use your test AccountSID and AuthToken, so you don’t need to pay for sent messages.
Creating A Backend Plugin Service
When a Zengine webhook is triggered, it makes a POST request with a payload about the triggered data. We need to setup a service to receive these payloads and send the text messages. We can do this by adding a backend service to our plugin from the Developer tools. After creating a backend service, downloading and unzipping the draft source code, go to the top-level of the code directory, and run the command below to install the Twillio Node.js library:
Then in the plugin.js file, add the following code:
If you use your test API credentials, you can test sending a successful sms by using the magic number +15005550006 as the From number, and a regular phone number for the To number. To generate failure cases, check out this list of test numbers. You can try this out locally by booting up the node app by running npm start and going to localhost:3000/. This won’t actually send the text message, but you should get a successful response back. If you want to send real text messages, you must use your live API credentials. If you want to send text messages for free through your trial account, follow this 5-step process.
Plugin Settings
Now we want to allow workspace administrators to customize what triggers these sms messages to be sent. We can do this by adding a settings interface to your frontend plugin code. We accomplish this when invoking the register function and passing the interfaces array containing an object of type settings. You might have noticed your default frontend plugin.js code already comes with this settings interface set up, but in case not, you can use the code below (replaced with your own plugin namespace):
Now workspaces admins can go to the workspace settings section in Zengine, and click on the “Record SMS Plugin” card to edit settings about this plugin.
Configuring the Webhook
Now that our plugin has a settings section, we can use it to create the webhooks that will make requests to the plugin service endpoint. For the purposes of this tutorial, assume the webhook should trigger for events about records, so we set the resource attribute to 'records'. We also assume we only care about records in the current workspace, so we can get the workspace ID from the route using $routeParams. We don’t want the webhook to trigger for any activity on tasks, events, or comments associated with the records, so we set includeRelated to false.
Below is the resulting base data we will use to create a webhook:
Now we want to allow users to further filter down which records trigger the webhook, so we allow users to choose a form from a dropdown list of forms in the workspace. If a form is chosen, we also provide the option to create a data filter.
Add the code below, replacing ‘namespaced’ with your namespace, and ‘sms-messages’ with the actual route of your backend service. so a webhook is created when a workspace admin clicks the “Save” button.
The html below creates a form called pluginSettings that allows users to choose a form ID and a data filter.
Using Webhook Payload Data
Now that the webhook is being created in the plugin settings, text messages will be sent anytime a record is created, updated, or deleted in the workspace. However, we only want to send messages when a record is created, so we need to update our service code to look at the payload data, and ignore non-creates.
Update your service code below to use the payload data to filter out updates and deletes, as well as send the record id in the message body.
Once you have updated your plugin.js file, zip the updated plugin folder and upload it back to your plugin service. In order to test it working via a webhook, you will need to publish your plugin. If you don’t want it to show up in the marketplace, make sure your plugin is private.
After publishing your plugin, add it to a workspace, and create a record in that workspace. For record creation, a sample webhook payload looks like this:
You can see whether the webhook POST request was successful by querying the webhook_events endpoint. If you are using the live Twillio API credentials, you can also look at the Twillio SMS logs.
Saving Webhook Settings to Firebase
In order for workspace administrators to be able to come back and edit these settings, we will use Firebase to store them.
We want to restrict updating the Firebase data to workspace admins, so we take advantage of the firebaseAuthToken returned from the plugin API response to connect to Firebase. After sucessful authentication, the $scope.connect() method will assign the settings data to a scope property and turn off the loading indicator.
Note that you need to inject the $firebase service in your controller signature.
Now that we are fetching data from Firebase, we need to update the $scope.save method to save the data to Firebase. We can do this with by calling $scope.settings.$save(). For more information, check out the AngularFire documention on $save.
Since a new webhook is created each time the “Save” button is clicked, the code below also adds some logic to store the webhook id in Firebase and delete the old one before creating a new one.
Wrapping Up
At this point you should have a functional plugin that will send sms messages anytime a record matching certain user-defined conditions is created in the workspace. In part 2, we will work on making the plugin more customizable and secure.
Your plugin backend code should look like this:
Your plugin frontend code should now look something like this (with your own plugin namespace in the js registration options and html template id, and replace ‘/sms-messages’ with your own plugin service route):