Last week I blogged about my first experience working with OpenWhisk triggers and rules, specifically the Cron trigger which lets you execute actions according to a schedule. Today I'm sharing another example, which, while not as complex as the 911 scraper, I thought was kind of fun.
As a blogger, I try to keep to a certain amount of posts per month. While I a absolutely care more about quality than quantity, I still try to maintain a certain amount of content per month. I thought it would be fun to create an OpenWhisk action that would nag me if I hadn't blogged in a few days. This turned out to be rather simple:
- First, I get the RSS feed.
- Then I parse the XML. There's packages to read RSS, but there's also xml2js which just does a basic conversion.
- I can then check the date of the most recent article and compare it to now.
- If it's been too long, nag!
Let's start with the action:
const request = require('request');
const parseString = require('xml2js').parseString;
//number of days you have till i bug you
const NAG_DAY = 2;
//SendGrid API Key
const SG_KEY = 'SG.whywontanyonecommentonthestuffiputhere';
const helper = require('sendgrid').mail;
function doNag(last) {
let from_email = new helper.Email('raymondcamden@gmail.com');
let to_email = new helper.Email('raymondcamden@gmail.com');
let subject = 'You Need to Blog!';
let content = `
You have not blogged in the past ${NAG_DAY} days!
Your last post was on ${last}.
`
let mailContent = new helper.Content('text/plain', content);
let mail = new helper.Mail(from_email, subject, to_email, mailContent);
let sg = require('sendgrid')(SG_KEY);
var request = sg.emptyRequest({
method: 'POST',
path: '/v3/mail/send',
body: mail.toJSON()
});
sg.API(request, function(error, response) {
if(error) {
console.log(error.response.body);
} else {
//right now we do nothing really
}
});
}
function main() {
let rssurl = 'http://feeds.feedburner.com/raymondcamdensblog';
return new Promise((resolve, reject) => {
request.get(rssurl, function(error, response, body) {
if(error) return reject(error);
parseString(body, function(err, result) {
if(err) return reject(err);
//Latest post:
let latest = result.rss.channel[0].item[0];
//now lets try to parse the date
let latestDate = new Date(latest.pubDate[0]).getTime();
//alright then - so compare Now to latestDate
let now = Date.now();
//difference is how much time (duh)
let diff = now - latestDate;
if(diff > (NAG_DAY * 24 * 60 * 60 * 1000)) {
console.log('got to nag!');
doNag(latest.pubDate[0]);
resolve({status:true});
} else {
resolve({status:false});
}
});
});
});
}
exports.main = main;
Start with the main
function which is OpenWhisk's entry point to the function. I use the request library to open up my RSS feed and then parseString
from the xml2js library. I can then get the most recent blog entry (which is the first entry in a RSS feed) and make a date object with it.
Once I have that - then it's math. I set the constant NAG_DAY
to 2, which is a bit too low if you ask me, but I had blogged on Friday so I needed a value that would trigger the alert. (For folks curious, I try to blog once every 3 days.) If we need to nag, we then simply call doNag
.
The doNag
function just writes an email using the Sendgrid API and fires it out. And that's it.
So then I had to make this "live" - which beforehand would have meant provisioning a server and all that, but with the wonders of Serverless (yes, I'm half-joking here ;) I just did the following:
- Sent the action up to OpenWhisk with the CLI (
wsk action create --kind nodejs:6 rssnag rssnag.zip
) - Made the trigger (
wsk trigger create checkBlog --feed /whisk.system/alarms/alarm --param cron "* * 1 * *"
). That Cron value is for once a day, and yes I had to use http://crontab-generator.org again. - Made the rule (
wsk rule create blogNagRule checkBlog rssnag
)
And that's it. To test I used the OpenWhisk UI on IBM Bluemix and manually triggered it. And the result....