Evanescent Thoughts

Evanescent Thoughts

Finding Invisible Friends and Dynamically Updating Your Status in Google Chat using XMPP Scripts #linux #python #ubuntu

with 24 comments


Read on, only if you Wanna do any of the following :

  1. Update your  google Chat status with info dynamically or fetch score from a website and display it every minute in your status msg.
  2. Find invisible friends in your chat list.
  3. Wanna change your status message as soon as some one signs on ?? aka make your own Buddy Pounce.
  4. Wish all your contacts by running a simple prog on important days. Like say, I wrote a script that wished  my  friends “Happy Friendship Day” when they appeared online 🙂 .
  5. Get a step closer to writing  your own back end for an IM client.
  6. Wanna remind someone about something over chat at a particular time or period when you might not  be online.
  7. And lots more that your imagination can limit.

Warning : I dont promise that everything in this is right. There might be  hell lot of mistakes. Feel free to point them out in the comments 🙂

Being someone who does a lot of IM and chatting, I was more curious about how a web chat works. How is it that you are instantly notified of your friend’s online presence and know when he is about to type something on your chat window. A little more digging and reading a couple of sites on XMPP  helped me figure out what I have been wanting to do a long time back in College. What basically you need for having a chat with your friend miles away is an XMPP Server (eXtensible Messaging and Presence Protocol) and an authenticated connection established to it. And of course an IM client (like google talk or pidgin or empathy) unless you wanna write your own command line scripts using some Python API for XMPP.

Firstly, I m not a big fan of gtalk, just cos it doesnt exist for Linux platform and who the hell uses an IM client just for google. An IM client is something that maintains all your chat accounts across various domains that u have a authentication on. An XMPP server listens to your xmpp requests on port 5222 and 5223. To give an idea about how the whole thing happens, imagine an XMPP server with which Alice and Bob have established their authentication. Unlike VOIP, chatting is done  with a man in the middle which happens to be the XMPP server. When Alice wants to send a IM(Instant Message) to Bob, Alice sends it to the server and the server sends it to  Bob. This sending and receiving is done in the form of XML packets. An XML stream runs between the Server  and Alice. A similar stream runs with Server and Bob. Whatever Alice puts on the XML stream is received by the server and the server reads the XML packet and looks at to whom the message is intended for and the server puts an XML packet to Bob’s XML stream and hence Bob receives the message Alice sent :). All this happens each time  u type something on ur IM client or change your status. Now this is  all about messaging. What about the status notifications and stuff ?? Thats where the presence part of XMPP comes to play. Basically a stanza in the XMPP stream between the server and the client can be etiher a Roster/Message/IQ/Presence. A Roster is used to notify the client about who all are online and registered with the server. A Message as I said above is a stanza that is used to communicate from one client to another through the server. A IQ is Info/Query where in u get specific info about a user. And finally a Presence is used to notify your type of availability to the other users (like busy , dnd  , away and put a status). This is the view of the XMPP  like how say you might see earth flying from an airplane . Each of these have their own specifications and finer details. For more, if you are interested, google it up .

When google opened a subdomain aka talk.google.com, users (the geeky ones) were able to authenticate and start chatting even before google officially announced that it has actually started an IM service :).  This happened back in 2004 when google first started the talk.google.com subdomain. Since then it kept on adding features to it chat client and led to group chat and stuff. But as I see, gtalk is not even close to an IM client. Its specific to google and has very limited capabilities when compared to pidgin or empathy. I am not talking about just using multiple accounts but about stuff that you can do with just your google accout like say control the presence notifications, add a  buddy pounce n stuff :). Well I can throw in more info with all my current enthu  about xmpp but I ll stop here and break straight to the part of writing cool scripts to do stuff with your google Chat that you cant do with your gtalk 🙂

Stuff that you might need : Python interpretor, xmpppy library for python. If you are in Linux , install python-xmpp and python-dnspython packages and you should be clear to go. If you are on windows, Keep breaking your head 😀

The first script I am gonna show here is how to send a message to a friend. This is how I started it. You might wanna cross check with the documentation here.

import xmpp
import getpass

user="sathya.phoenix"
passwd = getpass.getpass("Enter Password: ")
msg="helloworld"
to="deepblue.ar@gmail.com"

client= xmpp.Client('gmail.com',debug=[])
client.connect(server=('talk.google.com',5223))
client.auth(user,passwd)
client.sendInitPresence()
message = xmpp.Message(to,msg)
message.setAttr('type','chat')
client.send(message)

A quick look should tell you that Lines  1 and 2 import the necessary modules. The getpass module helps you to enter the password like the way you would enter it on a computer. Otherwise, you would have to put it somewhere and expose it (even better ways to do this are welcome in comments). I am declaring the variables in Lines 4,5,6,7. Line 9 , I create a xmpp Client with the parameters. When u specify the debug=[] option, the debug messages dont get thrown at you in the terminal. You connect to the server on port 5223 in Line 10 and authenticate in  11. Line 12 sends a Roster request and Initial Presence notification. You construct a message packet in the Line 12 and set its attributes in Line 13 and send it to server in Line 15 🙂 .

The next one I worked on was a script to dynamically update my status message with something like a clock or a cricket score. I am gonna leave to US on Aug 19th and thought how cool would it be to put a countdown on my status that updates how much time is left every minute(First I set it up every second, but it gets irritating to chat on the other end unless you have a very patient friend 😛 ).

import xmpp
import time
import datetime
import getpass

user="sathya.phoenix"
passwd = getpass.getpass("Enter Password: ")

client= xmpp.Client('gmail.com')
client.connect(server=('talk.google.com',5223))
client.auth(user,passwd)
client.sendInitPresence()

while(1):
	diff = datetime.datetime(2010, 8, 19,4,40,00) - datetime.datetime.today()
	days=str(diff.days)
	hrs=str(diff.seconds/60/60)
	minutes=str(diff.seconds/60 - (diff.seconds/60/60 * 60))
	seconds1=int(hrs)*3600+int(minutes)*60
	seconds= str(-seconds1+(diff.seconds))
	timeleft=days+" Days, "+hrs+" Hours, "+minutes+" Minutes more !!"
	pres=xmpp.Presence(priority=5, show='chat',status= timeleft )
	client.send(pres)
	time.sleep(60)

Lines  upto 12 are self explanatory . I then start a while loop and calculate the difference in time from the current time to the time when I ll be boarding my flight. The diff gives back a structured variable with diff in days and seconds. The seconds difference is done mod 86400 (ie no of seconds in a day). So make appropriate calculations to count the days, minutes and hours and seconds left in lines 15-20 and I construct a XML Presence stanza by calling the xmpp.Presence() and send it on to the XMPP server. After this, I pause the loop for 60 seconds in Line 24 to send the next update packet after a minute. You could do something like put up Live cricket scores  and stuff here to keep your friends informed or put a horizontally scrolling status msg or whatever that comes to your mind !! 🙂 .

The next script that I have is a script to find invisible friends in gtalk 🙂 .  This I find pretty much useful. I used to do the other way around (that is to make myself invisible from pidgin by sending an XMPP req)  cos Pidgin’s Inivisible status doesnt work well. I found the info here when I was googling it back in my coll. Basically I put the following XML snippet in my Pidgin’s XMPP console to make myself go invisible.

{{{
<presence>
<priority>5</priority>
</presence>
<presence type="unavailable">
<priority>5</priority>
</presence>
}}}

So I try to do the reverse of this from the Roster I get from the server and that should pretty much give the list of people who are invisible on gTalk :). Which I do in the following python code.

import xmpp
import getpass

user = "sathya.phoenix"
passwd = getpass.getpass("Enter Password: ")
server = "gmail.com"

client=xmpp.Client(server,debug=[])
client.connect(server=('talk.google.com',5223))
client.auth(user,passwd)
client.sendInitPresence(requestRoster=1)

def check(connec, event):
   if event.getType() == 'unavailable':
     print event.getFrom()

client.RegisterHandler('presence', check)

while client.Process(1):
  pass

Lines 1-10 again do the same authenticating and stuff while in Line 11 , instead of just sending the initPresence , we request for a Roster which gives us the status info of all my friends who have registered with the XMPP server. Now here is the magic. Even though you are invisible , your client registers with the XMPP server and sets the status as unavailable which the other Clients detect that and put you under the offline category(those who havent registered).  So all we got to do is to check for which of the registered users in the Roster are having a status “unavailable”. Pretty simple thing to break someone’s privacy huh 😉 .  So we have a handler to handle the presence notifications in the Roster and display the gmail ids that have status as “unavailable” and have registered with the server.  Now only disadvantage is that, if your friend is invi , he sure ends up on this list, but not vice versa. There are a couple more to check for that as well :).

So you could write handlers that can do a lot of stuff for you. Like you can send wishes to all online contacts by calling the client.send() in Line 15 and remove the if statement on Line 14. Or when some buddy of yours comes online , you can change your status message to soemthing else . Guess you can figure all that out by looking at the scripts above and combining them and making suitable modifications. Its all exciting !

PS : Any more cool ideas to do, put them on comments. Will try out 🙂 Also check this out if you wanna insert code snippets in your blog the easy way 🙂

Advertisements

Written by Sathya Narayanan

August 3, 2010 at 11:25 am

24 Responses

Subscribe to comments with RSS.

  1. I can notice that you did come up with something interesting… just that it is too techy for me to understand 😛

    Bharath

    August 3, 2010 at 2:47 pm

  2. Interessssssssting. 🙂 Will try it out tonight. 🙂

    Alagappan

    August 3, 2010 at 3:10 pm

    • sure 🙂 heard its a lot of python work at GA ..

      Sathya Narayanan

      August 3, 2010 at 3:28 pm

  3. Nenachaan.. i thought u’ll leave ur friends spellbound for some days wit ur status msg.. then u’ll reveal the source..

    Gave away the snippets soon 🙂

    Vinod

    August 3, 2010 at 10:23 pm

    • will be going to blr for a week.. so thought of finishing the post before that 🙂

      Sathya Narayanan

      August 3, 2010 at 10:42 pm

  4. Similar one Twitt your Google status http://www.h3manth.com/content/twiit-your-google-status

    init0

    August 6, 2010 at 9:15 am

    • great stuff in ur blog man 🙂 awesome 🙂

      Sathya Narayanan

      August 6, 2010 at 2:22 pm

  5. yeah its great. thanx 🙂

    chat hr

    August 7, 2010 at 1:25 pm

  6. Nice Thanks

    Leo

    August 9, 2010 at 3:58 am

  7. i didnt understand…..

    abhimaan

    August 9, 2010 at 11:32 am

    • probably the reference docs and wiki wud help u 🙂

      Sathya Narayanan

      August 9, 2010 at 9:42 pm

  8. I am trying to write a python script that shows different status msgs to different ppl
    and also different availability statuses

    I just need to send XMPP strings through python. I know what to send.
    Do you know a direct function to send raw xmpp strings through DBUS?

    hittudiv

    August 19, 2010 at 1:32 pm

  9. I want it through DBUS

    hittudiv

    August 19, 2010 at 1:33 pm

  10. Going offline also puts in invi list

    Shijith T

    September 9, 2010 at 12:36 am

  11. The next script that I have is a script to find invisible friends in gtalk 🙂 . This I find pretty much useful. I used to do the other way around (that is to make myself invisible from pidgin by sending an XMPP req).

    can you elaborate this above sentence.? How will you find people who are invisible just by making yourself invisible by sending “unavailable” presence through pidgin.?

    sharath

    October 21, 2010 at 1:31 pm

    • no .. i check which all contacts have registered with the server but set their status to unavailable (which makes them invisible) .. if they hadnt signed on, they wudnt be registered with the server..

      Sathya Narayanan

      October 21, 2010 at 3:08 pm

  12. Huh great blog! This is for everyday reading :-)! Thanks!

    Chat

    October 31, 2010 at 8:49 am

  13. Interesting….

    Sasikumar

    January 9, 2011 at 7:21 am

  14. If a user signs in and then signs off. This will display them as well. Not exactly foolproof…

    Pradeek

    February 1, 2011 at 8:43 am

    • true !! thats why i said there can be false positives 🙂

      Sathya Narayanan

      February 15, 2011 at 9:11 pm

  15. Hey man!! i had tried out ur cool stuffs today..Thanks a lot dude..

    Gowtham

    February 17, 2011 at 11:26 am

  16. when i tried ‘finding invisible friends’ i’ve got both offline and invisible friends..how to find invisible friends alone?

    Gowtham

    February 21, 2011 at 10:42 am

  17. Very well written post. Kudos.

    Avi

    March 30, 2011 at 11:44 am

  18. Hey does this still work ? I’m facing some prolems when I run the code, i get a lot of debug errors , the way i run the script is ‘python script.py’

    Harish

    March 30, 2011 at 4:24 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: