<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -24,17 +24,41 @@ require 'rubygems'
 require 'xmpp4r/client'
 require 'xmpp4r/roster/helper/roster'
 require 'facebooker'
+require 'twitter'
 require 'log4r'
 require 'yaml'
+require 'openssl'
+require 'digest/sha1'
+require 'base64'
 
 # Load config file
 config = YAML.load_file(&quot;#{File.dirname(__FILE__)}/../config/config.yml&quot;)
 XMPP_JID = config['jabber_id']
 XMPP_PASSWORD = config['jabber_password']
+TWITTER_CRYPT_KEY = config['twitter_crypt_key']
+TWITTER_CRYPT_IV = config['twitter_crypt_iv']
 FB_API_KEY = config['facebook_api_key']
 FB_API_SECRET = config['facebook_api_secret']
 ADMIN_JID = config['admin_jid']
 
+def facebook_enabled?
+  FB_API_KEY &amp;&amp; FB_API_SECRET
+end
+
+def twitter_enabled?
+  !TWITTER_CRYPT_KEY.nil?
+end
+
+def service_name
+  if facebook_enabled?
+    return &quot;Facebook&quot;
+  elsif twitter_enabled?
+    return &quot;Twitter&quot;
+  else
+    raise &quot;No service defined!&quot;
+  end
+end
+
 # Create logger
 @@log = Log4r::Logger.new 'log'
 @@log.outputters = Log4r::Outputter.stdout
@@ -64,6 +88,35 @@ module Jabber
         session.secure_with!(session_key, session_uid, 0, secret_from_session)
         return session
       end
+      def twitter_credentials=(credentials)
+        # Create hashed password
+        c = OpenSSL::Cipher::Cipher.new(&quot;aes-256-cbc&quot;)
+        c.encrypt
+        c.key = Digest::SHA1.hexdigest(TWITTER_CRYPT_KEY)
+        c.iv = Digest::SHA1.hexdigest(TWITTER_CRYPT_IV)
+        crypted_password = c.update(credentials[1])
+        crypted_password &lt;&lt; c.final
+        # Encode
+        crypted_password = Base64.encode64(crypted_password)
+        @@log.debug &quot;Storing twitter credentials for #{jid}&quot;
+        self.iname = &quot;#{credentials[0]} #{crypted_password}&quot;
+        @@log.debug &quot; - stored \&quot;#{self.iname}\&quot;&quot;
+        send
+      end
+      def twitter_credentials
+        @@log.debug &quot;Restoring twitter credentials for #{jid}&quot;
+        username, crypted_password = self.iname.split
+        # Decode
+        crypted_password = Base64.decode64(crypted_password)
+        # Decrypt password
+        c = OpenSSL::Cipher::Cipher.new(&quot;aes-256-cbc&quot;)
+        c.decrypt
+        c.key = Digest::SHA1.hexdigest(TWITTER_CRYPT_KEY)
+        c.iv = Digest::SHA1.hexdigest(TWITTER_CRYPT_IV)
+        password = c.update(crypted_password)
+        password &lt;&lt; c.final
+        return username, password
+      end
     end
   end
 end
@@ -85,24 +138,40 @@ def add_new_user(jid)
   @@log.debug &quot;adding new user #{jid.to_s}&quot;
   # Accept subscription
   @@roster.accept_subscription(jid)  
-  # Open facebook session
   key = jid.strip.to_s
-  @sessions[key] = Facebooker::Session::Desktop.create( FB_API_KEY, FB_API_SECRET )
-  # Send welcome messages
-  send_message jid, :chat, &quot;Hi there #{jid.node.capitalize}! I can update your Facebook status for you if you like, but I need you to do a couple of things for me in order to do so.&quot;
-  send_message jid, :chat, &quot;Please go to #{@sessions[key].login_url} and log in. Make sure you check the box which says 'save my login info'.&quot;
-  send_message jid, :chat, &quot;Then, please go to http://www.facebook.com/authorize.php?api_key=#{FB_API_KEY}&amp;v=1.0&amp;ext_perm=status_update, check the box and click OK.&quot;
-  send_message jid, :chat, &quot;When you've done those, come back here and let me know (just type OK or something).&quot;
+  if facebook_enabled?
+    # Open facebook session
+    @sessions[key] = Facebooker::Session::Desktop.create( FB_API_KEY, FB_API_SECRET )
+    # Send welcome messages
+    send_message jid, :chat, &quot;Hi there #{jid.node.capitalize}! I can update your Facebook status for you if you like, but I need you to do a couple of things for me in order to do so.&quot;
+    send_message jid, :chat, &quot;Please go to #{@sessions[key].login_url} and log in. Make sure you check the box which says 'save my login info'.&quot;
+    send_message jid, :chat, &quot;Then, please go to http://www.facebook.com/authorize.php?api_key=#{FB_API_KEY}&amp;v=1.0&amp;ext_perm=status_update, check the box and click OK.&quot;
+    send_message jid, :chat, &quot;When you've done those, come back here and let me know (just type OK or something).&quot;
+  elsif twitter_enabled?
+    # Flag twitter session pending
+    @sessions[key] = &quot;pending&quot;
+    # Send welcome messages
+    send_message jid, :chat, &quot;Hi there #{jid.node.capitalize}! I can update your Twitter status for you if you like, but I need your Twitter details in order to do so.&quot;
+    send_message jid, :chat, &quot;Please send me your Twitter username and password, with a space in between. For instance, type 'james my_password'.&quot;
+  end
 end
 
 def set_status(user, message)
   message = unescapeHTML(message)
-  @@log.debug &quot;setting Facebook status for #{user.jid.to_s} to \&quot;#{message}\&quot;&quot;
-  session = user.facebook_session
-  session.user.status = message
-  &quot;#{session.user.name} #{session.user.status.message}&quot;
+  if facebook_enabled?
+    @@log.debug &quot;setting Facebook status for #{user.jid.to_s} to \&quot;#{message}\&quot;&quot;
+    session = user.facebook_session
+    session.user.status = message
+    &quot;#{session.user.name} #{session.user.status.message}&quot;
+  elsif twitter_enabled?
+    @@log.debug &quot;setting Twitter status for #{user.jid.to_s} to \&quot;#{message}\&quot;&quot;
+    username, password = user.twitter_credentials
+    twitter = Twitter::Base.new(username, password)
+    twitter.post(message)
+    message
+  end
 rescue
-  &quot;It looks like your Facebook session has expired :(&quot;
+  &quot;Sorry - something went wrong!&quot;
 end
 
 def remove_user(roster_item)
@@ -157,7 +226,7 @@ subscription_callback = lambda { |item,presence|
     dump_roster if @@log.debug?
     if u.nil?
       @@log.debug &quot;... couldn't find user '#{from_jid.strip}' in roster - saying hello&quot;
-      send_message(from_jid, m.type, &quot;Hi! I don't think I know you - please add me to your contact list, and I can update your Facebook status for you!&quot;)
+      send_message(from_jid, m.type, &quot;Hi! I don't think I know you - please add me to your contact list, and I can update your #{service_name} status for you!&quot;)
     elsif m.body == 'exit' and from_jid.strip == ADMIN_JID
       @@log.debug &quot;... exit received&quot;
       send_message(from_jid, m.type, &quot;Exiting...&quot;)
@@ -168,17 +237,29 @@ subscription_callback = lambda { |item,presence|
       unless @sessions[key].nil?
         @@log.debug &quot;... storing session data in roster&quot;
         begin
-          @sessions[key].secure!
-          u.facebook_session = @sessions[key]
+          if facebook_enabled?
+            @sessions[key].secure!
+            u.facebook_session = @sessions[key]
+            send_message(from_jid, m.type, &quot;Thanks! You should now be able to set your status by just sending me a message. For instance, if you send 'is using JabberStatus', I will set your Facebook status to 'Yourname is using JabberStatus'. Try it out!&quot;)
+          elsif twitter_enabled?
+            twitter_credentials = message.squeeze(' ').split(' ')
+            @@log.debug &quot;... extracting username #{twitter_credentials[0]} and password #{twitter_credentials[1]}&quot;
+            raise &quot;bad credentials&quot; if twitter_credentials.size != 2
+            u.twitter_credentials = twitter_credentials
+            send_message(from_jid, m.type, &quot;Thanks! You should now be able to set your status by just sending me a message. Try it out!&quot;)
+          end
           @sessions[key] = nil
           @@log.debug &quot;... done&quot;
-          send_message(from_jid, m.type, &quot;Thanks! You should now be able to set your status by just sending me a message. For instance, if you send 'is using JabberStatus', I will set your Facebook status to 'Yourname is using JabberStatus'. Try it out!&quot;)
-        rescue
-          send_message(from_jid, m.type, &quot;Oops - something went wrong - we couldn't get the right details from Facebook. Did you check the 'save my login info' box?&quot;)
+        #rescue
+        #  if facebook_enabled?
+        #    send_message(from_jid, m.type, &quot;Oops - something went wrong - we couldn't get the right details from Facebook. Did you check the 'save my login info' box?&quot;)
+        #  else
+        #    send_message(from_jid, m.type, &quot;Oops - something went wrong. Sorry!&quot;)
+        #  end
         end
       else 
         new_status = set_status(u, message)
-        send_message(from_jid, m.type, &quot;I set your Facebook status to: \&quot;#{new_status}\&quot;&quot;)
+        send_message(from_jid, m.type, &quot;I set your #{service_name} status to: \&quot;#{new_status}\&quot;&quot;)
       end
     end
   end</diff>
      <filename>bin/jabberstatus.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,8 @@
 jabber_id: jabber_id_you_want_to_use_as_gateway_goes_here
 jabber_password: jabber_password_goes_here
-facebook_api_key: your_facebook_api_key_goes_here
-facebook_api_secret: your_facebook_api_secret_goes_here
+facebook_api_key: your_facebook_api_key_goes_here_if_using_facebook
+facebook_api_secret: your_facebook_api_secret_goes_here_if_using_twitter
+twitter_crypt_key: a_nice_complex_secure_key_for_encrypting_twitter_passwords
+twitter_crypt_iv: another_nice_complex_secure_key_for_encryption
 debug_mode: false
-admin_jid: a_jabber_id_that_should_be_allowed_to_send_admin_commands
\ No newline at end of file
+admin_jid: a_jabber_id_that_should_be_allowed_to_send_admin_commands</diff>
      <filename>config/config_example.yml</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>d31e82e359da8c8096c0116c885f8909efa6aca7</id>
    </parent>
  </parents>
  <author>
    <name>James Smith</name>
    <email>james@floppy.org.uk</email>
  </author>
  <url>http://github.com/Floppy/jabberstatus/commit/0d9318e589610f12463afa993415b51915d2d085</url>
  <id>0d9318e589610f12463afa993415b51915d2d085</id>
  <committed-date>2008-08-07T13:47:45-07:00</committed-date>
  <authored-date>2008-08-07T13:47:45-07:00</authored-date>
  <message>added Twitter support</message>
  <tree>fd138e351205ddd26d0b1fa915cf30bdaaf15cf2</tree>
  <committer>
    <name>James Smith</name>
    <email>james@floppy.org.uk</email>
  </committer>
</commit>
