-
-
Save coffeejunk/1250190 to your computer and use it in GitHub Desktop.
XMPP/Ruby Bot for HipChat with support for multiple rooms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'rubygems' | |
require 'xmpp4r' | |
require 'xmpp4r/muc/helper/simplemucclient' | |
# Most of this is borrowed from https://gist.github.com/941931 | |
# Added support for multiple rooms and external handling of messages. | |
# We want the MUC functionality to just handle shit for us. Unfortunately we | |
# have to override/repeat the join method in order to add the directive that | |
# will disable the history being sent to us. :-( | |
module Jabber | |
module MUC | |
class MUCClient | |
def join(jid, password=nil) | |
if active? | |
raise "MUCClient already active" | |
end | |
@jid = (jid.kind_of?(JID) ? jid : JID.new(jid)) | |
activate | |
# Joining | |
pres = Presence.new | |
pres.to = @jid | |
pres.from = @my_jid | |
xmuc = XMUC.new | |
xmuc.password = password | |
pres.add(xmuc) | |
# NOTE: Adding 'maxstanzas="0"' to 'history' subelement of xmuc nixes | |
# the history being sent to us when we join. | |
history = XMPPElement.new('history') | |
history.add_attributes({'maxstanzas' => '0'}) | |
xmuc.add(history) | |
# We don't use Stream#send_with_id here as it's unknown | |
# if the MUC component *always* uses our stanza id. | |
error = nil | |
@stream.send(pres) { |r| | |
if from_room?(r.from) and r.kind_of?(Presence) and r.type == :error | |
# Error from room | |
error = r.error | |
true | |
# type='unavailable' may occur when the MUC kills our previous instance, | |
# but all join-failures should be type='error' | |
elsif r.from == jid and r.kind_of?(Presence) and r.type != :unavailable | |
# Our own presence reflected back - success | |
if r.x(XMUCUser) and (i = r.x(XMUCUser).items.first) | |
@affiliation = i.affiliation # we're interested in if it's :owner | |
@role = i.role # :moderator ? | |
end | |
handle_presence(r, false) | |
true | |
else | |
# Everything else | |
false | |
end | |
} | |
if error | |
deactivate | |
raise ServerError.new(error) | |
end | |
self | |
end | |
end | |
end | |
end | |
class Bot | |
attr_accessor :config, :client, :mucs | |
def initialize(config) | |
self.config = config | |
self.client = Jabber::Client.new(config[:jid]) | |
self.mucs = {} | |
config[:rooms].each { |name, jid| | |
self.mucs[name] = Jabber::MUC::SimpleMUCClient.new(client) | |
} | |
if Jabber.logger = config[:debug] | |
Jabber.debug = true | |
end | |
self | |
end | |
def connect | |
client.connect | |
client.auth(config[:password]) | |
client.send(Jabber::Presence.new.set_type(:available)) | |
self.mucs.each do |room, muc| | |
muc.on_message do |time, nick, text| | |
next if nick == config[:nick] | |
yield room, nick, text | |
end | |
muc.join(self.config[:rooms][room] + '/' + config[:nick]) | |
end | |
self | |
end | |
def send_message(room, msg) | |
if msg[0, 6] == '/topic' | |
msg = msg.split('/topic').last.strip | |
message = Jabber::Message.new(muc.room) | |
message.subject = msg | |
muc.send message | |
else | |
muc.send Jabber::Message.new(muc.room, msg) | |
end | |
end | |
end | |
bot = Bot.new({ | |
:server => 'conf.hipchat.com', | |
:rooms => { :dev => '[email protected]', | |
:shared => '[email protected]' }, | |
:nick => '...', | |
:jid => '[email protected]', | |
:password => '...' | |
}) | |
bot.connect { |room, nick, message| | |
bot.send_message(room, "Got message from #{nick} in #{room}: #{message}") | |
} | |
loop do | |
sleep 1 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
in send_message
muc
is not defined... lacks something likemuc = self.mucs[room]