Saturday, September 16, 2006

SMS notification for new Gmail

Awesome! After some searching, I found a free SMS site that will allow unlimited messages without a captcha, (damn google) but it does add a short ad for the service to the text message which is tolerable considering the utility.

Instead of being a jerk, and just posting the code, and encouraging you to figure it out "yer damn self" I'm going to explain each of the lines cuz I'm in a teaching mood, and it's 3:30 in the morning...

#!/usr/bin/perl
$oldmail='0';

The first line declares this file as a Perl script
The second line declares the scalar ($) variable "oldmail" with a value of "0"

while(1){

This begins a WHILE loop (while) that will go on forever (1). It will continuously run the code contained within the {} following the statement. The opening { is at the end of this line, the closing } is all the way at the end of the script. This means it will continuously run the code contained within these curly brackets.

`curl -u USERNAME:PASSWORD https://mail.google.com/mail/feed/atom 2>/dev/null`=~/<fullcount>(\d+)<\/fullcount>/;

Err... Ok, so here's the tricky part... :)
We'll start with the first part:
`curl -u USERNAME:PASSWORD https://mail.google.com/mail/feed/atom 2>/dev/null`
Curl is a linux program which interacts with web servers. It's basicly a browser. What we're going to do here is obtain some information from Gmail's feed. The feed will tell us how many unread messages there are. The ` ("~" without the shift) is a container for shell code, this means that the code within is run in linux (bash, namely) instead of Perl. We have the name of the program we wish to run, curl, the user and pass info it will need, and the site it will get for us. The 2>/dev/null just says that if there are any errors, it should trash them to keep them from mucking up our output. Were I to run this line of code in a plain bash prompt I would get the following:
[bishop@Aemaeth ~]$ curl -u myusername:mypassword https://mail.google.com/mail/feed/atom 2>/dev/null
<?xml version="1.0" encoding="UTF-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#"><title>Gmail - Inbox for myemailaddy@gmail.com</title><tagline>New messages in your Gmail Inbox</tagline><fullcount>2</fullcount><link rel="alternate" href="http://mail.google.com/mail" type="text/html"/><modified>2006-09-16T10:27:27Z</modified></feed>

As you can see, the command will give us the info we want; the number of new messages we have. It's right between the two "fullcount" tags, and that's how we're going to find it...

Ok, now that we've covered the first part of that line of code, lets finish it up:
=~/<fullcount>(\d+)<\/fullcount>/;
The =~ means that the preceeding statement (the output of the command we just went over) should contain (=) the following expression (~) held within the forward slashes /.../ If you look inside those slashes you can see that fullcount HTML tag we were going to use to help the script pick up the number we want it to find. If you compair the match code <fullcount>(\d+)<\/fullcount> with the output of the command ...ne><fullcount>2</fullcount><li... You can see where we're we're going. But what does (/d+) mean? First, the parentheses (...) mean that whatever is within them will be assigned to a new variable named $1 that will be important in the next line. The /d is a code that means that program should try to match a digit (0123456789) in that spot, and the + means that it should try to match that digit one or more times. So, we're going to take one or more digits found between <fullcount> and </fullcount> and put those digits into a new variable called $1.

Everyone still with me??? :-\ That was the tough part.

if($1>$oldmail){

This is an IF statement. It says that if $1 (the number of unread messages) is bigger than the oldmail variable (0 at first) to run the code contained within the following curly brackets {...} So, using our example, I had two unread messages, so 2 is greater than 0, and the code will run.

`curl -s -c cookie https://www.vazu.com 2> /dev/null >/dev/null;curl -s -b cookie -d 'send_to=714-555-5555&send_from=714-555-5555&send_message=j00 %20haev%20teh%20mail&formstatus=1&countdown=96&Submit=Send' https://www.vazu.com/library/homepagesend.php 2> /dev/null > /dev/null; rm cookie`;

Ok, this is more linux code, since it's between the `...` basically, this code sends the SMS message to your phone by using a website that provides that service (for free). It's not critical that you understand it inside and out, but I've bolded some key points to make this a little clearer, and I'll go over some of the highlights. Note that there are three different commands here, lumped into one line; they are seperated by the semi-colon (;). The first command makes internet cookies by connecting to the web site. The next command uses those cookies to send a POST request to the server with some special codes the server needs to complete its job. The last command deletes the cookies as they are of no use. This code will tell the server to send a text message to 714-555-5555 saying "j00 haev teh mail" (because you do).

Congratulations! You've just received a text message for getting a new piece of mail! I have no doubt that this is the most meaningful moment of your life. :)

The next line is simply a "}" which signals the termination of the code to be run from that IF statement earlier.

$oldmail=$1;

Here, we're setting the oldmail number to the current number of unread messages for the next cycle. This way, it won't constantly get SMS messages because the number of unread messages is more than 0. Once it's reset to 2, if I get another message later, 3 will be greater than 2, and I'll receive an SMS saying I have new mail. Concordinately, if I read all my unread messages, and have 0 unread messages, 0 will not be greater than 3, and no SMS will be sent, and the 3 will be reset to 0 for the next round of messages. that made sense, right?

sleep(180);

This tells the script to wait for 180 seconds, otherwise it would run as fast as it could, and that would just be rude and unnecessary. You might set it to 10 seconds for testing, but in practice, 3 minutes is probably the fastest you could want it to update...

The last line is simply a "}" which closes the WHILE statement for code that should be run forever. Once the code gets here, it will go back to right after the WHILE statement and start over.


#!/usr/bin/perl
$oldmail='0';
while(1){
`curl -u USERNAME:PASSWORD https://mail.google.com/mail/feed/atom 2>/dev/null`=~/<fullcount>(\d+)<\/fullcount>/;
if($1>$oldmail){
`curl -s -c cookie https://www.vazu.com 2> /dev/null >/dev/null;curl -s -b cookie -d 'send_to=714-555-5555&send_from=714-555-5555&send_message=j00%20haev%20teh%20mail&formstatus=1&countdown=96&Submit=Send' https://www.vazu.com/library/homepagesend.php 2> /dev/null > /dev/null; rm cookie`;
}
$oldmail=$1;
sleep(180);
}

No comments: