AAIMI Email: React to incoming email commands using Python
5th March 2017
The latest Python module from the AAIMI Project is AAIMI Email. This is a stand-alone, general-purpose version of our incoming email client from the AAIMI Home Automation platform.
The program allows you to control a Linux computer or server by sending emails. You just need to add your own functions and actions, and AAIMI takes care of the rest.
I've tried to keep things as simple as possible for this first version. It reads incoming emails but can't send emails. The next version will have an outbound client that can send access codes to verify senders. At present, it can only verify the email address from the headers in the email. Note that this means someone else could spoof your email address and - providing they know the format and keywords for your functions - send commands to the system
Download and setup
Before you begin you'll need to get a dedicated Gmail address for the system. This is the address you send commands to. You'll also need to allow third-party apps in the Google settings for that account.
In the folder you'll find the LICENSE text that nobody reads, which tells you you can do anything you want with this program, including modifying, renaming and sharing the code. There's also a text file for the email log. The email program is called aaimi_email_01.py.
You'll need to modify a few lines in aaimi_email.py. Open the file and go to line 34.
Replace SystemEmail with the dedicated Gmail address for your system. Leave the system_pass variable on line 36 blank, AAIMI will prompt for that on startup.
Next scroll down to the user_authentication variable on line 47.
By default this is disabled, meaning anyone can send an email. This is probably not ideal, although it might be entertaining.
If you wish to use a whitelist of email addresses(recommended), change user_authentication from 'no' to 'yes'.
Beneath that on line 50, replace 'YourEmail' with your Gmail address, and 'YourName' with your first name. Add entries for any other users who need to email the system
Next scroll to line 79 and you'll find the socket_or_direct variable. This denotes whether the program reacts to emails locally or over a web socket to another program running on your computer.
Set to 'direct' AAIMI react to an email by calling functions from within the program. These functions are the ones we'll add next.
Set to 'socket' AAIMI will instead route the email command to another running program. There are a few reasons you may wish to do this. One example is if you wish to perform system-level functions that require root privileges. You can run AAIMI as a standard user, and have all your functions in a background program running as root. You'll need to set up a listening socket in your other program on the same port as shown below.
Add your functions
Because I want this to be a general-purpose program I am leaving it to you to add the functions called when an email arrives. The only functions I've added and enabled is an echo function to test the system. When this function is called it merely prints the command parameters you sent in your email.
It's up to you to create or add your own functions to suit your needs.
I'll walk you through the process of creating a function from scratch and adding the call to the schedule_change() function.
You add you functions starting on line 205. You can create and call as many functions as you need. The first word in your email decides which function to call.
As an example, to call the included echo_email_parameters() function, the first word in your email will be 'echomail', followed by a space. In this case the rest of the words can be anything, as long as it is between two and four space-separated words. The functions sole task is to repeat the test parameters you send, so use what you want. The body of your email would look something like this:
(echomail repeat my parameters)
The parentheses are vital, because that's How AAIMI finds your command among all the junk hidden in all emails
You should see 'repeat my parameters' printed in the terminal.
Now to build a new function. For this example I'll make a logging function to keep track of work hours. The user can enter their hours into an email each day after work and AAIMI will add it to a work log.
Below the echo_email_parameters() function, declare a new function called log_my_hours().
The schedule_change() function now looks like this:
That's it, we've created and added a new function. To log your work hours via email, send AAIMI an email like this:
(work high_st 0800 1600 7.5)
The first word, 'work', tells AAIMI you wish to log your work hours. The subsequent words are the work location, start time, finish time and total hours minus breaks.
I'll leave the new function in the code as an example of how you can use AAIMI Email.
To make more functions you'll need to decide on a command name for the first word, and add whichever parameters your function requires as the second, third and, if necessary, fourth and fifth word in the email, as parameters in your function. You'll then route those parameters via the call to your function in schedule_change().
Running the program
To fully utilize AAIMI Email it needs to be on 24/7 in the background on your computer, regardless of whether you are logged on. We'll use a Linux tool called Screen for this. Screen will run the program in the background for as long as the computer is turned on.
You may need to install screen.
sudo apt-get install screen
To start a Screen session type sudo screen and press Enter. Press Spacebar to clear welcome messages. You'll now see a new all-white prompt.
Type python aaimi_email_01.py
You'll be prompted for the system Gmail password.
After this AAIMI will log into Gmail and count the number of emails. On the first run it will not read the existing mail, just count them and set a variable. This is so the system won't re-execute all the old commands if you don't empty the inbox when you restart the program.
Any time the number of emails changes, AAIMI will read the new mail and send the command and parameters to the schedule_change() function.
To exit the screen session, press and hold control, press A, then D. If you don't exit this way Screen may turn off.
That's it for now, have fun. Stay tune for a more-polished and powerfull version 0.2 in a few weeks.