May 02, 2008

Posted by John

Tagged launchd, rexml, twitter, web services, and xml

Older: Twitter Gem Gets STDIN

Newer: ToDo's On Your Desktop

Update Your Friends iChat Status With A Twitter Direct Message, Simply Because You Can

I have a dream. A dream wherein I can update a buddy’s iChat status remotely. It’s not a change the world dream, but it would be fricken sweet, right?. I mean imagine your fiend coding up a storm on his computer and all of a sudden noticing that his iChat status says ‘I have a man-crush on DHH.’ I know you are feelin’ me.

Anyway, I guess I should drop some history. The dream started a year back with Steve, Apache and PHP, but quickly faded as we lost interest. A few days back, the dream was rekindled, this time with Chas, Twitter and Ruby and it has now ended in success.

The Goal

The goal is very unselfish. I don’t want this power all to myself. I want to share it with all my friends, that is with the exception of who we shall now refer to as “the victim.” We wanted to be able to allow ourselves and a few friends the ability to update one of our other friend’s iChat status (“the victim”) from anywhere. What is a tool we all use, all the live long day? Twitter. The solution is actually pretty simple. It’s only 3 steps. Create a private twitter account that you can all direct message. Install a ruby script on “the victim’s” computer. Setup scheduled task to run ruby script every few minutes. I’ll now detail these steps with code samples but remember, with great power comes great responsibility (and laughter).

Step 1 – Create Private Twitter Account

Create a twitter account and make it private. All the friends that would like to have power over “the victim” should then request to follow the new account and you should approve them. This means that any friend who follows that account, and that you approve, can now direct message that account. The general public cannot. Now the group of controlling friends needs only to twitter ‘d newtwitteraccount some new ichat status’ and the next status for “the victim” is ready to be set.

Step 2 – Install Ruby Script

Ok, so I could care less about windows. Knowing that, I’m only dealing with Mac’s. What does every mac come with? Ruby. What language do I make love to every night? Ruby. Now beings that I wrote the twitter gem, you might assume that I used that in the script. You’d be wrong. You know what they say about assuming, right? It makes an ass out of ‘u’ and ‘ming’ or something like that.

More than likely you will only have a few bathroom break minutes to setup everything on your friends computer. This means we need the least amount of dependencies to slow us down. Below is the quick and dirty script I wrote to get the latest direct message from a twitter account using only core ruby libraries. Basically it grabs the latest direct message and if it is new, it executes some applescript to update the iChat status.

#!/usr/bin/env ruby
%w[open-uri rexml/document fileutils].each { |x| require x }

Debug = true
Username = 'newaccount'
Password = 'password'
dms = []
url = "http://twitter.com/direct_messages.xml"
lines = ['tell application "System Events"', 'if exists process "iChat" then', 'tell application "iChat"', 'set the status message to "#{latest}"', 'end tell', 'end if', 'end tell']
puts 'Doing some magic' if Debug
data   = open(url, :http_basic_authentication => [Username, Password]).read
doc    = REXML::Document.new(data)
doc.elements.each('direct-messages/direct_message/text') { |el| dms << el.text }
latest = dms.first
if latest
  puts 'we have a latest message' if Debug
  open('latest.txt', 'w+') do |f|
    last = f.gets
    if latest != last
      puts 'we are changing ichat status now' if Debug
      f.puts latest
      cmd = "-e '#{lines.collect { |l| l.gsub('#{latest}', latest) }.join("' -e '")}'"
      system "osascript #{cmd}"
    end
  end
end

This script should be located at ~/Library/TwitteriChatHack/twitter-dm.rb. Be sure to update Username and Password to the private account you just created in step 1.

Step 3 – Schedule Task to Run Ruby Script

We have our script, but it does nothing without being told to. That said, we have to schedule it to run on an interval. Mac OSX has a great scheduling tool called launchd. It appears to be a black art, but is actually really easy to use. Justin just wrote up a great article on how to automate rick-rolling your friends with launchd. Below is the sample launchd plist item that instead of rick-rolling, will run our ruby script from step 2.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.addictedtonew.twitter.ichat.hack</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/bin/env</string>
		<string>ruby</string>
		<string>/Users/MACOSXUSERNAME/Library/TwitteriChatHack/twitter-dm.rb</string>
	</array>
	<key>RunAtLoad</key> <false/>
	<key>StartInterval</key> <integer>60</integer>
</dict>
</plist>

This script should be located at ~/Library/LaunchAgents/com.addictedtonew.twitter.ichat.hack.plist. Be sure to change MACOSXUSERNAME with your friends max osx username.

Now the only thing left to do is to actually load the task into launchd. If you don’t do this, your script won’t work until “the victim” logs out and back in. Just run the following command:

launchctl load ~/Library/LaunchAgents/com.addictedtonew.twitter.ichat.hack.plist

Summary

That’s it. Once you create the private twitter account, add the ruby script onto “the vicitim’s” computer and setup the launchd task, you can can ‘d twitteraccount i love britney spears’ and within a minute your friend’s iChat status will be updated appropriately. Below is an example on my computer of the direct message and iChat status update.

Notes

  • The interval at which the status can be udpated at is set with the StartInterval number. Mine defaults to 60 but you might want to set it to 300 (every 5 minutes) so you aren’t continually checking for updates.
  • The ruby script checks to see if iChat is running and only attempts to udpate status if it is so it won’t pop open iChat on your friends computer every minute.
  • The ruby script also saves the last direct message that was used so if you direct message and your buddy changes his status back to something else, it will only change it again if you put through a new direct message.

So that is all. What kind of crazy things like this have you all done?

0 Comments

Sorry, comments are closed for this article to ease the burden of pruning spam.

About

Authored by John Nunemaker (Noo-neh-maker), a web developer and programmer who has fallen deeply in love with Ruby. More about John.

Syndication

Feed IconRailsTips Articles - An assortment of howto's and thoughts on Ruby and Rails.

Feed IconRails Quick Tips - Ruby and Rails related links.