Not logged in. · Lost password · Register
Forum: MatriX and XmppDotNet RSS
Avatar
sudorm #1
Member since Aug 2018 · 5 posts
Group memberships: Members
Show profile · Link to this post
Subject: Using MAM (XEP 313) to get user's conversation history
Howdy! I'm having trouble trying to figure out how to get all of the messages for a user. I tried using the code found in this forum: https://forum.ag-software.net/thread/1693-How-to-get-priva…

This didn't quite work for me. I received some errors claiming that the module was not supported. I tried to fashion my own query xml tag using the XEP-313 documentation found here: https://xmpp.org/extensions/xep-0313.html#query

  1. <iq type="set" id="MX_3" xmlns="jabber:client">  
  2.  <query xmlns="urn:xmpp:mam:2">    
  3.     <set xmlns="http://jabber.org/protocol/rsm">
  4.       <max>1</max>
  5.     </set>  
  6.  </query>
  7. </iq>

This fixed the error and seems to return the correct data. My server responds with this:

  1. <!-- Incoming 8/23/2018 4:41:10 PM -->
  2. <message to='user1@localhost/12141833377959589889731' from='user1@localhost'>
  3. <result id='1534864749939235' xmlns='urn:xmpp:mam:2'>
  4. <forwarded xmlns='urn:xmpp:forward:0'>
  5. <message xml:lang='en' to='user2@localhost' from='user1@localhost/2415766176799085569403' type='chat' id='purple28e6e12f' xmlns='jabber:client'>
  6. <archived by='user1@localhost' id='1534864749939235' xmlns='urn:xmpp:mam:tmp'/>
  7. <stanza-id by='user1@localhost' id='1534864749939235' xmlns='urn:xmpp:sid:0'/>
  8. <active xmlns='http://jabber.org/protocol/chatstates'/>
  9. <body>Hello?</body>
  10. </message>
  11. <delay from='localhost' stamp='2018-08-21T15:19:09.939235Z' xmlns='urn:xmpp:delay'/>
  12. </forwarded>
  13. </result>
  14. </message>
  15. <r xmlns='urn:xmpp:sm:3'/>
  16. <iq xml:lang='en' to='user1@localhost/12141833377959589889731' from='user1@localhost' type='result' id='MX_3'>
  17. <fin complete='false' xmlns='urn:xmpp:mam:2'>
  18. <set xmlns='http://jabber.org/protocol/rsm'>
  19. <count>33</count>
  20. <first>1534864749939235</first>
  21. <last>1534864749939235</last>
  22. </set>
  23. </fin>
  24. </iq>

What I am having trouble with is figuring out where this data is stored/sent after the library makes the query. I noticed that in your weather example, you have a response weather tag that comes inside of the IQ result. Then, you simply grab the weather tag out of it. My server doesn't do that. Is there some way I can grab onto all of the XML that my server is spitting back to me? If I could do that, then I could parse all of the messages out. Or, is there an easier way to do that?

Thank you ahead of time!
This post was edited on 2018-08-25, 12:08 by Alex.
Avatar
Alex #2
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by sudorm on 2018-08-24, 00:00:
1535058007

can you please let me know what was wrongby default  and what you had to fix?

Quote by sudorm on 2018-08-24, 00:00:
1535058007

MatriX parses and builds only the XML DOM for you here. YOu have to parse out the information you need on your own.
But this should be pretty easy with the MatriX classes and XElement extensions we build in. Let us know when you need help here.

Alex
Avatar
sudorm #3
Member since Aug 2018 · 5 posts
Group memberships: Members
Show profile · Link to this post
If I remember right, I had to use query instead of a retrieve. In the example I have linked previously, there is a list variable with a type of Retrieve. I made my own query tag with your library instead. I then put that in the iq constructor and that is what fixed the error.

  1. var query = new Matrix.Xml.XmppXElement("urn:xmpp:mam:2", "query");
  2.  
  3. var iq = new Matrix.Xmpp.Client.Iq
  4. {
  5.     Type = Matrix.Xmpp.IqType.Set,
  6.     Query = query
  7. };

I will definitely let you know if I need any help parsing the data out! I was just having an issue figuring out where the data went. I just remembered that there is a onXML event in the library and that I could use that to record the server's response.
This post was edited on 2018-08-27, 15:52 by Alex.
Avatar
Alex #4
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
what you have done looks good to far. Some suggestions.
I wouls suggest that you create a custom class (eg MamQuery) for your query Element like desribed here and register it in the factory.
You can also easily creae an Iq query with this code then:

  1. var iq = new IqQuery<MamQuery>()
  2. {
  3.     Type = Matrix.Xmpp.IqType.Set,
  4. };

You can send your IQ using the async functionality and get back the result in 1 line like:

  1. Iq result = await xmppClient.SendIqAsync(iq);
  2. // parse your result here

this is usually easier than hooking up events like OnIq.

Alex
This post was edited on 2018-08-27, 18:50 by Alex.
Avatar
sudorm #5
Member since Aug 2018 · 5 posts
Group memberships: Members
Show profile · Link to this post
I think I might have an issue with trying to get all of the information I need doing this. I want to get all of the body text of messages between two different users. When I send my query, I get a long lists of messages that are outside of the result iq stanza like so:

  1. <!-- Outgoing 8/27/2018 1:02:41 PM -->
  2. <iq type='get' id='bauer1'>
  3.  <query xmlns='urn:xmpp:mam:tmp' queryid='f27' />
  4. </iq>
  5.  
  6. <!-- Incoming 8/27/2018 1:02:41 PM -->
  7. <message to='bauer1@localhost/1685755360005429248182' from='bauer1@localhost'>
  8. <result id='1534864749939235' queryid='f27' xmlns='urn:xmpp:mam:tmp'>
  9. <forwarded xmlns='urn:xmpp:forward:0'>
  10. <message xml:lang='en' to='bauer2@localhost' from='bauer1@localhost/2415766176799085569403' type='chat' id='purple28e6e12f' xmlns='jabber:client'>
  11. <archived by='bauer1@localhost' id='1534864749939235' xmlns='urn:xmpp:mam:tmp'/>
  12. <stanza-id by='bauer1@localhost' id='1534864749939235' xmlns='urn:xmpp:sid:0'/>
  13. <active xmlns='http://jabber.org/protocol/chatstates'/>
  14. <body>Hello?</body>
  15. </message>
  16. <delay from='localhost' stamp='2018-08-21T15:19:09.939235Z' xmlns='urn:xmpp:delay'/>
  17. </forwarded>
  18. </result>
  19. </message>
  20.  
  21. <r xmlns='urn:xmpp:sm:3'/>
  22.  
  23. <message to='bauer1@localhost/1685755360005429248182' from='bauer1@localhost'>
  24. <result id='1534873799967505' queryid='f27' xmlns='urn:xmpp:mam:tmp'>
  25. <forwarded xmlns='urn:xmpp:forward:0'>
  26. <message xml:lang='en' to='bauer1@localhost' from='bauer2@localhost/18326359478510802945859' type='chat' id='purplea221b7ba' xmlns='jabber:client'>
  27. <archived by='bauer1@localhost' id='1534873799967505' xmlns='urn:xmpp:mam:tmp'/>
  28. <stanza-id by='bauer1@localhost' id='1534873799967505' xmlns='urn:xmpp:sid:0'/>
  29. <active xmlns='http://jabber.org/protocol/chatstates'/>
  30. <body>test</body>
  31. </message>
  32. <delay from='localhost' stamp='2018-08-21T17:49:59.967505Z' xmlns='urn:xmpp:delay'/>
  33. </forwarded>
  34. </result>
  35. </message>
  36.  
  37. (There are about 30 other messages here)
  38.  
  39. <message to='bauer1@localhost/1685755360005429248182' from='bauer1@localhost'>
  40. <result id='1535035079809423' queryid='f27' xmlns='urn:xmpp:mam:tmp'>
  41. <forwarded xmlns='urn:xmpp:forward:0'>
  42. <message xml:lang='en' to='bauer2@localhost' from='bauer1@localhost/12141833377959589889731' type='chat' id='168295fe-6a21-4c81-9a5d-ccba58d10dfe' xmlns='jabber:client'>
  43. <archived by='bauer1@localhost' id='1535035079809423' xmlns='urn:xmpp:mam:tmp'/>
  44. <stanza-id by='bauer1@localhost' id='1535035079809423' xmlns='urn:xmpp:sid:0'/>
  45. <origin-id xmlns='urn:xmpp:sid:0' id='168295fe-6a21-4c81-9a5d-ccba58d10dfe'/>
  46. <request xmlns='urn:xmpp:receipts'/>
  47. <body>Test</body>
  48. <thread>lfCdlxXHpjAhfSlOIIJVtKtaNyBPpatz</thread>
  49. </message>
  50. <delay from='localhost' stamp='2018-08-23T14:37:59.809423Z' xmlns='urn:xmpp:delay'/>
  51. </forwarded>
  52. </result>
  53. </message>
  54.  
  55. <!-- Incoming 8/27/2018 1:02:41 PM -->
  56. <message to='bauer1@localhost/1685755360005429248182' from='bauer1@localhost'>
  57. <result id='1535035101328343' queryid='f27' xmlns='urn:xmpp:mam:tmp'>
  58. <forwarded xmlns='urn:xmpp:forward:0'>
  59. <message xml:lang='en' to='bauer2@localhost' from='bauer1@localhost/12141833377959589889731' type='chat' id='7f8c306d-3b7c-4251-b4f7-b77d4617b2ac' xmlns='jabber:client'>
  60. <archived by='bauer1@localhost' id='1535035101328343' xmlns='urn:xmpp:mam:tmp'/>
  61. <stanza-id by='bauer1@localhost' id='1535035101328343' xmlns='urn:xmpp:sid:0'/>
  62. <origin-id xmlns='urn:xmpp:sid:0' id='7f8c306d-3b7c-4251-b4f7-b77d4617b2ac'/>
  63. <request xmlns='urn:xmpp:receipts'/>
  64. <body>Test</body>
  65. <thread>lfCdlxXHpjAhfSlOIIJVtKtaNyBPpatz</thread>
  66. </message>
  67. <delay from='localhost' stamp='2018-08-23T14:38:21.328343Z' xmlns='urn:xmpp:delay'/>
  68. </forwarded>
  69. </result>
  70. </message>
  71.  
  72. <iq xml:lang='en' to='bauer1@localhost/1685755360005429248182' from='bauer1@localhost' type='result' id='bauer1'>
  73. <query queryid='f27' xmlns='urn:xmpp:mam:tmp'>
  74. <set xmlns='http://jabber.org/protocol/rsm'>
  75. <count>33</count>
  76. <first>1534864749939235</first>
  77. <last>1535035101328343</last>
  78. </set>
  79. </query>
  80. </iq>

Just storing the resulting iq that I get from the server doesn't seem to give me the information that I want. I want to try and parse out the author, recipient, body, etc of each individual message.

I think I just might have thought of a solution though. Would each of these message elements that I receive from my server trip the OnMessage event? If they would, then I could parse each message as I receive them for the information that I need.
This post was edited 2 times, last on 2018-08-27, 20:41 by Alex.
Avatar
Alex #6
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
This looks fine to me. I assume your server limits the result set by default to 33, and you have to send subsequent queries to page through the whole archive.

See also:
https://xmpp.org/extensions/xep-0313.html#query

Example 10 and 11 should be what you are looking for:
https://xmpp.org/extensions/xep-0313.html#query-paging

Alex
Avatar
sudorm #7
Member since Aug 2018 · 5 posts
Group memberships: Members
Show profile · Link to this post
I'm not too worried about paging through the rest of the results yet. I just want to get the data I need from the messages I get back. How do I get the body of the message in the following query?

  1. <!-- Outgoing 8/27/2018 2:04:43 PM -->
  2. <iq type='set' id='q29303'>
  3.  <query xmlns='urn:xmpp:mam:2'>
  4.       <set xmlns='http://jabber.org/protocol/rsm'>
  5.          <max>1</max>
  6.       </set>
  7.  </query>
  8. </iq>
  9.  
  10. <!-- Incoming 8/27/2018 2:04:43 PM -->
  11. <message to='bauer1@localhost/1685755360005429248182' from='bauer1@localhost'>
  12. <result id='1534864749939235' xmlns='urn:xmpp:mam:2'>
  13. <forwarded xmlns='urn:xmpp:forward:0'>
  14. <message xml:lang='en' to='bauer2@localhost' from='bauer1@localhost/2415766176799085569403' type='chat' id='purple28e6e12f' xmlns='jabber:client'>
  15. <archived by='bauer1@localhost' id='1534864749939235' xmlns='urn:xmpp:mam:tmp'/>
  16. <stanza-id by='bauer1@localhost' id='1534864749939235' xmlns='urn:xmpp:sid:0'/>
  17. <active xmlns='http://jabber.org/protocol/chatstates'/>
  18. <body>Hello?</body>
  19. </message>
  20. <delay from='localhost' stamp='2018-08-21T15:19:09.939235Z' xmlns='urn:xmpp:delay'/>
  21. </forwarded>
  22. </result>
  23. </message>
  24. <r xmlns='urn:xmpp:sm:3'/>
  25. <iq xml:lang='en' to='bauer1@localhost/1685755360005429248182' from='bauer1@localhost' type='result' id='q29303'>
  26. <fin complete='false' xmlns='urn:xmpp:mam:2'>
  27. <set xmlns='http://jabber.org/protocol/rsm'>
  28. <count>33</count>
  29. <first>1534864749939235</first>
  30. <last>1534864749939235</last>
  31. </set>
  32. </fin>
  33. </iq>

All the examples I have seen so far talk about parsing the resulting iq, but the body is not in the resulting iq in this example. How do I get what is in the body of the message above?
Avatar
Alex #8
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
the object hierarchy of the message is:

* Message
   * Result
      * Forwarded
         * Message

For Result there is currently no XElement class in MatriX. You can create and register your custom class for this.
Then you can either go down all the levels in the tree like this:
  1. var forwardedMessage =
  2. msg
  3.    .Element<Result>()
  4.    .Element<Forwarded>()
  5.    .Element<Message>();

or you loop recusive like this:
  1. var forwardedMessage = msg.Element<Message>(true);

once you have the internal message object you can just use all its properties, like Body.
This post was edited 2 times, last on 2018-08-27, 21:44 by Alex.
Avatar
sudorm #9
Member since Aug 2018 · 5 posts
Group memberships: Members
Show profile · Link to this post
Alex, thank you. I believe I understand now. I'm looking at what my onMessage event catches now and can see the nested message with result in it. I'll be sure to ask you if I have any more questions.
Avatar
Alex #10
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Yes, OnMessage is the correct event. Forgot to mention this.

Alex
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters: