Accessing JSON object inside Message Stanza using Smack Library - android

my addAsyncStanzaListner is being called when an ack message is received from Firebase Cloud Messaging services. I need to ack this messages according to the docs. The problem that I am having is I can't reach the "message_type" "key"/"value" pair inside the JSON object that arrives inside the message stanza that's received. Could you please help me in accessing this important value/pair. I am using Smack Library 4.1. I've been following this post answer for this setup, but somehow It doesn't work:
GCM XMPP Server using Smack 4.1.0
Here's how the code is looking like:
other_connection.addAsyncStanzaListener(new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
//how should i convert this stanza into a message stanza
//I have tried Message message = (Message)packet; IT DOESNT WORK
//I have tried getting the extension with the GCM Namespace. It doesnt
//return a json string

In your code you just recive a Stanza as Java Object.
Stanza has a method to output an XML.
You can use this method to obtain a JSON if you need, just add some custom functionality.
Following this example
your code can looks like this:
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
JSONObject jsonObj = XML.toJSONObject(packet.toXML());
String json = jsonObj.toString();
//foo

Note: This answer is for the general problem of extracting JSON from a message. In the case of FCM, it's possible that there's another method that's more appropriate.
Suppose your have a Stanza object that corresponds to the following XML:
<message from='a#example.com' to='b#example.com' type='normal'>
<json xmlns='urn:xmpp:json:0'>{ "key1" : "value1", "key2": "value2" }</json>
<body/>
</message>
To extract the JSON string, you need to do:
import org.jivesoftware.smackx.json.packet.JsonPacketExtension;
...
JsonPacketExtension jsonPacketExtension = JsonPacketExtension.from(stanza);
String contentJson = jsonPacketExtension.getJson();

Related

how to post html tag in retrofit android

I need to use the following format payload in post method in retrofit. I need to post html tags as string. If we can't do this in retrofit, how can we do that?
{
"text": "<p>ffsdsdf <span class=\"mention\" data-index=\"0\" data-denotation-char=\"#\" data-id=\"12fe9af4-e2d6-47cb-9601-64c7a1fe9c4a\" data-value=\"Vendor 3 company Vendor\"><span contenteditable=\"false\"><span class=\"ql-mention-denotation-char\">#</span>Vendor 3 company Vendor</span></span> </p>",
"users": ["12fe9af4-e2d6-47cb-9601-64c7a1fe9c4a"]}
Update:
All I need to create a tag according to the number of users I get.
public interface placeApi {
#GET("/{id}")
public void getDataAPICall(#EncodedPath("text") TypedString text,
Callback<Model> response);
}
Try this.

how to publish and parse custom payload for pubsub xmpp smack library

this question is asked before here and here but i dont get answer from there.
I'm developing application in which i'm using pubsub and xmpp, for android i'm using smack library. i want to send custom payload to the node and on receiving custom payload how to parse and display it in to list? now i am able to send and receive message but it is just a small example from documentaion. here is my example,
String msg = "room pubsub test";
SimplePayload payload = new SimplePayload("message", "pubsub:test:message", "<message xmlns='pubsub:test:message'><body>" + msg + "</body></message>");
PayloadItem<SimplePayload> item = new PayloadItem<>(null, payload);
node.publish(item);
and when i receive item
node.addItemEventListener(new ItemEventListener() {
#Override
public void handlePublishedItems(ItemPublishEvent items) {
System.out.println("======================handlePublishedItems==============================");
System.out.println(items.getItems());
}
}
and the output i'm getting is
[org.jivesoftware.smackx.pubsub.PayloadItem |
Content [<item id='5E277A9C33A58'>
<message xmlns='pubsub:test:message'>
<body xmlns='pubsub:test:message'>room pubsub test</body><
/message>
</item>]]
i want to send custom payload like the time at which message is sent, who have sent this message etc.
so, how can i send custom payload? and how to parse it and show it to user?
Send custom payload for time and sender using below code:
SimplePayload payload = new SimplePayload("message", "pubsub:test:message", "<message xmlns='pubsub:test:message'><body>" + textMessage + "</body><from>"+Sender+"</from><time>"+time+"</time></message>");
For parsing you can use XmlPullParser and parse response using Tag name

How to get 'to' field in firebase could messaging JSON?

I can succesfully send Firebase cloud messages to my Android sample project. As described in here, I apply step 2 and it works so far.
My JSON body:
{
"to": "/topics/testTopic",
"data": {
"key1" : "val1",
"key2" : true
}
}
has a data field which I can access properly in my onMessageReceived() method:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String toVal = remoteMessage.getTo();
Map<String, String> data = remoteMessage.getData();
}
But the getTo() method gets null.
How can I access the 'to' field in my originating JSON?
I was expecting to have "/topics/testTopic" in im variable toVal.
I think you're looking for RemoteMessage.getFrom():
Get the sender of this message.
This will be the sender ID or the topic for topic messages.

How to send a XMPP IQ Package to a PHP JAXL-Script?

ive a problem. Im using asmack for connecting and sending Data between Android and OpenFire.
Now i'ld like to get this data with PHP and Jaxl (which is working fine).
The problem is that i modify the sent message (to JSON and XML) and add a HEADER to the XML/JSON. This seems to work well but its not a proper solution.
Now i'm thinking about sending IQ Packages which hold the Header information already.
This is the Part in Android/Java.
CommandIQPacket iq1 = new CustomIQPacket();
iq1.setTo(to);
iq1.setType(IQ.Type.GET);
iq1.setCommand("test");
iq1.setPriority(1);
iq1.setJid(message.getMessage());
iq1.setDate(new Date(System.currentTimeMillis()));
mConnection.sendPacket(iq1);
The CustomIQPacket class extends IQ and add the required data by overriding getChildElementXML().
Sample:
public class CommandIQPacket extends IQ {
private int priority;
private String jid, command;
//some getter and setter
#Override
public CharSequence getChildElementXML() {
StringBuilder builder = new StringBuilder("<query xmlns=\"urn:xmpp:ts\">");
builder.append("<jid command=\"");
builder.append(command).append("\"");
builder.append(" date=\"");
builder.append(date).append("\"");
builder.append(" priority=\"");
builder.append(priority).append("\"");
builder.append(">");
builder.append(jid);
builder.append("</jid>");
builder.append("</query>");
return builder.toString();
}
}
Now i've my PHP CLI Script with JAXL. This looks like that.
<?php
// configs, stuff, etc.
$client = new JAXL(array(
'jid' => "myopenfireuser",
'pass' => "myopenfirepass",
'bosh_url' => "http://url-to-bosh.com:7070/http-bind/",
'log_level' => JAXL_INFO,
'strict' => TRUE
));
$client->require_xep(array(
'0115', // Entity Capabilities
'0203', // Delayed Delivery
'0114', // jabber component protocol
'1337'
));
ive added 1337 here, which should be the XEP for parsing the IQ package.
$client->add_cb('on_chat_message', function($stanza) {
global $client;
$iq = $client->xeps['1337']->get_raw_iq_pkt();
// some more stuff
}
Now it seems to be that $iq does not hold any rawdata. I cant access the XML which means that i cant parse the IQ Package.
The 1337 XEP looks like that.
class XEP_1337 extends XMPPXep {
public function init() {
return array(
'on_get_iq' => 'on_xmpp_iq'
);
}
public function get_raw_iq_pkt() {
$attrs = array(
'type' => 'get',
'from' => $this->jaxl->full_jid->to_string(),
'to' => $this->jaxl->full_jid->domain
);
return $this->jaxl->get_iq_pkt(
$attrs, new JAXLXml('query', "ts")
);
}
}
I couldnt find any good tutorial about JAXL and IQ Packages. This is the only readme ive found about it (https://media.readthedocs.org/pdf/jaxl/latest/jaxl.pdf)
The sent data is for example
<iq id='qEfml-14' to='openfirebot#openfirebot.com/Ressource' type='get'><query xmlns="ts"><jid command="test" date="Mon Jul 28 12:36:15 MESZ 2014" priority="1">...</query></iq>
the return value from openfire (jaxl) is
<iq type="error" id="NP3HP-12" from="bot..#myopenfire.com" to="maclient#ts.com/Ressource"><query xmlns="ts" action="create"><jid command="test" date="Mon Jul 28 23:04:22 MESZ 2014" priority="1">...</jid></query><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
OpenFire error=
at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:283)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:701)
2014.07.29 15:56:33 org.jivesoftware.openfire.nio.ConnectionHandler - Closing connection due to error while processing message: <iq id="769-83772" to="ts.com" from="ts.com/4140f14a" type="result"></iq>
java.lang.NullPointerException
at org.jivesoftware.openfire.IQRouter.route(IQRouter.java:115)
at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:76)
at org.jivesoftware.openfire.net.StanzaHandler.processIQ(StanzaHandler.java:330)
at org.jivesoftware.openfire.net.ClientStanzaHandler.processIQ(ClientStanzaHandler.java:93)
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:295)
at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:187)
at org.jivesoftware.openfire.nio.ConnectionHandler.messageReceived(ConnectionHandler.java:181)
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:570)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.common.IoFilterAdapter.messageReceived(IoFilterAdapter.java:80)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:58)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:185)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:239)
at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:283)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:701)
This is what ive found out now:
Its important that to has the fullname with ressource. user#domain/Ressource
And.. the Receiving client must be online. Offline messages dont get accepted for IQ PAckets from OpenFire (by default)
And.. regarding this article it must be registered somehow. How can this be done in jaxl? i thought adding the XEP and using init() is enough.
Sending and Receiving custom XMPP IQs with aSmack on Android
And.. ive modified the PAcketListener but still same result.
PacketFilter filter = new PacketFilter() {
#Override
public boolean accept(Packet packet) {
return true;
}
};
mConnection.addPacketListener(mPacketListener, filter);
ProviderManager.addIQProvider("query", "ts", new CommandIQProvider());
while mPacketListener is a class which extends from PacketListener.
public class ChatPacketListener implements PacketListener {
public void processPacket(Packet packet) {
if (packet instanceof Message) {
Message message = (Message) packet;
String from = message.getFrom();
if (message.getBody() != null) {
Log.d("ChatPacketLsitener", "XMPP packet received - sending Intent: " + XmppService.ACTION_XMPP_MESSAGE_RECEIVED);
XmppService.maybeAcquireWakeLock();
XmppTools.startSvcXMPPMsg(mCtx, message.getBody(), from);
}
} else {
Log.e("Packet", "Packet is not from type Message. Its from type " + packet.getClass());
}
}

XMPP IQ result parsing issue

I am building a XMPP chat client app with eclipse, java and asmack. Using tutorials and many many google searches I managed to get the buddy list working, actual chatting also works fine.
My problem is with searching for more buddies to add to my contacts list. The XML to send is exemplified here : http://xmpp.org/extensions/xep-0055.html
My request is :
<iq
id="search123"
from="name3#webserv.xxx.com/name3"
to="search.xxx.zzz.com"
type="set" >
<query xmlns="jabber:iq:search" >
<nick>
android
</nick>
</query>
</iq>
the response I thought I was getting was/is this:
<iq
id="search123"
from="search.xxx.zzz.com"
to="name3#webserv.telebroad.com/Smack"
type="result" >
</iq>
But using
connConfig.setDebuggerEnabled(true);
(and an online Telnet Client) I managed to find out that the server IS actually working correctly and it's sending the requested results, but I'm just getting what you see above.
I have been at this for 4 days and my self esteem is quite low :P
Here is my code concerning the IQ request and response:
Packet asdf = new Packet() {
#Override
public String toXML() {
return "<iq type='set'"+
" from='name3#webserv.xxx.com/name3'"+
" to='search.xxx.zzz.com'"+
" id='search2'"+
" xml:lang='en'>"+
" <query xmlns='jabber:iq:search'>"+
" <nick>Android</nick>"+
" </query>"+
" </iq>";
}
};
ChatList.connection.sendPacket(asdf);
Log.e("packet", "request = "+ asdf.toXML());
PacketFilter filter = new IQTypeFilter(IQ.Type.RESULT);
ChatList.connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
IQ iq = (IQ)packet;
Log.e("response","incoming packet : "+ packet.toXML());
Log.e("response","incoming packet2 : "+ packet.toString());
}
}, filter);
I've tried lots of TypeFilters to no avail. I'm stumped!!
Bottom line:
1.request is being accepted correctly by server;
2.server response is correct(so says the debugger);
3.any response.toString or toXML prints out the type result XML from above(without the actual items after type='result'>.
4.I am about a week overdue on my final build for this app...help! :)
Try adding
ProviderManager pm = ProviderManager.getInstance();
pm.addIQProvider( "query","jabber:iq:search",new UserSearch.Provider());
pm.addExtensionProvider("x","jabber:x:data", new DataFormProvider());
before establishing connection.
This spec is already implemented via the UserSearchManager. Try using that instead.
As for your own case, I would guess that you haven't registered an appropriate provider for this specific element and namespace (like org.jivesoftware.smackx.search.UserSearch$Provider). In a normal Java environment, this would already be registered, but you will have to code it yourself in Android.
https://stackoverflow.com/a/14214622/1688731
This...just works!!!! I have no idea why. maybe Iterator iterator = row.getValues("jid"); does the trick. But everything else, I've tried a LOT of times!!

Categories

Resources