Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the processing of rooms #1

Merged
merged 8 commits into from
Jan 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions src/connector.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ module.exports = class Connector extends EventEmitter
# - `stanza`: Full response stanza, an `xmpp.Element`
getRooms: (callback) ->
iq = new xmpp.Element("iq", to: this.mucDomain, type: "get")
.c("query", xmlns: "http://jabber.org/protocol/disco#items");
.c "query", xmlns: "http://jabber.org/protocol/disco#items", include_archived: true
@sendIq iq, (err, stanza) ->
rooms = if err then [] else
# Parse response into objects
Expand All @@ -147,6 +147,24 @@ module.exports = class Connector extends EventEmitter
is_archived: !!getChild(x, "is_archived")
callback err, (rooms or []), stanza

getRoom: (jid, callback) ->
iq = new xmpp.Element("iq", to: jid, type: "get")
.c "query", xmlns: "http://jabber.org/protocol/disco#info", include_archived: true
@sendIq iq, (err, stanza) ->
q = stanza.getChild "query"
i = q.getChild "identity"
x = q.getChild "x"
room =
jid: jid.toString()
name: i.attrs.name
id: getInt x, "id"
topic: getText x, "topic"
privacy: getText x, "privacy"
owner: getText x, "owner"
guest_url: getText x, "guest_url"
is_archived: !!getChild x, "is_archived"
callback err, room

# Fetches the roster (buddy list)
#
# - `callback`: Function to be triggered: `function (err, items, stanza)`
Expand Down Expand Up @@ -346,6 +364,10 @@ module.exports = class Connector extends EventEmitter

onRosterChange: (callback) -> @on "rosterChange", callback

onRoomPushes: (callback) -> @on "roomPushes", callback

onRoomDeleted: (callback) -> @on "roomDeleted", callback

# Emitted whenever the connector pings the server (roughly every 30 seconds).
#
# - `callback`: Function to be triggered: `function ()`
Expand Down Expand Up @@ -470,9 +492,27 @@ onStanza = (stanza) ->
@emit event_id, null, stanza
else if stanza.attrs.type is "set"
# Check for roster push
if stanza.getChild("query").attrs.xmlns is "jabber:iq:roster"
users = usersFromStanza(stanza)
@emit "rosterChange", users, stanza
q = stanza.getChild "query"
switch q.attrs.xmlns
when "jabber:iq:roster"
users = usersFromStanza stanza
@emit "rosterChange", users, stanza
when "http://hipchat.com/protocol/muc#room"
i = q.getChild "item"
jid = i.attrs.jid
if i.attrs.status == "deleted"
@emit "roomDeleted", jid
return
room =
jid: jid
name: i.attrs.name
id: getInt i, "id"
topic: getText i, "topic"
privacy: getText i, "privacy"
owner: getText i, "owner"
guest_url: getText i, "guest_url"
is_archived: !!getChild i, "is_archived"
@emit "roomPushes", room
else
# IQ error response
# ex: http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-result
Expand Down
99 changes: 57 additions & 42 deletions src/hipchat.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class HipChat extends Adapter
constructor: (robot) ->
super robot
@logger = robot.logger
@rooms = {}
reconnectTimer = null

emote: (envelope, strings...) ->
Expand All @@ -18,16 +19,7 @@ class HipChat extends Adapter
{user, room} = envelope
user = envelope if not user # pre-2.4.2 style

target_jid =
# most common case - we're replying to a user in a room or 1-1
user?.reply_to or
# allows user objects to be passed in
user?.jid or
if user?.search?(/@/) >= 0
user # allows user to be a jid string
else
room # this will happen if someone uses robot.messageRoom(jid, ...)

target_jid = @targetJid user, room
if not target_jid
return @logger.error "ERROR: Not sure who to send to: envelope=#{inspect envelope}"

Expand All @@ -38,16 +30,7 @@ class HipChat extends Adapter
{user, room} = envelope
user = envelope if not user # pre-2.4.2 style

target_jid =
# most common case - we're replying to a user in a room or 1-1
user?.reply_to or
# allows user objects to be passed in
user?.jid or
if user?.search?(/@/) >= 0
user # allows user to be a jid string
else
room # this will happen if someone uses robot.messageRoom(jid, ...)

target_jid = @targetJid user, room
if not target_jid
return @logger.error "ERROR: Not sure who to send to: envelope=#{inspect envelope}"

Expand Down Expand Up @@ -105,7 +88,7 @@ class HipChat extends Adapter
connector.onTopic (channel, from, message) =>
@logger.info "Topic change: " + message
author = getAuthor: => @robot.brain.userForName(from) or new User(from)
author.room = @roomNameFromJid(channel)
author.room = @rooms[channel].name
@receive new TopicMessage(author, message, 'id')


Expand Down Expand Up @@ -146,6 +129,17 @@ class HipChat extends Adapter
delete @robot.brain.data.users[user.id]
@robot.brain.userForId user.id, user

setRooms = (callback) =>
connector.getRooms (err, rooms, stanza) =>
if rooms
for room in rooms
@rooms[room.jid] = room
else
return @logger.error "Can't list rooms: #{errmsg err}"

if callback?
callback()

joinRoom = (jid) =>
if jid and typeof jid is "object"
jid = "#{jid.local}@#{jid.domain}"
Expand All @@ -165,27 +159,35 @@ class HipChat extends Adapter
init
.done (users) =>
saveUsers(users)
# Join requested rooms
if @options.rooms is "All" or @options.rooms is "@All"
connector.getRooms (err, rooms, stanza) =>
if rooms
for room in rooms
if [email protected]_join_public && room.guest_url != ''
@logger.info "Not joining #{room.jid} because it is a public room"
else
joinRoom(room.jid)
else
@logger.error "Can't list rooms: #{errmsg err}"
# Join all rooms
else
for room_jid in @options.rooms.split ","
joinRoom(room_jid)

setRooms =>
# Join requested rooms
if @options.rooms is "All" or @options.rooms is "@All"
for _, room of @rooms
if [email protected]_join_public && room.guest_url != ''
@logger.info "Not joining #{room.jid} because it is a public room"
else
joinRoom room.jid
# Join all rooms
else
for room_jid in @options.rooms.split ","
joinRoom room_jid

.fail (err) =>
@logger.error "Can't list users: #{errmsg err}" if err

connector.onRosterChange (users) =>
saveUsers(users)

connector.onRoomPushes (room) =>
if @options.rooms is "All" or @options.rooms is "@All"
if !@rooms[room.jid]
joinRoom room.jid
@rooms[room.jid] = room

connector.onRoomDeleted (jid) =>
delete @rooms[jid]

handleMessage = (opts) =>
# buffer message events until the roster fetch completes
# to ensure user data is properly loaded
Expand All @@ -207,7 +209,7 @@ class HipChat extends Adapter
getAuthor: => @robot.brain.userForName(from) or new User(from)
message: message
reply_to: channel
room: @roomNameFromJid(channel)
room: @rooms[channel].name

connector.onPrivateMessage (from, message) =>
# remove leading @mention name if present and format the message like
Expand Down Expand Up @@ -241,6 +243,8 @@ class HipChat extends Adapter
action = if @options.autojoin then "joining" else "ignoring"
@logger.info "Got invite to #{room_jid} from #{from_jid} - #{action}"
joinRoom(room_jid) if @options.autojoin
connector.getRoom room_jid, (err, room) =>
@rooms[room.jid] = room

firstTime = false
connector.connect()
Expand All @@ -253,11 +257,22 @@ class HipChat extends Adapter
catch e
@logger.error "Bad user JID: #{jid}"

roomNameFromJid: (jid) ->
try
jid.match(/^\d+_(.+)@conf\./)[1]
catch e
@logger.error "Bad room JID: #{jid}"
roomJidFromName: (name) ->
for _, room of @rooms
if room.name == name
return room.jid

targetJid: (user, room) ->
# most common case - we're replying to a user in a room or 1-1
user?.reply_to or
# allows user objects to be passed in
user?.jid or
if user?.search?(/@/) >= 0
user # allows user to be a jid string
else
@robot.brain.userForName(room)?.jid or
@roomJidFromName room or
room # this will happen if someone uses robot.messageRoom(jid, ...)

# Convenience HTTP Methods for posting on behalf of the token'd user
get: (path, callback) ->
Expand Down