Jabber4R is copyrighted free software by Rich Kilmer <rich@infoether.com>
Please see LICENSE.txt for licensing information.
Version: 0.8.0
Date: August 15, 2005

==== Overview

The purpose of this library is to allow Ruby applications to talk to a Jabber IM system.
Jabber is an open-source instant messaging service, which can be learned about here.

                      http://www.jabber.org

An interesting facet of Jabber is its ability to represent multiple resources connecting 
to a single account at the same time. One could connect to the account 
account@jabber.org from home and from work and from a pda all at the same time. 
Each connection is viewed as a resource. Messages can be sent to an account (and the 
server will decide which resource gets it based on the resources priority) or to an 
account+resource. The fully qualified account and resource name is:

                      account@host/resource

This library was created to allow a Ruby application to connect to an existing Jabber 
account as an additional resource. This is not meant to be a library to create a complete 
Ruby-based Jabber IM client. It currently does not support creation of accounts and 
managing presence subscriptions (do that with one of the other 30 Jabber clients out 
there). It was written for ease of use, not completeness. It does support:

* Account registration 
* Connection to an account (digest/plain text)
* Access to Roster (buddy list) 
* Tracking of presence of resources in the Roster (including local account resources) 
* Sending and receiving messages 
* Requesting VCards
* Managing subscriptions 

What can you do with this? You could write a Ruby application that allows you to query 
it by IM for status, control, etc. You could use this as a communications channel 
backbone for a Ruby application (which is my intent).

==== Release Notes

* Now have rake-based building and install.

==== Usage

require 'jabber4r/jabber4r'
session = Jabber::Session.bind_digest("rich@jabber.com", "secret")
session.new_message("bob@jabber.com").set_body("ruby speak!").send
session.release

You can send and receive messages.  I make use of chaining on messages so you can do this

  session.add_message_listener do |message|
    message.reply.set_body(Echo: #{message.body}).send
  end

If you want to send and wait for a reply message do:

  answer=session.new_chat_message("rich@jabber.com").set_body("Hello there").send(true)

Then execute:
  puts answer.body
  answer.reply.set_body("Thanks for the reply").send

The examples below demonstrate many features.

Please look at the doc directory (RDoc format) for detailed info on Jabber4R.  The 
Jabber::Session class is kind of the main thing to focus on.

I have a test directory with a single unit test file (for testing the JID class).  
I will work on many more. There is also a fun echo.rb file there that you can run
to echo and messages back to the sender...and when they send 'shutdown' the session
releases.

  ruby echo.rb <jabberid> <password>

You can observe roster changes, but cannot manage subscriptions (the framework is there
to do this, but it needs some work).  You also cannot add an account (you must already
have one).  That's in the works as well.

Have fun!


== Installation

To install, execute the following command:

> gem install jabber4r

That's it!

==== Examples

NOTE:  Remember to change your account@host/resource and password to YOURs.

Connecting to an account, sending a message, and disconnecting:

require 'jabber4r/jabber4r'
begin
  session = Jabber::Session.bind('account@host/resource', 'password')
  session.new_message('rich_kilmer@jabber.org').set_subject('hello').set_body('This is really cool').send
rescue Exception=>error
  puts error
ensure
  session.release if session
end

-----------------

Connecting to an account, sending a message, waiting for a reply, and disconnecting:

require 'jabber4r/jabber4r'
begin
  session = Jabber::Session.bind('account@host/resource', 'password')
  #NOTE: send the first message and wait for a reply (i.e. send(true) )
  message = session.new_chat_message('rich_kilmer@jabber.org').set_body('hey').send(true)
  #NOTE: reply to the reply with an echo of the message, but don't wait
  message.reply.set_body("You said #{message.body}").send
rescue Exception=>error
  puts error
ensure
  session.release if session
end
 
-----------------

Connecting to an account, echoing back each received message, and disconnecting 
when a shutdown message is received:

 
require "jabber4r/jabber4r"
begin
  session = Jabber::Session.bind("account@host/resource", "password")
  myThread = Thread.current
  mlid = session.add_message_listener do |message|
    message.reply.set_body("Echo: #{message.body}").send
    myThread.wakeup if message.body=="shutdown"
  end
  Thread.stop
  session.delete_message_listener(mlid)
rescue Exception=>error
  puts error
ensure
  session.release if session
end

-----------------

Connecting to an account, outputting roster changes, and disconnecting when a 
shutdown message is received:

require "jabber4r/jabber4r"
begin
  session = Jabber::Session.bind("account@host/resource", "password")
  myThread = Thread.current
  #NOTE: Just like before, a 'shutdown' message stops the session
  mlid = session.add_message_listener do |message|
    myThread.wakeup if message.body=="shutdown"
  end
  listenerid = session.add_roster_listener do |event, object|
    case event
      when Jabber::Roster::ITEM_ADDED
        puts "Added item: #{object.to_s}"
      when Jabber::Roster::ITEM_DELETED
        puts "Deleted item: #{object.to_s}"
      when Jabber::Roster::RESOURCE_ADDED
        puts "Added resource: #{object.to_s}"
      when Jabber::Roster::RESOURCE_DELETED
        puts "Deleted resource: #{object.to_s}"
      when Jabber::Roster::RESOURCE_UPDATED
        puts "Updated resource: #{object.to_s}"
    end
  end
  Thread.stop
rescue Exception=>error
  puts error
ensure
  session.release if session
end

