Skip to content

Commit

Permalink
Merge pull request #80 from andyfowler/xmpp-persist
Browse files Browse the repository at this point in the history
Persist users in XMPP adapter
  • Loading branch information
atmos committed Oct 27, 2011
2 parents b4ba059 + 9a0dbb6 commit 56bc14a
Showing 1 changed file with 82 additions and 20 deletions.
102 changes: 82 additions & 20 deletions src/hubot/xmpp.coffee
Expand Up @@ -15,11 +15,15 @@ class XmppBot extends Robot
jid: options.username
password: options.password

@client.on 'error', @.error
@client.on 'online', @.online
@client.on 'stanza', @.read

@options = options

error: (error) =>
console.error error

online: =>
console.log 'Hubot XMPP client online'

Expand All @@ -45,31 +49,89 @@ class XmppBot extends Robot
console.error '[xmpp error]' + stanza
return

# ignore non-messages
return if !stanza.is 'message' or stanza.attrs.type not in ['groupchat', 'direct', 'chat']

# ignore our own messages
return if @options.username in stanza.attrs.from

# ignore empty bodies (i.e., topic changes -- maybe watch these someday)
body = stanza.getChild 'body'
return unless body

message = body.getText()

[room, from] = stanza.attrs.from.split '/'
user = new Robot.User from, {
room: room
type: stanza.attrs.type
}

@receive new Robot.TextMessage user, message
switch stanza.name
when 'message'
@readMessage stanza
when 'presence'
@readPresence stanza

readMessage: (stanza) =>
# ignore non-messages
return if stanza.attrs.type not in ['groupchat', 'direct', 'chat']

# ignore our own messages
return if @options.username in stanza.attrs.from

# ignore messages from the server. on Openfire, this includes "This room is not anonymous"
return if stanza.attrs.from in @options.rooms

# ignore empty bodies (i.e., topic changes -- maybe watch these someday)
body = stanza.getChild 'body'
return unless body

message = body.getText()

[room, from] = stanza.attrs.from.split '/'

# note that 'from' isn't a full JID, just the local user part
user = @userForId from
user.room = room
user.type = stanza.attrs.type

@receive new Robot.TextMessage user, message

readPresence: (stanza) =>
jid = new Xmpp.JID(stanza.attrs.from)
bareJid = jid.bare().toString()

# xmpp doesn't add types for standard available mesages
# note that upon joining a room, server will send available
# presences for all members
# http://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.1
stanza.attrs.type ?= 'available'

switch stanza.attrs.type
when 'subscribe'
console.log "#{stanza.attrs.from} subscribed to us"

@client.send new Xmpp.Element('presence',
from: stanza.attrs.to
to: stanza.attrs.from
id: stanza.attrs.id
type: 'subscribed'
)
when 'probe'
@client.send new Xmpp.Element('presence',
from: stanza.attrs.to
to: stanza.attrs.from
id: stanza.attrs.id
)
when 'available'
if bareJid not in @options.rooms
from = stanza.attrs.from
else
# room presence is stupid, and optional for some anonymous rooms
# http://xmpp.org/extensions/xep-0045.html#enter-nonanon
from = stanza.getChild('x', 'http://jabber.org/protocol/muc#user')?.getChild('item')?.attrs?.jid

return if not from?

# for now, user IDs and user names are the same. we don't
# use full JIDs as user ID, since we don't get them in
# standard groupchat messages
jid = new Xmpp.JID(from)
userId = userName = jid.user

console.log "Availability received for #{userId}"

user = @userForId userId, name: userName
user.jid = jid.toString()

send: (user, strings...) ->
for str in strings
console.log "Sending to #{user.room}: #{str}"

to = if user.type in ['direct', 'chat'] then user.room + '/' + user.id else user.room
to = if user.type in ['direct', 'chat'] then "#{user.room}/#{user.id}" else user.room

message = new Xmpp.Element('message',
from: @options.username
Expand Down

0 comments on commit 56bc14a

Please sign in to comment.