Create Group like WhatsApp, BBM in XMPP with (a)Smack - xmpp

Can I implement groupchat like WhatsApp or BBM in XMPP Asmack? I'm using Openfire Server.
I already implemented the basic multiuserchat in XMPP (http://xmpp.org/extensions/xep-0045.html), but it's not contain all the features that i needed.
I need the full features of group chat like :
groups can persist user no matter if they are online or not.
deliver offline messages to a group member (when he comes online).
Should I customize the server? or there are any Standard about this group feature?
I really need help for this problem.
Thank you.

You should use a packet listener for group chat messages. Run this packet listener in a service so that group chats are update even when the app is not running in foreground. Then check the sender id from packet and update your data base accordingly. Check the code below.
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
yourXmppConnection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
String received_message=message.getBody();
String from_user=message.getFrom();
// Add incoming message to the list view or similar
}
}
}, filter);

Related

Display message 'user typing...' to everyone, including sender, if I am typing a message, VUE JS and socket.io

I am using vuejs and socket.io in my application. The task is this: if I type a message in a dialogue with the user, display a message to both the interlocutor and myself, that I am typing a message.
How can I implement this?
Socket.io gives you lots of options to send messages across the board. What I always found very helpful is the Emit cheatsheet from the official docs (https://socket.io/docs/emit-cheatsheet/).
Here are some of the methods on how to broadcast messages to all clients including sender.
io.on('connect', onConnect);
function onConnect(socket) {
// sending to all clients in 'chat' room, including sender
io.in('chat').emit('typing', 'User xy is typing');
// sending to all clients in namespace 'chatNamespace', including sender
io.of('chatNamespace').emit('typing', 'User xy is typing');
// sending to a specific room in a specific namespace, including sender
io.of('chatNamespace').to('chat').emit('typing', 'User xy is typing');
}
Now this of course are just example methods. You would need to wrap this into your own business logic and probably register some socket event listeners to get this going.

How to synchronize XMPP chat threads between two users?

I'm currently using the aSmack library to do an XMPP client for Android.
One thing that I'm wondering is, what happens if two users each create a chat with the other person?
For example the first client will do:
connection.getChatManager().createChat("testing2#testing.com", new MessageListener() {
#Override
public void processMessage(Chat arg0, Message arg1) {
//.....
}
});
And the second client will do:
connection.getChatManager().createChat("testing1#testing.com", new MessageListener() {
#Override
public void processMessage(Chat arg0, Message arg1) {
//.....
}
});
Will there be two chat instances on the server, and so the message listeners won't pick up any messages, since they will be coming from a different chat?
Or will the server automatically synchronize the chat threads into one, and so the message listeners will work correctly and be able to intercept the incoming messages?
If it's the first scenario, then what possible solutions are there to solve that problem so as to merge the chats into one?
Edit: I've just tried it on a quick example and it seems it's the first case, though I'm unsure if it's because I did something incorrectly.
XMPP servers are not aware of the two chat threads you created in your example and therefore unable to synchronize them. This is by design. A XMPP chat is simply a set of message stanzas with the same thread id.
I recommend reading RFC 6121 5.2.1.

XMPP Smack chat using openfire

Few questions around getting Chat working with Smack (3.2.1)/Openfire(3.7.1Alpha).
I am currently testing it using a unit test. My unit test creates a connection, creates account, logs in, adds a new user to its roster, attempts to send a chat message to the new user and eventually deletes the users. Apart from my confusions around getting chat to work, others seem to work (verified using openfire admin dashboard).
A. When I do the following
public void sendChatMessage(String sender, String receiver, String message) {
Chat chat = chatManager.createChat(receiver, messageListener);
chat.sendMessage(message);
}
Current connection is of the 'sender' (i.e. sender is logged in) and my attempt is to send a message to 'receiver'. When I get callback in my listener, message.getFrom() returns the 'receiver' and message.getBody() returns null. I am obviously trying to send a message on behalf of 'sender' to 'receiver'. What am I missing?
B. My 'sender' and 'receiver' are simply unique 'usernames' (without
any #domain) and my server is simply 'localhost'.
connection = new XMPPConnection("localhost");
Do I need to modify the 'receiver' to be of different value to make it a valid JID (there are no errors at the moment)? What if I change my server (& the openfire server configurations)?
C. I am assuming there will always be one XMPPConnection per user? Is this correct?
D.
XMPPConnection.DEBUG_ENABLED = true;
When I have XMPPConnection in debug mode, a new window opens up, however, it is tied with my IDE. How can I have it not tied to the ide so I can look into the logs while trying to debug the code?

Access muc roster from an ejabberd module (disco_items?)

I'm building an ejabberd module to send carbon copies of messages to an external RESTful API. Everything works okay, and requests to that API are sending POST params with Sender, Recipient and the message Body.
I'm triggering the user_send_packet and user_receive_packet hooks for this, and I can extract the params (Sender, Recipient, Body) from the packet:
Sender = xml:get_tag_attr_s("from", Packet),
Recipient = xml:get_tag_attr_s("to", Packet),
Body = xml:get_path_s(Packet, [{elem, "body"}, cdata])
For group chats (MUC) I'd also like to send the MUC roster (participants) in a parameter, but I don't know how to access them.
Is there an event for this? Can anyone point me to some documentation?
Thanks in advance!
It seems that you want to get MUC participants of specific room.
You need to look at mod_muc.erl and mod_muc_room.erl.
I'm not sure which version of ejabberd you use, so I will explain based on latest ejabberd.
After getting pid of room by calling
mnesia:dirty_read(muc_online_room, {Room, Host})
you can call
gen_fsm:sync_send_all_state_event(Pid, {get_disco_item, From, Lang}, 100)
or use similar code. User list is in the reply.
If you don't like reply format, you may want to add custom handle_sync_event to mod_muc_room.erl .

openfire get online users

I'm using OpenFire server for instant messaging and JSJaC JavaScript library on the client. I'm new in XMPP technology.
What I want is on load I want to send a list of users and receive status for each. Something like
$(function(){
var UserList = ["Isis", "Jackob", "Oybek"];
con.send(UserList, OnComplete);
});
function OnComplete(myList){
for (el in myList)
if (el.IsOnline) {
// Do DOM Stuff
}
}
Is it possible?
I've been looking for the documentation, examples and other similar responses but didn't find anyting.
You can't query for presence. You can subscribe to presence. If you send your own presence in, the server will send you the current presence of everyone you have subscribed to, as well as every change they make to their presence from there on in. There's no way to tell when you're "done" getting presence, because you're never done. Just set up a callback to do something interesting whenever you get a presence change from the person you are subscribed to, and you'll be in good shape:
con.registerHandler('presence_in', function(p) {
var from = p.getFromJID()
// do something interesting with p, from, etc.
});