Python Phone Push Notification Scheduler

Recently, I’ve been looking at solutions for pushing messages to my phone for work related activities. I work remotely, and often run jobs that take hours to run in the background. Simply having a notification that pushes to my phone to check a job’s results will suffice. I’m generally paranoid, so I’m particular about what information I trust to various providers. Part of this paranoia drives me to segregate my home and work traffic. Work (but non-corporate… think research) traffic takes place over a VPN, and often hits rate-limits with APIs due to other users. This project will setup a push notification system that will reschedule messages at a set time in the future if we hit an API limit.

Prerequisites

For this article, I will be using Notify My Android. They offer a free tier (5 notifications per day), or a premium account for a one time fee of $5.99. There’s a simple Python library called PyNMA that makes API interaction incredibly simple. I love redis, and decided that I’d use it as a task queue in python. Combine RQ with rq-scheduler and we have our full stack for the project. Go ahead and setup a new virtualenv like the one below and grab the requirements.

sudo apt-get install redis-server
sudo service redis-server start
mkdir nma_notify
virtualenv -p python3 ./env
pip install redis pynma rq-scheduler

You need to create an account at notifymyandroid.com. After you have registered and logged in, navigate to My Account, and you should see something similar to the screenshot below. You’ll need to generate a new key and save it for later. By default the script will read a single line from /home/ubuntu/.pynma_key and use it as the API key. You can change the path later, but go ahead and save it into your home directory and chmod it to 0600.

info

Test Push Messages

Now that we have all of the requirements, lets push a simple message to our phones.

#!/usr/bin/env python3

import pynma
API_KEY = 'api_key_goes_here'
p = pynma.PyNMA(API_KEY)
print(p.push('test', 'test', 'test'))

The required arguments for push are the application sending the event, the event type, and the description. Check the documentation to get a full list of options, but we will also use the following optional arguments in our scripts. url, priority(-2[low] to 2 [high]).

Queue Flow

Our event system will work in this way:

notify.py script to queue up event notifications to be sent out immediately.

rqscheduler needs to be run in the background and is responsible for adding the events back into the work queue at the appropriate time.

send_event.py will contain the worker code for the event queue. Error detection will be detailed in the next section, but if we hit an API limit, send_event will reschedule the notification for a time in the future after the API limit has been reset for rschedule to pickup.

rq worker pynma_queue needs to be run as well so that as new jobs become available (immediate or in the future) they will be executed sequentially.

Error Detection

PyNMA returns a dictionary with the result information after a push job has completed. Possible error codes that may come back from the server are the following.

Code Description
200 Success
400 Invalid format, length, or null
401 API keys provided were invalid
402 API calls per hour exceeded
500 Internal server error

We will only reschedule notifications if we receive the error code 402 as the others are either success or a failure that will reoccur if we send the same arguments again. The value of resettimer is in minutes.

Note the values returned are always strings, so take that into account when comparing values.

An example response follows:

{'api_key': {'code': '402', 'resettimer': '34', 'message': 'Your IP exceeded the maximum number of API calls per hour allowed.', 'type': 'error'}

notify.py

send_event.py

Sending Notifications

Before we start using notify.py, let’s go ahead and setup the workers and schedulers as discussed previously. From nma_notify directory, start the worker by typing the following.

rq worker pynma_queue

For the scheduler, run the following.

rqscheduler

Now, simply queue up a notification to be send out.

python notify.py test_app test_event test_description -h 'https://www.bitrot.sh' -p 2

If you’re not using a shared IP, you should immediately receive a message on your phone. You can also setup a nice alias in bash by doing something like this.

chmod +x notify.py
alias notify=/home/ubuntu/nma_notifier/notify.py
notify x y z -u 'https://url' -p 2

You have everything that you need to start adding notifications to all of the things in your Linux environment. Enjoy.

comments powered by Disqus