Search code examples
javascriptxmppejabberdstrophestrophe.js

Unable to retrieving chat history using Strophe.js and Ejabberd with XEP-0313: Message Archive Management (MAM)


I'm currently working on a web-based chat application using Strophe.js as the XMPP client library and Ejabberd as the XMPP server. I'm attempting to implement support for retrieving chat history using XEP-0313: Message Archive Management (MAM), but I'm encountering difficulties.

My goal is to fetch the chat history for a particular user and display it in the chat interface. However, my current implementation seems to only return the count of messages, rather than the actual message content.

Here's a snippet of my code for retrieving the chat history:

const iq = $iq({
  type: 'set',
  id: 'juliet1',
}).c('query', {
  xmlns: 'urn:xmpp:mam:2'
}).c('x', {
  xmlns: 'jabber:x:data',
  type: 'submit'
}).c('field', {
  var: 'FORM_TYPE',
  type: 'hidden'
}).c('value').t('urn:xmpp:mam:2').up().up().c('field', {
  var: 'with'
}).c('value').t(jid).up().tree();

connection.sendIQ(iq, function(response) {
   const message = response.getElementsByTagName('result');
   console.log(response);
   messages.forEach(message => {
      const body = Strophe.getText(message.querySelector("body"));
      const from = message.getAttribute('from');
      displayMessage(from, body);
   });
   return true;
});

The issue I'm facing is that response.getElementsByTagName('result') doesn't return any messages, when console logging response i am getting only -

<iq xmlns="jabber:client" xml:lang="en" to="dev@localhost/1178459894898988032171235" from="dev@localhost" type="result" id="juliet1">
  <fin xmlns="urn:xmpp:mam:2" complete="true">
    <set xmlns="http://jabber.org/protocol/rsm">
      <count>1</count>
      <first>1707854878326932</first>
      <last>1707854878326932</last>
    </set>
  </fin>
</iq>

I've double-checked my XMPP server configuration, and it seems to support MAM properly.

I'm wondering if there's something wrong with my code or if there's a better approach to retrieving chat history using Strophe.js and Ejabberd. Any insights or suggestions would be greatly appreciated.

Strophe.js version: 1.6.0

Ejabberd version: 23.10.0

ejabberd.yml

mod_mam:
  ## Mnesia is limited to 2GB, better to use an SQL backend
  ## For small servers SQLite is a good fit and is very easy
  ## to configure. Uncomment this when you have SQL configured:
  ## db_type: sql
  assume_mam_usage: true
  default: always

Thank you in advance for your help!

note: - I have tested the query in Gajim XML console and it returns the messages.


Solution

  • I initially lacked knowledge on retrieving chat history. However, I later discovered some plugins that allowed me to retrieve chat messages from MAM.

    I've created a function that retrieve messages from particular user by passing its JID

    get_chat_history: function (jid) {
        const q = {
          onMessage: function (message) {
              let msg = $(message).find("forwarded > message");
              let body = msg.find("body").text();        
              return true;
          },
          onComplete: function (response) {
              scroll_chat();
          },
          with: jid,
          max: "100",
          before: "",
        };
        
        connection.mam.query(Strophe.getBareJidFromJid(connection.jid), q);
    }
    

    in the above function

    • onMessage retrieves the history of the message.
    • onComplete is called when all messages have been fetched. allowing for any necessary actions (in my case scrolling to bottom)

    The plugins used to achieve this are:

    • strophejs-plugin-mam Link
    • strophejs-plugin-rsm Link

    Although achieving the same without using the plugins is possible:

    get_chat_history: function (jid) {
        const id = connection.getUniqueId();
        let mamQuery = $iq({ type: "set", id: id })
          .c("query", {
            xmlns: "urn:xmpp:mam:2",
          })
          .c("x", { xmlns: "jabber:x:data", type: "submit" });
        mamQuery
          .c("field", { var: "FORM_TYPE", type: "hidden" })
          .c("value")
          .t("urn:xmpp:mam:2")
          .up()
          .up();
        mamQuery.c("field", { var: "with" }).c("value").t(jid).up().up();
    
        mamQuery
          .up()
          .c("set", { xmlns: "http://jabber.org/protocol/rsm" })
          .c("max", {}, "100")
          .c("before");
    
        connection.sendIQ(mamQuery);
    }, 
    

    add handler to handler the retrieval of history messages

    connection.addHandler(
        function (iq) {
            // iq will have the messages  
        },
        "urn:xmpp:mam:2",
        "message",
        null
    );