2

I am trying to implement a chat messaging application using Smack and ejabberd. I am getting the input below as Packet parameter in my filter_packet hook on my server:

   {{jid,<<"senderUserName">>,<<"domain.com">>,<<"Smack">>,<<"senderUserName">>,<<"domain.com">>,<<"Smack">>},{jid,<<"receiverUserName">>,<<"domain.com">>,<<>>,<<"receiverUserName">>,<<"domain.com">>,<<>>},{xmlel,<<"message">>,[{<<"xml:lang">>,<<"en">>},{<<"to">>,<<"receiverUserName@domain.com">>},{<<"id">>,<<"4Xd7d-13">>},{<<"type">>,<<"chat">>}],[{xmlel,<<"body">>,[],[{xmlcdata,<<"my message">>}]},{xmlel,<<"thread">>,[],[{xmlcdata,<<"25e5fc87-e57f-4046-9aef-30c569ab9160">>}]},{xmlel,<<"customTag">>,[],[{xmlcdata,<<"Custom extras">>}]}]}}

Here are my questions:

  1. Why I am getting sender and receiver Usernames twice ?
  2. How can I get the values of different tuple elements in Erlang ?
Mickaël Rémond
  • 9,035
  • 1
  • 24
  • 44
no one
  • 477
  • 6
  • 19

1 Answers1

2

ejabberd filter_packet hook parameter is a tuple containing the following value: {FromJID, ToJID, XMLPacket}.

  • FromJID is a #jid{} record.
  • ToJID is a #jid{}.
  • XMLPacket is an #xmlel{} record, that is a parsed representation of the original XMPP packet.

Your first question is about the #jid{} record structure (From and To). The internal record is not intended to be used directly but through the jlib.erl function. However, at the moment, the record is indeed optimized for avoiding extra processing and matching on namepreped, nodepreped username and domain. The namepreped / nodepreped value are stored as an addition to the original untouched value. If the processed values are equals to the original value, yes, you may feel this is a duplicate. However, it will be different if you are using various case and some special unicode characters.

I guess your second question is about the parsed XML element datastructure. To extract and manipulate the data from the #xmlel record, you can extract the needed field of the record: name, attrs, and children.

The record is defined as:

-record(xmlel, {
    name = <<"">> :: binary(),
    attrs    = [] :: [attr()],
    children = [] :: [xmlel() | cdata()] }).

You can use that info to get down in the XML tree, using the children list. You will also find ready-made helper functions in the xml.erl module.

Mickaël Rémond
  • 9,035
  • 1
  • 24
  • 44