Using GAE Cron to get SMS Alerts from Gmail
Who doesn’t love the free email service Gmail? I am currently using Google Apps Mail for this domain, and I got it installed in my computer, so I just have to switch windows to check messages. Most of the emails I am receiving is crucial, especially from Scriptlance. And when I am offline (either I am sleeping or I am not home), I don’t know if an email arrives, or if I should be online to respond to that email. So the solution for this? SMS alert.
I’m pretty sure there are lots of services that offer email alerts to your phone, but chances are, they are not free, and we are not sure if the login information is kept or used in something we do not like.
For this to work, there are some requirements:
- SMS Gateway
- Google App Engine Account
- Google App Engine SDK (and Python 2.5 of course)
- Your Gmail or Google Apps Mail credentials
The SMS gateway is not free in most cases, but you can use if a friend has one, just make sure it works with your carrier.
The first thing you need to do is create a GAE Application. Name it whatever you like, and on the
app.yaml, add these lines:
- url: /check/mail script: check.py login: admin
Of course you can changes the
script, but I just like to use that in this guide. Next is to create
cron.yaml, and put the following lines:
cron: - description: Check Mail url: /check/mail schedule: every 1 minutes
You can change the schedule on how frequent you like your mail to be checked. For me, I chose to check every one minute (There’s a grammatical error on the yaml file, but ignore it, it’s correct according to the syntax). That means, every minute, the script will check for unread messages and sends me a SMS message if there is one.
Next is to create a script called
#!/usr/bin/env python ''' Copyright (c) Ruel Pagayon <http://ruel.me> ''' from xml.dom.minidom import parseString from google.appengine.ext import db import urllib2 import urllib import base64 import sys ''' Change the values below. ''' gFeed = 'https://mail.google.com/mail/feed/atom' #gFeed = 'https://mail.google.com/a/domian.tld/feed/atom' #For Google Apps for Mail users. gEmail = 'firstname.lastname@example.org' gPass = 'pass' class Uid(db.Model): cont = db.StringProperty() def sendSMS(message): ''' Insert appropriate code for your SMS gateway here. Obviously the one below doesn't work. It's there to give you an insight on how it will work. ''' urllib2.urlopen('http://somegateway.com:1578/?user=smsuser&password=smspass&PhoneNumber=18005669874&Text=%s' % urllib.quote(message)) def getNewMail(feed): ''' Check for new unread mails. Use basic auth. ''' request = urllib2.Request(feed) base64string = base64.encodestring('&s:%s' % (gEmail, gPass)).replace('\n', '') request.add_header("Authorization", "Basic %s" % base64string) ''' Parse XML using DOM ''' xdata = urllib2.urlopen(request).read() dom = parseString(xdata) count = dom.getElementsByTagName('fullcount').firstChild.data ''' Retrieve last message ID from datastore ''' ouid = Uid.all() if ouid.count() != 0: lastId = ouid.cont if int(count) > 0: ''' Check if there are feed entries. Get the ID of the latest message. ''' eid = dom.getElementsByTagName('entry').getElementsByTagName('id').firstChild.data ''' Generate report. ''' message = "You got " + count + " new email(s)\n\n" for entry in dom.getElementsByTagName('entry'): ''' Loop through each email entry ''' message += "Sender: %s (%s)\n" % (entry.getElementsByTagName('name').firstChild.data, entry.getElementsByTagName('email').firstChild.data) message += "Subject: %s\n\n" % entry.getElementsByTagName('title').firstChild.data if eid != lastId: ''' If the last ID from the data store, is different from the latest message ID, update the data store and send the SMS ''' if ouid.count() != 0: nuid = Uid.get(ouid.key()) else: nuid = Uid() nuid.cont = eid nuid.put() sendSMS(message) ''' You got 1 new email(s) Sender: Someone (email@example.com) Subject: Example Message ''' def main(): getNewMail(gFeed) if __name__ == '__main__': main()
Change the values that suites your needs. And the docstrings on the script pretty much explains everything, so I don’t have to repeat it here.
Now, we all know that a free GAE app has quota, and on the script, we will be using the Data Store API and the UrlFetch API, let’s do some math. The quota will reset every 24 hours. So, if you decided to check the mail every 1 minute, we got 1440 calls. And it’s not even a quarter of the limit.
Now obviously we can use the script on our webservers, the only thing that we need to change is the data store calls (GAE doesn’t allow writing to disk, so Datastore is used). But the problem here is the credentials are in plain text, and there’s a huge risk for this information to be seen by other parties. So why not just use GAE? Where only you and Google can have access. :)