xmppjs / hubot-xmpp

XMPP adapter for Hubot
181 stars 101 forks source link

Best way to do direct messages over XMPP? #47

Closed bnied closed 10 years ago

bnied commented 10 years ago

I'm trying to determine what the best method for sending direct messages from Hubot to other XMPP users would be. Currently, I have this:

    robot.router.post '/notifications/direct-im', (req, res) ->
            body = req.body

        message = body.message
        username = body.username

        user = robot.brain.userForName username
        user.id = username
        user.type = 'direct'

        robot.send user, "#{message}"

        res.writeHead 200, {'Content-Type': 'text/plain'}
        res.end "OK"

However, that code doesn't seem to send the message to the user. What am I doing wrong?

markstory commented 10 years ago

If you set the loglevel to debug does the message get logged? What you have seems like it should work in theory. The delivery issues could be caused by mismatching jid values.

bnied commented 10 years ago

It does log the message. However, it posts the message to the room instead of opening a direct message to the user I specify.

markstory commented 10 years ago

You probably also need to set the room on the user. The send method needs a room. You might want to check the contents of the message around like 251 and make sure the XML looks correct.

mdarveau commented 10 years ago

Hi,

I'm not sure if this is the issue here but I found that robot.brain.userForName does not work very well for me.

The problem is that the jid for a user when a message is sent to a chat room is something like: room@conference.jabber.xxx/Some User Friendly Name or Generated ID While the private message jid for a user is: username@jabber.xxx

There is no way to get the user's username from the group char JID. This is actually a privacy feature of jabber. However, you can configure the jabber server to also send the private chat jid of a user in the group chat presence message. In openfire, this is done in "Group Chat", "Room Settings", "Show Real JIDs of Occupants to": Anyone

There seems to be code for this in hubot-xmpp but could not manage to make it work. I created a little helper script to track groupchat vs private chat jid. See https://github.com/MacKeeper/jobot/blob/master/scripts/xmpp-id-resolver.coffee

I planned to tests it and then contribute it to xmpp/hubot once tested and when I find a way to work around the initialisation timming issue.

At the very beginning of your script: @xmppIdResolver = require( './xmpp-id-resolver' )( @robot )

You can then do somethink like:

Example on how to resolve a groupchat message to a specific user message

robot.respond /.*test ping me/i, ( msg ) => to_jid = @xmppIdResolver.getPrivateJID( msg.envelope.user.jid ) message = "Ping from #{@robot.name}" envelope = room: to_jid user: type: 'chat' robot.send( envelope, message )

Hope it helps!

Manuel

On 2013-12-10, at 10:01 AM, bnied notifications@github.com wrote:

It does log the message. However, it posts the message to the room instead of opening a direct message to the user I specify.

— Reply to this email directly or view it on GitHub.

markstory commented 10 years ago

@MacKeeper Having the JID resolver 'just work' when it can would be a nice feature for hubot-xmpp.

bnied commented 10 years ago

Got it! Thanks @MacKeeper! The envelope part was what I was missing.

For completeness' sake, this is what the final script looked like:

# Description:
#   Interface to directly message a user (test script)
#
# Commands:
#   None
#
# Dependencies:
#   None
#
# Configuration:
#   None
#
# Notes:
#   None
#
# Author:
#   Ben Nied <bnied@shutterstock.com>
#
# URLS:
#   /notifications/direct-im

module.exports = (robot) ->
    robot.router.post "/notifications/direct-im", (req, res) ->
        body = req.body

        message = body.message
        username = body.username + "@domain.net"

        envelope = 
            room: username
            user:
                type: 'chat'

        robot.send(envelope, message)

        res.writeHead 200, {'Content-Type': 'text/plain'}
        res.end "OK"

I cheated a bit in generating the JID for each user, since they're predictable in our circumstance.

mdarveau commented 10 years ago

Will send a pull request in the comming days :-)

I see that there is some code in readPresence which looks to be trying to handle that (lines 164-166) but I think it's broken. Would you like me to fix that code or integrate the privave vs groupchat jid resolver?

Manuel

On 2013-12-10, at 10:54 AM, Mark Story notifications@github.com wrote:

@MacKeeper Having the JID resolver 'just work' when it can would be a nice feature for hubot-xmpp.

— Reply to this email directly or view it on GitHub.

markstory commented 10 years ago

It might be simpler to update readPresence.