From 6d31cf7759f8898c39eefba8de60b0f30a472b2e Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sat, 27 Aug 2016 09:22:55 +0900 Subject: [PATCH 1/8] Add rooms object. --- src/hipchat.coffee | 49 ++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/hipchat.coffee b/src/hipchat.coffee index d2868c2..969c43b 100644 --- a/src/hipchat.coffee +++ b/src/hipchat.coffee @@ -9,6 +9,7 @@ class HipChat extends Adapter constructor: (robot) -> super robot @logger = robot.logger + @rooms = {} reconnectTimer = null emote: (envelope, strings...) -> @@ -146,6 +147,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.name] = 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}" @@ -165,21 +177,20 @@ 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 !@options.rooms_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 !@options.rooms_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 @@ -238,6 +249,7 @@ class HipChat extends Adapter changePresence LeaveMessage, user_jid, room_jid connector.onInvite (room_jid, from_jid, message) => + setRooms() 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 @@ -254,10 +266,9 @@ class HipChat extends Adapter @logger.error "Bad user JID: #{jid}" roomNameFromJid: (jid) -> - try - jid.match(/^\d+_(.+)@conf\./)[1] - catch e - @logger.error "Bad room JID: #{jid}" + for _, room of (@rooms or {}) + if room.jid == jid + return room.name # Convenience HTTP Methods for posting on behalf of the token'd user get: (path, callback) -> From 6131738b4ffb5ea170fd94ea4bad06e08f06ef0f Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sat, 27 Aug 2016 09:23:51 +0900 Subject: [PATCH 2/8] Add room specified message. --- src/hipchat.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hipchat.coffee b/src/hipchat.coffee index 969c43b..eb4c8da 100644 --- a/src/hipchat.coffee +++ b/src/hipchat.coffee @@ -27,6 +27,9 @@ class HipChat extends Adapter if user?.search?(/@/) >= 0 user # allows user to be a jid string else + user = @robot.brain.userForName room + @rooms[room]?.jid or + user?.jid or room # this will happen if someone uses robot.messageRoom(jid, ...) if not target_jid @@ -47,6 +50,9 @@ class HipChat extends Adapter if user?.search?(/@/) >= 0 user # allows user to be a jid string else + user = @robot.brain.userForName room + @rooms[room]?.jid or + user?.jid or room # this will happen if someone uses robot.messageRoom(jid, ...) if not target_jid From 86e1508cf1f05384b315ed148b24d9ccc8b50764 Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sat, 27 Aug 2016 20:03:01 +0900 Subject: [PATCH 3/8] Fix hash key of "rooms" object from name to jid. --- src/hipchat.coffee | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hipchat.coffee b/src/hipchat.coffee index eb4c8da..fa53375 100644 --- a/src/hipchat.coffee +++ b/src/hipchat.coffee @@ -28,7 +28,7 @@ class HipChat extends Adapter user # allows user to be a jid string else user = @robot.brain.userForName room - @rooms[room]?.jid or + @roomJidFromName room or user?.jid or room # this will happen if someone uses robot.messageRoom(jid, ...) @@ -51,7 +51,7 @@ class HipChat extends Adapter user # allows user to be a jid string else user = @robot.brain.userForName room - @rooms[room]?.jid or + @roomJidFromName room or user?.jid or room # this will happen if someone uses robot.messageRoom(jid, ...) @@ -112,7 +112,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') @@ -157,7 +157,7 @@ class HipChat extends Adapter connector.getRooms (err, rooms, stanza) => if rooms for room in rooms - @rooms[room.name] = room + @rooms[room.jid] = room else return @logger.error "Can't list rooms: #{errmsg err}" @@ -224,7 +224,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 @@ -271,10 +271,10 @@ class HipChat extends Adapter catch e @logger.error "Bad user JID: #{jid}" - roomNameFromJid: (jid) -> - for _, room of (@rooms or {}) - if room.jid == jid - return room.name + roomJidFromName: (name) -> + for _, room of @rooms + if room.name == name + return room.jid # Convenience HTTP Methods for posting on behalf of the token'd user get: (path, callback) -> From 0b17d7033f904ba41dfaa5b5eb9b3411c66e0f00 Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sun, 28 Aug 2016 01:39:42 +0900 Subject: [PATCH 4/8] Add room pushes. --- src/connector.coffee | 23 ++++++++++++++++++++--- src/hipchat.coffee | 6 ++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/connector.coffee b/src/connector.coffee index 23f774c..8f20255 100644 --- a/src/connector.coffee +++ b/src/connector.coffee @@ -346,6 +346,8 @@ module.exports = class Connector extends EventEmitter onRosterChange: (callback) -> @on "rosterChange", callback + onRoomPushes: (callback) -> @on "roomPushes", callback + # Emitted whenever the connector pings the server (roughly every 30 seconds). # # - `callback`: Function to be triggered: `function ()` @@ -470,9 +472,24 @@ 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") + return if i.attrs.status == "deleted" + room = + jid: i.attrs.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 diff --git a/src/hipchat.coffee b/src/hipchat.coffee index fa53375..196aba4 100644 --- a/src/hipchat.coffee +++ b/src/hipchat.coffee @@ -203,6 +203,12 @@ class HipChat extends Adapter 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 + handleMessage = (opts) => # buffer message events until the roster fetch completes # to ensure user data is properly loaded From b7f6993e19b7edf6c2b4dd03f52cb10d0f574415 Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sun, 28 Aug 2016 02:08:43 +0900 Subject: [PATCH 5/8] Add targetJid. --- src/hipchat.coffee | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/hipchat.coffee b/src/hipchat.coffee index 196aba4..99e6e65 100644 --- a/src/hipchat.coffee +++ b/src/hipchat.coffee @@ -19,19 +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 - user = @robot.brain.userForName room - @roomJidFromName room or - user?.jid or - 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}" @@ -42,19 +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 - user = @robot.brain.userForName room - @roomJidFromName room or - user?.jid or - 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}" @@ -282,6 +258,18 @@ class HipChat extends Adapter 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) -> @request "GET", path, null, callback From 7bf8149050912ab32b5356800931eb8a889b4e9e Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sun, 28 Aug 2016 02:28:26 +0900 Subject: [PATCH 6/8] Add onRoomDeleted. --- src/connector.coffee | 9 +++++++-- src/hipchat.coffee | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/connector.coffee b/src/connector.coffee index 8f20255..5d15380 100644 --- a/src/connector.coffee +++ b/src/connector.coffee @@ -348,6 +348,8 @@ module.exports = class Connector extends EventEmitter 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 ()` @@ -479,9 +481,12 @@ onStanza = (stanza) -> @emit "rosterChange", users, stanza when "http://hipchat.com/protocol/muc#room" i = q.getChild("item") - return if i.attrs.status == "deleted" + jid = i.attrs.jid + if i.attrs.status == "deleted" + @emit "roomDeleted", jid + return room = - jid: i.attrs.jid + jid: jid name: i.attrs.name id: getInt(i, "id") topic: getText(i, "topic") diff --git a/src/hipchat.coffee b/src/hipchat.coffee index 99e6e65..be7635d 100644 --- a/src/hipchat.coffee +++ b/src/hipchat.coffee @@ -185,6 +185,9 @@ class HipChat extends Adapter 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 From 9b028998f86be9109abcb4a7ab081e46ec5420c5 Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sun, 28 Aug 2016 03:23:51 +0900 Subject: [PATCH 7/8] Add getRoom. --- src/connector.coffee | 20 +++++++++++++++++++- src/hipchat.coffee | 3 ++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/connector.coffee b/src/connector.coffee index 5d15380..ef24ce1 100644 --- a/src/connector.coffee +++ b/src/connector.coffee @@ -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 @@ -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)` diff --git a/src/hipchat.coffee b/src/hipchat.coffee index be7635d..c3cda67 100644 --- a/src/hipchat.coffee +++ b/src/hipchat.coffee @@ -240,10 +240,11 @@ class HipChat extends Adapter changePresence LeaveMessage, user_jid, room_jid connector.onInvite (room_jid, from_jid, message) => - setRooms() 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() From e6caf652b7d76607700b5a465fa229f02205ee61 Mon Sep 17 00:00:00 2001 From: 178inaba <178inaba@users.noreply.github.com> Date: Sun, 28 Aug 2016 03:30:39 +0900 Subject: [PATCH 8/8] Remove brackets (coffee style). --- src/connector.coffee | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/connector.coffee b/src/connector.coffee index ef24ce1..c99e070 100644 --- a/src/connector.coffee +++ b/src/connector.coffee @@ -492,13 +492,13 @@ onStanza = (stanza) -> @emit event_id, null, stanza else if stanza.attrs.type is "set" # Check for roster push - q = stanza.getChild("query") + q = stanza.getChild "query" switch q.attrs.xmlns when "jabber:iq:roster" - users = usersFromStanza(stanza) + users = usersFromStanza stanza @emit "rosterChange", users, stanza when "http://hipchat.com/protocol/muc#room" - i = q.getChild("item") + i = q.getChild "item" jid = i.attrs.jid if i.attrs.status == "deleted" @emit "roomDeleted", jid @@ -506,12 +506,12 @@ onStanza = (stanza) -> 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") + 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