Email notifications from Firebase

So I built a pretty new website for my company using Polymer and it looks great.  I have a contact submission form that saves user’s contact information in a Firebase database.  Firebase is great, it’s easy to set up, easy to use (once you learn NoSQL), provide seamless syncing between your website, Android and iOS apps, they will host your site, provide SSL encryption, they provide a multitude of user sign in options, etc, etc.  I can’t say enough great things about Firebase.  However, Firebase is not built to do data processing.

So what’s a programmer to do when all those new contacts come flooding in from your new hotness website?  How do you know that anyone has filled out your form and wants to do business with you?  Should you monitor your Firebase console obsessively day and night? (Guilty!)  There has to be a better, easier way right?   Yes, there is!

Python to the rescue!  Python is a great programming language, if you haven’t picked it up yet then I highly suggest you give it a try.

So I decided to write a Python script to monitor my Firebase backend and send me an email whenever someone new adds their contact information to my website.  After writing the script you’ll also need to set up a way for the script to run on a recurrence.

 

 

There are several imports you’ll need for this script, first off is firebase-python, you can pip install this script – the instructions are in the link.  The remaining imports should already be available to you, so just set up your import section as so:

from firebase import Firebaseimport smtplibfrom email.MIMEMultipart import MIMEMultipartfrom email.MIMEText import MIMETextimport jsonimport logging

Next just connect up your Firebase instance to the script, pointing to your contacts node.  Set a reference to that Firebase instance –

firebase = Firebase('https://<YOURFIREBASEINSTANCE>.firebaseio.com/contacts')contact_list = firebase.get()

The way I’ve set up my script is I have two email accounts- The receiver account is the account I actually use on a day to day basis (I have a Google apps account for my business). The sender account is a dummy account that I made up for projects like this. Here’s one thing to keep in mind, your sender account will need to be flagged as less secure. This will allow Python to log in as you and send email, here’s the link to get that enabled. lesssecureapps

Here’s where the fun starts! We will set up our SMTP server and get it started, define our email addresses, get signed into our sender account and and begin setting up the message to be sent.

server = smtplib.SMTP('smtp.gmail.com', 587)server.starttls()fromaddr = 'sender_account@gmail.com'toaddr = 'receiver_account@gmail.com'msg = MIMEMultipart()msg['From'] = fromaddrmsg['To'] = toaddrserver.login(fromaddr, 'sender_account_password')

Now we’ll simply loop through the data and send ourselves an email if the contact has not been sent before. Also, we’ll update the contact and mark it as sent so we don’t keep sending the same contact information over and over. One thing that is very important – you want to UPDATE your Firebase data and not set it. If you set the data it will wipe out all the data you have with the current data, so that would leave you with only the current contact.

for cl in contact_list: contact_name = str(contact_list[cl]['name']) contact_phone = str(contact_list[cl]['phone']) contact_email = str(contact_list[cl]['email']) contact_message = str(contact_list[cl]['message']) contact_type = str(contact_list[cl]['type']) contact_pref = str(contact_list[cl]['contact']) try: contact_view = str(contact_list[cl]['viewed']) except Exception, e: contact_view = 'Y' logging.info(e) if contact_view == 'N': body = 'You have a new contact:<b> ' + contact_name + '</b> who would like to be contacted via ' + contact_pref + ' email address is: ' + contact_email + ' and phone is: ' + contact_phone + '. <br><br>The contact type is '+ contact_type + ' and the message is <br>' + contact_message msg['Subject'] = 'New Contact: '+contact_name msg.attach(MIMEText(body, 'HTML')) text = msg.as_string() server.sendmail(fromaddr, toaddr, text) contact_list[cl]['viewed']='Y' firebase.update(contact_list)

With that the email has been sent and the contact has been updated as viewed. One bit of house keeping and the script is done.

server.quit()

So the script is complete and you can test it via command line or IDE, depending on your setup. Assuming all your login information was correct and you didn’t encounter any errors (or resolved any that cropped up), now it’s time to focus on script execution. The script works great but the purpose of it is to notify you when someone registers on your site. You have a couple of options for this – 1. Spin up a Google App Engine instance and have it run as a cron job, 2. Have it run as a cron job on your own server, 3. Others? (feel free to leave comments.) I choose to run this on my own server and I have the perfect server for this job – a Raspberry Pi Model A. It’s perfect for this job because it is low energy, maintained by me and I have complete control over it.

I already have said Raspberry Pi set up running Rasbian (it’s tucked away in a spare bedroom) so I will just do a secure copy to push the file to the Raspberry Pi –

scp contact_script.py pi@ip_address_raspberry_pi:/home/pi

You’ll need to enter your password to giver permission to copy the file onto the raspberry pi.  Now we’ll ssh into the Raspberry Pi –

ssh@ip_address_raspberry_pi

Again enter your password for the Raspberry Pi.  At this point you should be at the command prompt in your home directory.  So let’s make sure our file was copied over successfully.  Enter the list command and verify that your script is there.

ls10_account.rc dead.letter python_games10_account.rc~ Desktop share20_frontends.rc contact_script.py80_httpd.rc80_httpd.rc.sample

Now you need to make the script executable –

chmod +x contact_script.py

Now the final step is to add the script to your crontab so it can be ran periodically. How often should you run it? That’s up to you, but I choose to have mine executed every 5 minutes. So I someone enters there contact information on my site then I will get a notification within 5 minutes and can email or call them back. So let’s edit your crontab and enter in the script information –

crontab -e# Edit this file to introduce tasks to be run by cron.# Each task to run has to be defined through a single line# indicating with different fields when the task will be run# and what command to run for the task## To define the time you can provide concrete values for# minute (m), hour (h), day of month (dom), month (mon),# and day of week (dow) or use '*' in these fields (for 'any').## Notice that tasks will be started based on the cron's system# daemon's notion of time and timezones.## Output of the crontab jobs (including errors) is sent through# email to the user the crontab file belongs to (unless redirected).## For example, you can run a backup of all your user accounts# at 5 a.m every week with:# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/## For more information see the manual pages of crontab(5) and cron(8)## m h dom mon dow command*/5 * * * * python /home/pi/contact_script.py

The last line is where the magic happens – let’s take it step by step.

Cron reads your entries like this:
Minute
Hour
Day of Month
Month
Day of Week
Command

So we entered:
Minute – “*/5” and Cron reads this as ‘Every 5 minutes’
Hour – “*” and Cron reads this as ‘Any Hour’
Day of Month – “*” and Cron reads this as ‘Any Day of the Month’
Month – “*” and Cron reads this as ‘Any Month’
Day of Week – “*” and Cron reads this as ‘Any Day of the Week’
Command – “python /home/pi/contact_script.py” and Cron reads this as ‘Execute the contact_script.py in the pi home folder using the system enabled version of Python’

Click Ctrl + X and save the crontab file. Now the script will be executed every 5 minutes and you’ll receive an email whenever someone new signs up for your website. To test it out go enter a new contact in your website and sit and wait for the email.

Thanks for reading, it took much longer to write this up than it did to write the actual script! Leave comments and let me know if you liked this and want to see more posts like this one.