A colleague approached me with this very important business problem:
Every Friday at SAS HQ, SAS cafe staff provides a breakfast goodie in our breakrooms. Often the supplied goodie is delicious, but sometimes it's more...well...healthy. I want to know whether I should eat my breakfast before I leave home on Friday morning, or if it's better to save my calories for the breakfast goodie at SAS. Can I write a SAS program to send me a text message on Friday morning with the "goodie news" so I can make an informed decision?
Find the data source
SAS HQ publishes the cafeteria menus on our intranet each day, and on Thursday the published menu includes an entry for the planned Friday goodie. Thus, we know that this "data" is available somewhere. My colleague had the idea of using FILENAME URL or PROC HTTP to have SAS read the cafe's menu web page and parse the details about the breakfast goodie. That's one way to do it, but here's something that I know about web pages: they all have source files somewhere that are used to generate the content you see in the browser. If you can gain access to that source file instead of going through the web server, you'll have a much simpler process.
With a little spelunking on the SAS network, I found the source files that feed the cafe menus. ("Feed" -- see what I did there?) The file with the goodie news is an HTML file that is named with a predictable date stamp. Here's the name for today: "../menus/DailyMenus/BreakfastWeb20160812.html". The source file looks like this:
<!-- Published on Thursday, August 11, 2016 01:02 PM--> <h2 class="menuHeader">Friday Breakfast Goodie</h2> <div class="entry fridayGoodie"><div class="menuLeft"><div class="menuLeftContent"> <span class="entryName">Blueberry Almond Crunch Teacake</span> </div></div></div>
We want just the goodie name. With a file reference to the menu file, we can easily parse this out with SAS. After this step, the goodie text is stored in the GOODIE macro variable.
/* Assuming this is run on Friday */ %let day = %sysfunc(compress(%sysfunc(today(),yymmdd10.),'-')); filename bg "../menus/DailyMenus/BreakfastWeb&day..html"; data _null_; infile bg dsd; length line $ 80 goodie $ 40; input line; /* Line with the goods */ if (find(line,'span class="entryName"') >0) then do; startpos = find(line, '>'); endpos=find(line, '</'); goodie = substr(line,startpos+1,endpos-startpos-1); call symput('GOODIE',goodie); end; run;
Sending the SMS message with SAS
Finally, we're getting to the part of this article that you probably came to read: how to send the text message with SAS. This feels a bit like cheating, but there isn't any magic function in SAS that sends SMS messages. Instead, we're going to rely on a mobile phone service trick. Most phone service providers allow you to send text messages via e-mail by using a special address scheme for the text message recipient. Each carrier is a little different, but you can find the details with a simple internet search: "sms via email".
My current carrier is AT&T, and so to receive a text message as e-mail I would send it to the address firstname.lastname@example.org. With the FILENAME EMAIL method, it's easy to send an e-mail using SAS. The trickiest part might be to find your SMTP server host name and other details. Using a service like Gmail? I've written a blog post about how to send e-mail with that method. Note: as with all phone text messages, text-message charges from your carrier may apply.
options emailhost='mailserver.company.com' emailsys=smtp; /* NOT my real phone number */ filename msg email to="email@example.com" FROM = "Cafe Bot <firstname.lastname@example.org>" subject="Breakfast goodie: &Goodie."; data _null_; file msg; put 'Bon appetit!'; run;
Here's an example of the text message from my phone:
Scheduling the SAS job to run automatically
This entire process is valuable only if we can run it unattended, without having to remember to trigger it every Friday morning. After all, if you can log in to run a SAS job that sends yourself a text message, you can (probably more easily) just check the breakfast menu for the day. So my colleague scheduled this program to run early every Friday morning at SAS using a cron job, the ubiquitous scheduler on UNIX. I imagine that his crontab -l output looks something like:
00 05 * * 5 /usr/local/bin/sas -nodms -sysin '/u/userid/food/breakfastgoodie.sas'
That sets up the job to run at 05:00 on day 5 (Friday), running SAS with this program as input. In the immortal words of Ron Popeil: Set it, and forget it!