0
votes

I have just switch to Smack 4.1 from depreciated asmack. Smack 4.1 is automatically sending receipts with wrong id attached which is causing exception in my case.

Smack 4.1 is attaching 2 different id's with receipt

Here is the chat message received

RECV (0): <message from='***' to='***' xml:lang='en' id='65' kind='0' type='chat'><body>vhh</body><request xmlns='urn:xmpp:receipts'/></message>

Here is the received receipt generated by Smack 4.1 in response of chat message

SENT (0): <message to='***' id='roZ7C-32' type='chat'><received xmlns='urn:xmpp:receipts' id='65'/></message>

Smack 4.1 is attaching 2 different ids with Received Receipt id='roZ7C-32' and id='65'

My Question ares :

  1. How can I make these 2 ids same
  2. How can I disable the receipts so that I can generate my custom recipts
3
Smack's behavior is correct as far as I can tell. If this is causing an exception on the delivery receipts receiver side then it's a bug there.Flow
Why is Smack attaching 2 different id's with a Receipt against a single chat message ?user4878765
There are two message stanzas involved, and every stanza has its own unique ID. The first message stanza with id "65" is acknowledged by Smack as delivered with the message stanza (id "roZ7C-32") send back to the sender of "65" containing <received … id='65'/>.Flow
Can I make Smack to send id 65 of both stanza instead of roZ7C-32user4878765
No, that's not possible and also not a good idea.Flow

3 Answers

0
votes

For your first question , to get the ID of the sent message the code would be:

Message ms = new Message();
ms.addBody("EN", Messegeforsend);
DeliveryReceiptRequest.addTo(ms); //tells that you will need delivery for this message
String send_message_id= ms.getStanzaId();

and you can get the ID for delivered message which would be same as the ID for the sent message :

deliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(connection);
deliveryReceiptManager.addReceiptReceivedListener(new ReceiptReceivedListener() {

            @Override
            public void onReceiptReceived(String arg0, String arg1, String arg2,Stanza arg3) {
                String delivered_message_id = arg2;
}

});

the send_message_id would be exactly equal to delivered_message_id, so you would know which message has been delivered

0
votes

SMACK 4.1.0 message receive listener to write below code

try {
                Message ms = new Message();
                ms.addBody("EN", "deleriyed");
                ms.setTo(message.getFrom());
                ms.setStanzaId(message.getStanzaId());
                DeliveryReceiptRequest.addTo(ms);
                connection.sendStanza(ms);
            } catch (NotConnectedException e) {
                e.printStackTrace();
            }
0
votes

The way you can disable this is just not adding receipt to message when sending one:

Most important method is

processPacketExtension

//Creating message in your method
public sendMessage(Jid to, String body){
    Message msg = Message(to, body);
    //Create and save your deliveryID to SQLite database
    deliveryID = DeliveryReceiptRequest.addTo(msg);
    ChatManager.getInstanceFor(connection).chatWith(jid).send(msg);
}

//Declare your stanza listener
private MessagePacketListener messagePacketListener;
//In your cotnructor   
messagePacketListener = new MessagePacketListener(context);

//Then in your login method register your stanza listener like this
public void login() throws SmackInvocationException, XmppStringprepException {
        connect();
        try {
            if (!con.isAuthenticated()) {
                ....
                con.addSyncStanzaListener(messagePacketListener, new StanzaTypeFilter(Message.class));
                ....
                }
        } catch(Exception e) {
                    ....
            }
        }



//Your StanzaListener where you parse your incoming message and if it is without body it is Delivery receipt
//Now you have your MessagePacketListener that process the incoming messages

public class MessagePacketListener implements StanzaListener{
    private Context context;

    MessagePacketListener(Context context) {
        this.context = context;
    }    
    @Override
    public void processStanza(Stanza packet) {
        Message msg = (Message)packet;

        //Message that have body
        if(msg.getBodies().size() > 0){
            //Text message
            //Do something with message msg.getBody()
        }
        else{
            //This must be sth like delivery receipt or Chat state msg and get your deliveryID
            processPacketExtension(msg);
        }
    }

    //processPacketExtension method that receive packet delivery ectension
    private void processPacketExtension(Message msg) {
        Collection<ExtensionElement> extensions = msg.getExtensions();
        if (extensions != null) {
            Iterator<ExtensionElement> iterator = extensions.iterator();
            if (iterator.hasNext()) {
                ExtensionElement extension = iterator.next();                
                if(extension instanceof DeliveryReceipt){
                    //Do sth with deliveryID
                    String deliveryID = ((DeliveryReceipt) extension).getId();
                }
            }
        }
    }
}