How to receive message stanza without sending self presence? - xmpp

I am using mongooseim with Android and Ios application. I just want to receive message from the server from background without sending self presence to anyone because this task is done by system. But I can't receive message stanza until I send my presence to the mongooseIM.
Do I missing something or there is a way by which I can get quick update from MongooseIM server in the background without sending presence?

As far as I understand you all you want to do is sync the messages when you receive a Push Notification. MongooseIM can be configured to serve a simple HTTP API with which you can get archived messages (mod_mam needs to be enabled) without establishing the XMPP connection. More details can be found in the HTTP API doc, especially the Swagger doc regarding get messages. Let me know if this suites you.

Related

How to get ejabberd server response messages for Rest API calls

I am trying to make use of ejabberd REST API calls by following this -
https://docs.ejabberd.im/developer/ejabberd-api/. I would like to do things like publishing to pubsub nodes or sending messages to clients by directly calling the APIs from a program or script.
I have configured the ejabberd server and tested ok with curl and Postman. Now, I would like to know if one can get detailed status messages of the API calls from the server back to the caller (program or script). Currently, the server only returns status codes of 0 for success and 1 otherwise for many of the calls.
In some cases, the API call may succeed but error may occur (for example, error in stanza). In the ejabberd debug logs, we can see the server replies back to the sender with iq stanzas with type=result or error. However, if the sender is not an XMPP client such as Postman or a Python script, the sender will have no way to receive it. Sure, we can use another XMPP client's JID in the "from" field but then we need to maintain an XMPP client and let it run all the time which we don't want.
Thanks for any advice.

Ejabberd Message delivery while application is terminated

I am developing a chat app using ejabberd server for both IOS and Android. I also wrote a module for ejabberd to get the offline messages sent to my own server api .
my own server api will send notifications to the IOS/Android platforms using FCM.
On the client side , if the application is in the foreground or the background , it will stay connected to ejabberd and if the client receives the message then ejabberd will send the message delivery status.
I am facing an issue while the app is terminated ( service is not running ) which means it is not connected to ejabberd (offline) . if i send a message to this app while it is not terminated , it will receive a notification but the message still undelivered . how can mark the messages as delivered when receiving the notification while the app is terminated.
to explain it more , the same functionality is working fine with whatsapp :
device A has whatsapp installed and whatsapp was turned off (terminated)
Device B has whatsapp running
Device B sends a message to device A
Device A receives a whatsapp notification
Without doing anything on Device A , the message status on Device B is marked as delivered .
How can I implement this scenario with ejabberd ?
In case someone went into this issue , here is the solution that I implemented with help of #Mickaël Rémond from his answer.
I configured ejabberd to send the offline messages to an http service ( your own server) please refer to this link for further on how to do it
your server should catch the above call and generate a notification message (FCM ) in my case and send it to recipient device
recipient device will catch the notification which includes the message
recipient device will call http service (your own server backend)that responsible for sending the deliver ack to the original sender . you need to pass from, to , stanzaId , vhost with this call
backend server will use ejabberd-api (set of exposed apis to manage ejabberd through rest apis calls) to send delivery message using this api
please note the following notes also :
sending the delivery message from your own server to ejabberd will not delete them from ejabberd database
if the user re-connected to the ejabberd server then the recipient will receive the message again from ejabberd .
It is probably too complex for a simple Stack Overflow question, as you need to integrate several moving part on client and server:
You need to execute code in background when receiving push notifications on iOS (you need that property set on your app in your app provisioning profile and have code to handle that). The client will initiate an HTTPS query to let the server know that the message was delivered.
You need to have an endpoint that will get the delivered HTTPS calls and generate either a message ack or a chat marker on behalf of the user and route it in ejabberd.
In real world, this is not enough if you want to take into account the fact that you can only have 1 push in the queue on APNS. If you have several messages sent while the device is not on the network, you will need to have the device check all received messages while offline on the server, otherwise you will lose messaging.
You need to rely on XMPP Message Archive Management (MAM) to handle that history.
As you see, this is not a simple few tens of line of codes but need real design and involved work.

Ejabberd with Stream management (XEP-198) not using offline message hook

We are developing an app with a chat feature. We have an ejabberd (15.02) configured to use mod_offline_post to use the offline message hook and forward all messages for offline clients to an url of our own which then forwards to the GCM.
However as we are developing an app, we also need XEP-198 (stream management) enabled to handle connection loss. This is working fine in itself. Streams are created and resumed, messages are acknowledged.
The problem is, that the jabber is waiting for a stream to resume and is not forwarding any offline messages to the offline message hook and thus to our mod and post url. It is storing them in its offline storage of course and they get delivered when the recipient resumes its stream.
Is there any way to configure the jabber to call the offline message hook while ejabberd_c2s:fsm_next_state:2517 Waiting for resumption of stream for... ?
PS: We use smack on the client side to provide stream management
In my understanding the behaviour of ejabberd is correct from the XMPP specification point of view. It is doing the right thing and should not in that case forward message to the offline store, because you are not offline technically.
It is just not the right place to place your push processing.

How to get acknowledgment for send/receive message in ejabbered/XMPP?

How to know that message is deliver to other user using XMPP framework and ejabberd, we are using XEP-0184 class for Message Delivery Receipts , we send the receipts request while sending with the message but didn’t get any response.
My Query is should i need to configure anything on server (or any changes in ejabberd.cfg file) for that or any client side code we need to do.
No, XEP-0184 is a purely client protocol, so there's nothing to set up on the server.
Among the reasons you're not receiving any acknowledges there might be:
Your clients just do not have XEP-0184 enabled.
Depending on the XMPP libraries you're using (on both clients — the sender and the receiver), the sender might decide to not even request receipts if it discovers (by querying the peer's capabilities) that it has XEP-0184 turned off.
To be may be more clear: XEPs usually suggest the implementations to check if the feature defined by the XEP is supported, and to not attempt to use it if it isn't. Not all libraries and client do this, but some do. This means that some implementations might go like this: OK, I was requested to send delivery receipt requests, so
Do service discovery on the peer I'm about to contact.
Check to see if it has XEP-0184 enabled.
If not, I'll just silently not attach any receipt requests.
Whether a particular XMPP library does this by itself depends on how "smart" is was made.
If by XMPP Framework you mean this library, please try to read its source code to see if it's "smart" and asks the peer for its caps and then checks to see if XEP-0184 is enabled.
Also check to see if you can enable logging of XML streams exchanged by your client. Inspecting them is the best way to debug XMPP-related issues.
You can use XEP-0022 Message events extension to achieve this:
Here your message stanza formate:
<message to='username#domain.com' id='msgId-21102012,12:12:11'>
<body>How are you doing?</body>
<x xmlns='jabber:x:event'>
<offline/>
<delivered/>
<composing/>
</x>
</message>
Based on receipnt status, open fire will respone with message event status. Once look into XEP-022 extension.

Send XMPP message without starting a chat

I am basically writing a XMPP client to automatically reply to "specific" chat messages.
My setup is like this:
I have pidgin running on my machine configured to run with an account x#xyz.com.
I have my own jabber client configured to run with the same account x#xyz.com.
There could be other XMPP clients .
Here is my requirement:
I am trying to automate certain kind of messages that I receive on gtalk. So whenever I receive a specific message eg: "How are you" , my own XMPP client should reply automatically with say "fine". How are you". All messages sent (before and after my client replies) to x#xyz.com but should be received by all clients (my own client does not have a UI and can only respond to specific messages.).
Now I have already coded my client to reply automatically. This works fine. But the problem I am facing is that as soon as I reply (I use the smack library), all subsequent messages that are sent to x#xyz.com are received only by my XMPP client. This is obviously a problem as my own client is quite dump and does not have a UI, so I don't get to see the rest of the messages sent to me, thereby making me "lose" messages.
I have observed the same behavior with other XMPP clients as well. Now the question is, is this is a requirement of XMPP (I am sorry but I haven't read XMPP protocol too well). Is it possible to code an XMPP client to send a reply to a user and still be able to receive all subsequent messages in all clients currently listening for messages? Making my client a full fledged XMPP client is a solution, but I don't want to go that route.
I hope my question is clear.
You may have to set a negative presence priority for your bot..
First thing to know is that in XMPP protocol every client is supposed to have a full JID. This is a bare JID - in your case x#xyz.com with a resource in the end e.g. x#xyz.com/pidgin or x#xyz.com/home (where /pidgin and /home are the resource). This is a part of how routing messages to different clients is supposed to be achieved.
Then there are the presence stanzas. When going online a client usually sends a presence stanza to the server. This informs about e.g. if the client is available for chat or away for lunch. Along with this information can be sent a priority. When there are more than one clients connected the one with the highest priority will receive the messages sent to the bare JID (e.g. ClientA(prio=50) and ClientB(prio=60) -> ClientB receives the messages sent to x#xyz.com). But there are also negative priorities. A priority less than 0 states that this client should never be sent any messages. Such a stanza might look like this
<presence from="x#xyz.com/bot">
<priority>-1</priority>
</presence>
This may fit your case. Please keep in mind it also depends on the XMPP server where your account is located, which may or may have not fully implemented this part of the protocol.
So to summarize: I recommend you to look through the Smack API how to set a presence and set the priority to <0 for your bot client right after it connected.