I am using ejabberd18.09 for IM application. the application has few features that needed to add extensions to the ejabberd(xmpp) messages.
I created a custom module on the offline_message_hook to capture the offline messages and send them to my own url for further processing .
the messages that are being sent to ejabberd have different cases depending on the type of message as following
if I am sending a photo the message will be as following
<message xmlns="jabber:client" xml:lang="en" to="someuserjid2" from="{someuserjid}" type="chat" id="mP8tO-8">
<mtype xmlns="urn:xmpp:mtype" value="media" />
<url xmlns="urn:xmpp:url" id="myId" mediaType="photo" link="myphotourl.com" />
<body>thumbnail string</body>
</message>
when sending a text
<message xmlns="jabber:client" xml:lang="en" to="someuserjid2" from="{someuserjid}" type="chat" id="mP8tO-8">
<mtype xmlns="urn:xmpp:mtype" value="text" />
<body>Hi John</body>
</message>
when sending a location
<message xmlns="jabber:client" xml:lang="en" to="someuserjid2" from="{someuserjid}" type="chat" id="mP8tO-8">
<mtype xmlns="urn:xmpp:mtype" value="location" />
<location xmlns="urn:xmpp:geo" lat="1.2" lng="2.2 " />
<body>location thumbnailstring</body>
</message>
I used a .erl code to read the body and the message ID as following
create_message(_From, _To, Packet) when (Packet#message.type == chat) and (Packet#message.body /= []) ->
Body = fxml:get_path_s(Packet, [{elem, list_to_binary("body")}, cdata]),
MessageId = fxml:get_tag_attr_s(list_to_binary("id"), Packet),
post_offline_message(_From, _To, Body, MessageId),
ok.
what I want is how (in erlang) can I read the value attribute of the mtype tag the create a switch statement on ( media, location , test ) values so that I can process each message separately ?
You can pass
attr
in the list of arguments tofxml:get_path_s
to pick out the value of an attribute of a certain element:Another thought: do you actually need the
<mtype>
element? It looks like you could just check for the presence of a<location>
or<url>
element. You could do it like this:The code gets a bit messy, since we need to nest the
case
expressions, unlike the previous version where we just checked the value of a single expression. One thing you could do is writing a helper function that tries each element in turn:And then call it like: