xmppejabberdsmackmultiuserchat

Ejabberd - get user from multi user chat message using Smack XMPP client or enforce nickname


I am running an ejabberd server with a series of locked down multi user chats (members only, registration required, no subject change or PMs permitted etc) One requirement is to strictly identify which users (from their user Id/account Jid when registering with the server) are present in each room, and which user has sent a message.

How this is achieved is not important, it can either be: a) By getting the userId from message.getFrom() b) By getting the nick/resource part from the message sender, and enforcing what nick a user can choose

In direct messages, the Jid of a sender will look like:

<userId>@<domain>/<resourcepart>

so I can take the userId (LocalPart) and not worry too much what nickname was chosen.

This is not possible in multi user chats however, since the Jid will appear as:

<roomName>@conference.<domain>/<resourcepart>

The userId of the sender is not present, so I have to rely on the nickname, but this can be set to anything by the users (and changed at any point in the chat)

Is there a way to enforce how a nick is set? (i.e. set to the same value as userId) or otherwise extract the userId from a multi user chat message?


Solution

  • As I wrote, you need a non-anonymous room. The real XMPP address (JID) of a room occupant will then be part of the participant's presence (XEP-0045 § 7.2.3). You can obtain the presence of a occupant via MultiUserChat.getOccupantPresence​(EntityFullJid user). From this Presence you want to extra the MUCUser information via MUCUser.from(presence). From which you extra the MUCIitem which should allow to retrieve the real JID via MUCItem.getJid()1.

    1: Note that the javadoc if this method seems to be misleading, it should contain the real JID of the user and not the MUC JID.