Download & Run the collection from this article:
I love Chipotle, I mean REALLY love Chipotle, to the point where in 2014 I was eating it 4 times a week. Back then I was excited every time I heard about a recall or outbreak caused by the chain, because they always give out free burritos the day after (I would get in line several times). That is, of course, until my doctor-brother casually related the suffering that is salmonella to me over dinner, simultaneously killing my enthusiasm for free burritos and my appetite.
As a newly minted germaphobe, I thought it prudent to stay up to date on the latest food advisories and alerts. In comes the FDA mailing list, which lets you subscribe to alerts via email. This is great if I’m an individual that diligently tracks my inbox, but what if I want to be able to get alerts as texts, maybe even text them out to more people than just myself? This would be a great way to automatically spread my fear of foodborne illness (or at least let them know there will be free burritos tomorrow).
To address these needs, I created today’s project—an ‘auto-email-alert-to-text-alert’ system, that I use to keep up to date on information from the FDA, though the methods in this post could ostensibly be used for all sorts of email and text related tasks.
I used Twilio (for SMS) and Context.io (for email parsing), in conjunction with Postman’s monitoring, environment, and scripting features, as well as the Postman API. This project assumes some familiarity with these Postman features before you get started, so check out our docs if you need a refresher.
Part 1. Some Assembly Required: Setting Up Your API User Accounts
Context.io is a tool for querying an email inbox that it’s been given prior access to. This requires a bit of setup, and it may be advisable to create a new email address or folder in your inbox to separate out new alerts from your normal inbox. For this project I just hooked it up to my work email via google SSO.
Setting up Twilio has a similar level of complexity, but I don’t need to give access via any account linkage. Instead I went to the site and registered as a free user, and then set up a free number to send my texts from. When you do this, be sure to note this number for use later on, along with your account ID and authorization token from main dashboard. If you are located internationally or would like to send notifications between countries, it is important to check compatibility with Twilio, for which they provide an information page.
The third request is to the Postman API, in order to save information between Monitor runs of our collection. Persisting our Environment in Postman while using Monitors requires a bit of setup. In order to use the Postman API we’ll have to fetch our key from the integrations section of the dashboard. Navigate there and click “+ Get API Key”.
For this request, I need the unique ID of our Environment as well as the JSON body I intend to send. To get this information, I used the Postman API to query Workspace Environments and copy the our Environment’s uid. Then I can query that specific environment to get the body. These requests are made via the GET “All Environments” and “Single Environment” calls, see docs here: https://docs.api.getpostman.com/. The only change that needs to be made to the body is replacing static values with local values for the two Environmental variables, as illustrated below:
Part 2. Stick To The Script: Scripting Requests
2.1 Environmental Variables and Explanations
|Variable||Request||What it’s for|
|userId||Context.io||Required field to ID our account|
|folder||Context.io||Required field to identify inbox to scan|
|AlertText||Internal||Used to pass array of messages between email and SMS requests|
|lastCheckTime||Context.io||Call fetches only emails sent after this UNIX time|
|twilioAccount||Twilio||Required field to ID our account|
|fromPhone||Twilio||The number the text is sent from|
|toPhone||Twilio||The number to receive the text|
|AlertMessage||Twilio||The text of the message that is sent|
|environment_uid||Postman||The unique ID of this environment, used to update it after the monitor runs|
2.2 Context.io Features and Consideration
Context.io has a lot of interesting features, from hosting multiple accounts, each with their own folders for organizing mail, to a suite of filtering options for requests. The features used in this project are:
- Date filtering – to ensure the project is efficient and retrieves only the newest records from the inbox Time Sent – UNIX Epoch time (if you’re unfamiliar, it’s the total number of seconds since this timing standard was invented in 70’s). I use this to ignore emails that were received before our last polling event.
- Message Subject – This is the alert I will text out.
There are a few considerations in calling the “lite” API for Context.io:
- I need the user ID of the account I wish to poll, as noted in step 1.1.
- I need the folder path to insert into the call – for this project I used only “INBOX”. For a more complex implementation, you could find out these paths by using Postman to call the “folders” endpoint (https://docs.context.io/#listing-folders).
2.2.2 Pre Request Script
I formatted the timestamp for date filtering in the pre-request script, as this allows me to only request emails from today.
2.2.3 Test Script
The meat of the service’s logic is right here. Our biggest edge case is that multiple emails require multiple tests – this is a good example of passing arrays between Postman request in a collection. In this case, I used JSON.stringify() and JSON.parse() to encode and decode our array of messages.
My tests are going to loop over the returned emails, seeing if any of them were sent by the FDA, and if they were sent after the last collection run (our UNIX time). Positive results have their titles added to my “alerts” array to be texted out.
After I filtered out the to-be-texts, I update the check time, then determine whether I want to send texts. If the alerts array is empty, I stop everything and don’t even consider sending a message. Otherwise, I use JSON.stringify() to turn it into a string I can now pass between requests (which will need to turn them back into objects via JSON.parse()).
I then set the next request to the texting service, and scoot on over to Twilio. As a note, setting the next request with collection scripting has a few major caveats:
- Every request will be executed unless stopped by a setNextRequest(null) somewhere in your workflow.
- setNextRequest is not synchronous, and will only execute at the end of your ENTIRE script. For this reason it is important to bulkify data that may have edge cases, such as this one, which will require multiple calls.
- Combining the two points above, setNextRequest(null) is NOT analogous to “halt” or “break” in other languages, and should not be treated as such. If you want your script to stop you need to add a check in the test for the prior request, so that the request you want to avoid is never called. For me at least, this required a bit of different thinking than I was used to.
Now that I have a tidy collection of doomsaying messages, I am ready to
distribute them to my germ-fearing (or burrito loving) public.
2.3.1 Features and Considerations
2.3.1 Pre Request Script
In the pre request script, I can JSON.parse AlertText to get the array of messages. Then, I test to see if the array has any values in it. If it does, I pop the array to remove the first value and set it as the AlertMessage to be sent, and then set the next request to “Send Text With Twilio” again to continue looping through the array.
2.3.2 Test Script
In the test script I can check to see if AlertText is empty. If it is, then set the next request to “Update Environment”.
2.4 Postman(That’s Us!)
Updating the environment via the Postman API is needed only when using Postman monitoring, since collections can persist in collection runner. The only scripting needed is a simple test to end theservice: “postman.setNextRequest(null);”. This forces the collection to stop running after completing the current request.
Part 3. Setting Up a Monitor
Monitors allow you to specify a frequency at which to run a collection. You run a collection a frequencies from every 5 minutes all the way to every week. It is important to be conscious of API limits when setting up repeated and automated calls such as this one. If you only have 1000 calls a week and you decide to query once every five minutes (the shortest interval available), your service will stop working correctly at exactly 11:20 am every Wednesday (1000 / 12 = 83.3333… – (3 x 24) = 11.333… , or 3 days, 11 hours, and 20 minutes, Math!). Postman’s free plan allows for 1000 Postman API calls and 1000 monitoring calls a month. If you want an update every few minutes if those “Brotes de brócoli” are actually “Brotes de intestinal distress” – you should consider Postman Pro.
Once I’ve created my monitor, I let it run—it’s really as simple as that. It will run automatically at the frequency selected, until I turn it off. The Monitoring tab in my Workspaces Dashboard hasa graph of monitoring calls over time, with response time and success information!
More information about an individual collection run is available if you click on that run’s bar.
Part 4. Multiple Copies of The Best Atari Game, or, Pitfalls
4.1 Request and formatting:
Probably the largest issue I ran into with Scripts was a matter of programmatic thinking. I have an alarming willingness to run my head into a brick wall in order achieve functionality that can be easily side-stepped. I was trying to test for an empty array during the pre-request script of our SMS request, and then stop the request entirely if there wasn’t any message to send. This isn’t what Postman is built to do.
I’ll repeat: this isn’t what Postman is built to do. We are in the business of sending requests and interacting with API’s, not halting before we get to the actual interaction. While it’s possible this functionality could be introduced in the future, there is currently no way to stop a request in the pre-request script without using throw() to cause an error. This kills the collection. So, if you want to have a robust service that can loop and stop before sending its final (presumably broken) request then you, like I, must alter your thinking.
The reason we have post-request tests is so that we can test the results of our call before moving on.
“But I’m not getting anything relevant back from the request, I’m just sending a text!” You might say. Well, good for you—I said the same thing. After much code fiddling, I finally had the bright idea to put my exit condition (a check that the AlertText array is empty) in the test of the Twilio request rather than in the pre-request script. Boom! Suddenly it works.
One of the most important ideas in building with Postman is that you can’t treat it like any other coding platform. To achieve powerful functionality we need to adapt our thinking to an API-centric model of programming.
Part 5. What We’ve Learned
This was a fun first “big” project for me with Postman. Although the end functionality of simultaneously indulging germaphobes and burritophiles may seem negligible, I actually accomplished much more.
The three separate setup processes for the APIs were all quite similar, involving first making a few experimental calls in order to gather ID’s and properly target the information I wanted to send or change. There is no other development environment that allows me to collect this information without leaving, switching context, and going back & forth. As someone who used to build a lot of legacy integrations, shuffling between SSO logins, keys, secrets, web portals, queries, and what seems like hundreds of windows just to get the ID of a given record – it’s very clear why Postman is such a beloved tool.
My email checking, while nothing groundbreaking, is a nice example of using Postman to write scripts that check APIs for incremental changes. This functionality can be extended to most anything you’d want to do in a live service – checking weather, account balances, progress on a route, the list goes on! Whether you want to use a similar collection to test your service or power it, Postman can make that happen in surprisingly few lines of code.
The texting service I’ve created may be a great way to annoy my friends, but it’s also an excellent example of looping in a collection. This basic model for a loop (one that checks for an exit condition in the test and then either calls itself or exits the collection) is very easy to extrapolate into more complicated projects.
Postman monitoring is quite self evident in its usefulness – regularly testing an API for whatever you wish. Beyond that, monitoring can transform a one-off collection and turns it into a service. Persistent environments lets us push monitoring further, making it the engine for intricate services. In the end, I have a neat little collection that provides an excellent base to understand the numerous ways in which all of Postman’s features can interact. I’ve set the stage for even grander burrito-and-public-health centric technology – for which I’d love to hear your ideas, comments, and feedback. Until then, whether a text has you running to Chipotle or away from it, happy hacking!