undefined

Messaging

ConnectyCube Chat (messaging) API is built on top of Real-time(XMPP) protocol. In order to use it you need to setup real-time connection with ConnectyCube Chat server and use it to exchange data.

By default Real-time Chat works over secure TLS connection.

Code samples

There are ready-to-go FREE code samples to help you better understand how to integrate messaging capabilities in your apps:

Connect to chat

// Provide chat connection configuration
ConnectycubeChatService.ConfigurationBuilder chatServiceConfigurationBuilder = new ConnectycubeChatService.ConfigurationBuilder();
chatServiceConfigurationBuilder.setSocketTimeout(60);
chatServiceConfigurationBuilder.setKeepAlive(true);
chatServiceConfigurationBuilder.setUseTls(true); //By default TLS is disabled.
ConnectycubeChatService.setConfigurationBuilder(chatServiceConfigurationBuilder);

ConnectycubeChatService chatService = ConnectycubeChatService.getInstance();

final ConnectycubeUser user = new ConnectycubeUser();
user.setId(21);
user.setPassword("supersecurepwd");

chatService.login(user, new EntityCallback() {
    @Override
    public void onSuccess() {

    }

    @Override
    public void onError(ResponseException errors) {

    }
});

Use ConnectionListener to handle different connection states:

ConnectionListener connectionListener = new ConnectionListener() {
    @Override
    public void connected(XMPPConnection connection) {

    }

    @Override
    public void authenticated(XMPPConnection connection) {

    }

    @Override
    public void connectionClosed() {

    }

    @Override
    public void connectionClosedOnError(Exception e) {

    }

    @Override
    public void reconnectingIn(int seconds) {

    }

    @Override
    public void reconnectionSuccessful() {

    }

    @Override
    public void reconnectionFailed(Exception e) {

    }
};

ConnectycubeChatService.getInstance().addConnectionListener(connectionListener);

Disconnect

boolean isLoggedIn = chatService.isLoggedIn();
if(!isLoggedIn){
    return;
}

chatService.logout(new EntityCallback() {

    @Override
    public void onSuccess() {
        chatService.destroy();
    }

    @Override
    public void onError(ResponseException errors) {

    }
});

Reconnection

The SDK reconnects automatically when connection to Chat server is lost.

There is a way to disable it and then manage it manually:

ConnectycubeChatService.getInstance().setReconnectionAllowed(false);

Dialogs

All chats between users are organized in dialogs. The are 3 types of dialogs:

  • 1-1 chat - a conversation between 2 users.
  • group chat - a conversation between specified list of users.
  • public chat - an open conversation. Any user from your app can subscribe to it.

You need to create a new dialog and then use it to chat with other users. You also can obtain a list of your existing dialogs.

Create new dialog

Create 1-1 chat

You need to pass ConnectycubeDialogType.PRIVATE as a type and an id of an opponent you want to create a chat with:

ArrayList<Integer> occupantIds = new ArrayList<Integer>();
occupantIds.add(34);

ConnectycubeChatDialog dialog = new ConnectycubeChatDialog();
dialog.setType(ConnectycubeDialogType.PRIVATE);
dialog.setOccupantsIds(occupantIdsList);

//or just use DialogUtils
//ConnectycubeChatDialog dialog = DialogUtils.buildPrivateDialog(recipientId);

ConnectycubeRestChatService.createChatDialog(dialog).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog createdDialog, Bundle params) {

    }

    @Override
    public void onError(ResponseException exception) {

    }
});

Create group chat

You need to pass ConnectycubeDialogType.GROUP as a type and ids of opponents you want to create a chat with:

ArrayList<Integer> occupantIds = new ArrayList<Integer>();
occupantIds.add(34);
occupantIds.add(35);
occupantIds.add(36);

ConnectycubeChatDialog dialog = new ConnectycubeChatDialog();
dialog.setType(ConnectycubeDialogType.GROUP);
dialog.setOccupantsIds(occupantIdsList);
dialog.setName("Hawaii party");
//dialog.setPhoto("...");
//dialog.setDescription("...");

//or just use DialogUtils
//ConnectycubeChatDialog dialog = DialogUtils.buildDialog("Hawaii party", ConnectycubeDialogType.GROUP, occupantIds);

ConnectycubeRestChatService.createChatDialog(dialog).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog createdDialog, Bundle params) {

    }

    @Override
    public void onError(ResponseException exception) {

    }
});

Create public chat

It's possible to create a public chat, so any user from your application can subscribe to it. You need to pass ConnectycubeDialogType.PUBLIC as a type to create a chat with:

ConnectycubeChatDialog dialog = new ConnectycubeChatDialog();
dialog.setType(ConnectycubeDialogType.PUBLIC);
dialog.setName("Blockchain trends");
//dialog.setPhoto("...");
//dialog.setDescription("...");

ConnectycubeRestChatService.createChatDialog(dialog).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog createdDialog, Bundle params) {

    }

    @Override
    public void onError(ResponseException exception) {

    }
});

With public dialog ID any a user can subscribe to the public dialog via the following code:

ConnectycubeRestChatService.subscribePublicDialog(dialogID).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog dialog, Bundle params) {

    }

    @Override
    public void onError(ResponseException responseException) {

    }
});

After dialog subscription, this dialog will be listed in retrieve dialogs request and you also will be able to chat in it.

You also can unsubscribe if you do not want to be in this public dialog anymore:

ConnectycubeRestChatService.unsubscribePublicDialog(dialogID).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog result, Bundle params) {

    }

    @Override
    public void onError(ResponseException responseException) {

    }
});

Retrieve list of dialogs

It's common to request all your conversations on every app login:

RequestGetBuilder requestBuilder = new RequestGetBuilder();
requestBuilder.setLimit(50);
requestBuilder.setSkip(100);
//requestBuilder.sortAsc("last_message_date_sent");

ConnectycubeRestChatService.getChatDialogs((ConnectycubeDialogType)null, requestBuilder).performAsync(new EntityCallback<ArrayList<ConnectycubeChatDialog>>() {
    @Override
    public void onSuccess(ArrayList<ConnectycubeChatDialog> dialogs, Bundle params) {
        int totalEntries = params.getInt("total_entries");
    }

    @Override
    public void onError(ResponseException exception) {

    }
});

It will return all your 1-1 dialogs, group dialog and also public dialogs your are subscribed to.

If you want to retrieve only conversations updated after some specific date time, you can use requestBuilder.gt("updated_at", "1455098137"); filter. This is useful if you cache conversations somehow and do not want to obtain the whole list of your conversations on every app start.

Update dialog’s name, description, photo

User can update group chat name, description, photo:

ConnectycubeChatDialog dialog = new ConnectycubeChatDialog();
dialog.setDialogId("5356c64ab35c12bd3b108a41");
dialog.setName("Hawaii party");
dialog.setPhoto("https://new_photo_url"); // or it can be an ID to some file in Storage module
dialog.setDescription("New dialog description");

ConnectycubeRestChatService.updateChatDialog(dialog, null).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog updatedDialog, Bundle bundle) {

    }

    @Override
    public void onError(ResponseException error) {

    }
});

Add/Remove occupants

You can add/remove occupants in group and public dialogs:

DialogRequestBuilder requestBuilder = new DialogRequestBuilder();
requestBuilder.addUsers(378);
// requestBuilder.removeUsers(22);

ConnectycubeChatDialog dialog = new ConnectycubeChatDialog();
dialog.setDialogId("5356c64ab35c12bd3b108a41");

ConnectycubeRestChatService.updateChatDialog(dialog, requestBuilder).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog updatedDialog, Bundle bundle) {

    }

    @Override
    public void onError(ResponseException error) {

    }
});

Important note: Only group chat owner and admins can remove other users from group chat.

Add/Remove admins

Admins it's a special role in chats. They have the same permissions as a dialog's creator except add/remove other admins and remove dialog.

Owner of the group chat dialog can add admins:

DialogRequestBuilder updateBuilder = new DialogRequestBuilder();
updateBuilder.addAdminsIds(17616, 17617);
ConnectycubeRestChatService.updateChatDialog(groupDialog, updateBuilder).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog result, Bundle params) {

    }

    @Override
    public void onError(ResponseException responseException) {

    }
});

and remove:

DialogRequestBuilder updateBuilder = new DialogRequestBuilder();
updateBuilder.removeAdminsIds(17616, 17617);
ConnectycubeRestChatService.updateChatDialog(groupDialog, updateBuilder).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog result, Bundle params) {

    }

    @Override
    public void onError(ResponseException responseException) {

    }
});

Pin messages

Pinning a message allows users to easily store messages which are important and have a quick access to them. The following code pins some messages to a particular group dialog:

DialogRequestBuilder updateBuilder = new DialogRequestBuilder();
updateBuilder.addPinnedMessagesIds("5356c64ab35c12bd3b10ba32", "5356c64ab35c12bd3b10wa65");
//updateBuilder.removePinnedMessagesIds("5356c64ab35c12bd3b10ba32", "5356c64ab35c12bd3b10wa65");
ConnectycubeRestChatService.updateChatDialog(groupDialog, updateBuilder).performAsync(new EntityCallback<ConnectycubeChatDialog>() {
    @Override
    public void onSuccess(ConnectycubeChatDialog result, Bundle params) {

    }

    @Override
    public void onError(ResponseException responseException) {

    }
});

Remove dialog

The following snippet is used to delete a conversation:

String dialogId = "5356c64ab35c12bd3b108a41";
boolean forceDelete = false;

ConnectycubeRestChatService.deleteDialog(dialogId, forceDelete).performAsync(new EntityCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid, Bundle bundle) {

    }

    @Override
    public void onError(ResponseException error) {

    }
});

This request will remove this conversation for current user, but other users still will be able to chat there. The forceDelete parameter is used to completely remove the dialog. Only group chat owner can remove the group conversation for all users.

You can also delete multiple conversations in a single request.

Chat history

Every chat conversation stores its chat history which you can retrieve:

ConnectycubeChatDialog chatDialog = new ConnectycubeChatDialog("5356c64ab35c12bd3b108a41");

MessageGetBuilder messageGetBuilder = new MessageGetBuilder();
messageGetBuilder.setLimit(100);
// messageGetBuilder.gt("date_sent", "1455098137");

ConnectycubeRestChatService.getDialogMessages(chatDialog, messageGetBuilder).performAsync(new EntityCallback<ArrayList<ConnectycubeChatMessage>>() {
    @Override
    public void onSuccess(ArrayList<ConnectycubeChatMessage> messages, Bundle bundle) {

    }

    @Override
    public void onError(ResponseException error) {

    }
});

If you want to retrieve chat messages that were sent after or before specific date time only, you can use messageGetBuilder.gt("date_sent", "1455098137") or messageGetBuilder.lt("date_sent", "1455098137") filter. This is useful if you implement pagination for loading messages in your app.

Important note: All retrieved chat messages will be marked as read after the request. If you decided not to mark chat messages as read, then add the following parameter to your request: messageGetBuilder.markAsRead(false);

Send/Receive chat messages

Receive messages

There is IncomingMessagesManager to listen for all incoming messages from all dialogs.

IncomingMessagesManager incomingMessagesManager = chatService.getIncomingMessagesManager();

incomingMessagesManager.addDialogMessageListener(new ChatDialogMessageListener() {
    @Override
    public void processMessage(String dialogId, ConnectycubeChatMessage message, Integer senderId) {

    }

    @Override
    public void processError(String dialogId, ChatException exception, ConnectycubeChatMessage message, Integer senderId) {

    }
});

Pay attention, messages from group & public chat dialogs will be received in this callback only after you join the dialogs.

1-1 chat

try {
    ConnectycubeChatDialog privateDialog = ...;

    ConnectycubeChatMessage chatMessage = new ConnectycubeChatMessage();
    chatMessage.setBody("How are you today?");
    chatMessage.setSaveToHistory(true);

    privateDialog.sendMessage(chatMessage);
} catch (SmackException.NotConnectedException e) {

}

privateDialog.addMessageListener(new ChatDialogMessageListener() {
    @Override
    public void processMessage(String dialogId, ConnectycubeChatMessage message, Integer senderId) {

    }

    @Override
    public void processError(String dialogId, ChatException exception, ConnectycubeChatMessage message, Integer senderId) {

    }
});

Group/Public chat

Before you start chatting in a group/public conversation, you need to join it by calling join method:

ConnectycubeChatDialog groupChatDialog = ...;

DiscussionHistory discussionHistory = new DiscussionHistory();
discussionHistory.setMaxStanzas(0);

groupChatDialog.join(discussionHistory, new EntityCallback() {
    @Override
    public void onSuccess(Object o, Bundle bundle) {

    }

    @Override
    public void onError(ResponseException e) {

    }
});

Then you are able to send/receive messages:

try {
    ConnectycubeChatMessage chatMessage = new ConnectycubeChatMessage();
    chatMessage.setBody("How are you today?");
    chatMessage.setSaveToHistory(true);

    groupChatDialog.sendMessage(chatMessage);
} catch (SmackException.NotConnectedException e) {

}

groupChatDialog.addMessageListener(new ChatDialogMessageListener() {
    @Override
    public void processMessage(String dialogId, ConnectycubeChatMessage message, Integer senderId) {

    }

    @Override
    public void processError(String dialogId, ChatException exception, ConnectycubeChatMessage message, Integer senderId) {

    }
});

When it's done, you can leave the group conversation by calling leave method:

try {
    groupChatDialog.leave();
    groupChatDialog = null;
} catch (XMPPException | SmackException.NotConnectedException e) {

}

'Sent' status

There is a 'sent' status to ensure that message is delivered to the server.

In order to use the feature you need to enable it:

ConnectycubeChatService chatService = ConnectycubeChatService.getInstance();

chatService.setUseStreamManagement(true);

chatService.login(user);

Pay attention: you should enable Stream Management before logging into the chat. Stream Management is initialized only during chat login step.

The Stream Management defines an extension for active management of a stream between client and server, including features for stanza acknowledgements.

The following callback is used to track the status:

ChatDialogMessageSentListener messageSentListener = new ChatDialogMessageSentListener() {
    @Override
    public void processMessageSent(String dialogId, ConnectycubeChatMessage message) {

    }

    @Override
    public void processMessageFailed(String dialogId, ConnectycubeChatMessage message) {

    }
};

ConnectycubeChatDialog chatDialog = ...;
chatDialog.addMessageSentListener(messageSentListener);

'Delivered' status

The following callback is used to track the 'delivered' status:

private MessageStatusesManager messageStatusesManager;
private MessageStatusListener messageStatusListener;

// call it after chat login
messageStatusesManager = ConnectycubeChatService.getInstance().getMessageStatusesManager();

messageStatusListener = new MessageStatusListener() {
    @Override
    public void processMessageDelivered(String messageId, String dialogId, Integer userId) {

    }

    @Override
    public void processMessageRead(String messageId, String dialogId, Integer userId) {

    }
};

messageStatusesManager.addMessageStatusListener(messageStatusListener);

The SDK sends the 'delivered' status automatically when the message is received by the recipient. This is controlled by chatMessage.setMarkable(true) parameter when you send a message.

If markable is false or omitted, then you can send the delivered status manually via Chat:

ConnectycubeChatMessage message = ...;

try {
    chatDialog.deliverMessage(message);
} catch (XMPPException | SmackException.NotConnectedException e) {

}

and via REST

MessageUpdateBuilder messageUpdateBuilder = new MessageUpdateBuilder();
messageUpdateBuilder.markDelivered();

ConnectycubeRestChatService.updateMessage(messageId, dialogId, messageUpdateBuilder).performAsync(new EntityCallback<Void>() {
    @Override
    public void onSuccess(Void result, Bundle params) {

    }

    @Override
    public void onError(ResponseException responseException) {

    }
});

'Read' status

Send the 'read' status:

try {
    chatDialog.readMessage(chatMessage);
} catch (XMPPException | SmackException.NotConnectedException e) {

}

Receive the 'read' status callback:

private MessageStatusesManager messageStatusesManager;
private MessageStatusListener messageStatusListener;

// call it after chat login
messageStatusesManager = ConnectycubeChatService.getInstance().getMessageStatusesManager();

messageStatusListener = new MessageStatusListener() {
    @Override
    public void processMessageDelivered(String messageId, String dialogId, Integer userId) {

    }

    @Override
    public void processMessageRead(String messageId, String dialogId, Integer userId) {

    }
};

messageStatusesManager.addMessageStatusListener(messageStatusListener);

'Is typing' status

The following 'typing' notifications are supported:

  • typing: The user is composing a message. The user is actively interacting with a message input interface specific to this chat session (e.g., by typing in the input area of a chat window)
  • stopped: The user had been composing but now has stopped. The user has been composing but has not interacted with the message input interface for a short period of time (e.g., 30 seconds)

Send the 'is typing' status:

try {
    chatDialog.sendIsTypingNotification();
} catch (XMPPException | SmackException.NotConnectedException e) {
    e.printStackTrace();
}

...

try {
    chatDialog.sendStopTypingNotification();
} catch (XMPPException | SmackException.NotConnectedException e) {
    e.printStackTrace();
}

Receive the 'is typing' status callback:

ChatDialogTypingListener typingListener = new ChatDialogTypingListener() {
    @Override
    public void processUserIsTyping(String dialogId, Integer senderId) {

    }

    @Override
    public void processUserStopTyping(String dialogId, Integer senderId) {

    }
};

chatDialog.addIsTypingListener(typingListener);

Edit Message

The following snippet is used to edit chat message:

try {
    dialog.editMessageWithId("5356c64ab35c12bd3b10wa64", "Updated message body", true);
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
}

Other users will receive the 'update' status callback:

MessageUpdateListener messageUpdateListener = new MessageUpdateListener() {
    @Override
    public void processMessageUpdated(String messageID, String dialogId, String newBody, boolean isLastMessage) {

    }
};
ConnectycubeChatService.getInstance().getMessageStatusesManager().addMessageUpdateListener(messageUpdateListener);

Delete chat messages

The following snippet is used to remove chat message via REST:

Set<String> messagesIds = new HashSet<String>() {{
    add("546cc3240eda8f2dd7ee2291");
    add("546cc3230eda8f2dd7ee2292");
}};

boolean forceDelete = false;

ConnectycubeRestChatService.deleteMessages(messagesIDs, forceDelete).performAsync(new EntityCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid, Bundle bundle) {

    }

    @Override
    public void onError(ResponseException e) {

    }
});

This request will remove the messages from current user history only, without affecting the history of other users. The forceDelete parameter is used to completely remove messages.

The following snippet is used to remove chat message in a real time:

try {
    dialog.removeMessageWithId("5356c64ab35c12bd3b10wa64");
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
}

Other users will receive the 'delete' status callback:

MessageDeleteListener messageDeleteListener = new MessageDeleteListener() {
    @Override
    public void processMessageDeleted(String messageID, String dialogId) {

    }
};
ConnectycubeChatService.getInstance().getMessageStatusesManager().addMessageDeleteListener(messageDeleteListener);

Self-destroy message

Self-destroy messages is used if you want to implement some sort of Secret Chat where messages are visible only for some limited amount of time.

It's your responsibility to setup a timer in your app and remove messages from the client side.

Self-destroy messages are not stored in server history.

ConnectycubeChatMessage chatMessage = new ConnectycubeChatMessage();
chatMessage.setBody("Self destroy message");
chatMessage.setDestroyAfter(10);
try {
    chatDialog.sendMessage(chatMessage);
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
}

chatDialog.addMessageListener(new ChatDialogMessageListener() {
    @Override
    public void processMessage(String dialogId, ConnectycubeChatMessage message, Integer senderId) {
        if (message.getDestroyAfter() > 0) {
            // setup a timer
        }
     }
});

Attachments

Image/Video

Chat attachments are supported with the cloud storage API. In order to send a chat attachment you need to upload the file to ConnectyCube cloud storage and obtain a link to the file (file UID). Then you need to include this UID into chat message and send it.

File messageAttachment = new File("some_image.png");
Boolean fileIsPublic = false;

ConnectycubeStorage.uploadFileTask(messageAttachment, fileIsPublic, null, new ProgressCallback() {
    @Override
    public void onProgressUpdate(int progressPercentages) {

    }
}).performAsync(new EntityCallback<ConnectycubeFile>() {
    @Override
    public void onSuccess(ConnectycubeFile storageFile, Bundle bundle) {
        // create a message
        ConnectycubeChatMessage chatMessage = new ConnectycubeChatMessage();
        chatMessage.setSaveToHistory(true);
        // attach a photo
        ConnectycubeAttachment attachment = new ConnectycubeAttachment("photo");
        attachment.setId(file.getId().toString());
        chatMessage.addAttachment(attachment);

        // send a chat message
        // ...
    }

    @Override
    public void onError(ResponseException e) {

    }
});

The same flow is supported on the receiver's side. When you receive a message, you need to get the file UID and then download the file from the cloud storage.

// ChatDialogMessageListener

...

@Override
public void processMessage(String dialogId, ConnectycubeChatMessage chatMessage, Integer senderId) {
    for (ConnectycubeAttachment attachment : chatMessage.getAttachments()){
        String fileId = attachment.getId();

        // download a file
        ConnectycubeStorage.downloadFile(fileId).performAsync(new EntityCallback<InputStream>(){
            @Override
            public void onSuccess(InputStream inputStream, Bundle params) {
                // process file
            }

            @Override
            public void onError(ResponseException errors) {

            }
        });
    }
}

Contact

A contact profile can be send via chat attachments as well:

// create a message
ConnectycubeChatMessage chatMessage = new ConnectycubeChatMessage();
chatMessage.setSaveToHistory(true);

// build a contact representation
JsonObject jc = new JsonObject();
jc.add("phone", new JsonPrimitive("180032323223"));
jc.add("name", new JsonPrimitive("Samuel Johnson"));

// attach a contact
ConnectycubeAttachment attachment = new ConnectycubeAttachment("contact");
attachment.setData(jc.toString());
chatMessage.addAttachment(attachment);

// send a chat message
// ...

On the receiver's side, when you receive a message, you need to get a contact data from an attachment:

// ChatDialogMessageListener

...

@Override
public void processMessage(String dialogId, ConnectycubeChatMessage chatMessage, Integer senderId) {
    for (ConnectycubeAttachment attachment : chatMessage.getAttachments()){
        String data = attachment.getData();
        JsonObject obj = new JsonParser().parse(data).getAsJsonObject();
        String phone = obj.getAsJsonPrimitive("phone").getAsString();
        String name = obj.getAsJsonPrimitive("name").getAsString();
    }
}

Unread messages count

You can request total unread messages count and unread count for particular conversation:

Set<String> dialogsIds = new HashSet<String>();
    dialogsIds.add("546cc3240eda8f2dd7ee2291");
    dialogsIds.add("546cc3230eda8f2dd7ee2292");

ConnectycubeRestChatService.getTotalUnreadMessagesCount(dialogsIds).performAsync(new EntityCallback<Integer>() {
    @Override
    public void onSuccess(Integer total, Bundle params) {
        Log.i(TAG, "total unread messages: " + total);
        Log.i(TAG, "dialog Unread1: " + params.getInt("546cc3240eda8f2dd7ee2291"));
        Log.i(TAG, "dialog Unread2: " + params.getInt("546cc3230eda8f2dd7ee2292"));
    }

    @Override
    public void onError(ResponseException e) {

    }
});

Chat alerts

When you send a chat message and the recipient/recipients is offline, then automatic push notification will be fired.

In order to receive push notifications you need to subscribe for it. Please refer to Push Notifications guide.

To configure push template which users receive - go to Dashboard Console, Chat Alerts page

Note that currently push notifications are supported on mobile environment only.

Contact list

The Contact List API is rather straightforward. User A sends a request to become "friends" with user B. User B accepts the friend request. And now user A and B appear in each other's roster.

Setup Contact List

To access contact list you have to obtain it and set all needed listeners:

RosterListener rosterListener = new RosterListener() {
    @Override
    public void entriesDeleted(Collection<Integer> userIds) {

    }

    @Override
    public void entriesAdded(Collection<Integer> userIds) {

    }

    @Override
    public void entriesUpdated(Collection<Integer> userIds) {

    }

    @Override
    public void presenceChanged(ConnectycubePresence presence) {

    }
};

SubscriptionListener subscriptionListener = new SubscriptionListener() {
    @Override
    public void subscriptionRequested(int userId) {

    }
};

// Do this after success Chat login
ConnectycubeRoster chatRoster = ConnectycubeChatService.getInstance().getRoster(ConnectycubeRoster.SubscriptionMode.mutual, subscriptionListener);
chatRoster.addRosterListener(rosterListener);

RosterListener is a listener that is fired any time a contact list is changed or the presence of a user in the contact list is changed (user becomes online/offline)

SubscriptionListener is a listener that is fired on "subscribe" (add to contact list) request from any user.

Access to the Contact list

Then you can access all contact list items:

Collection<ConnectycubeRosterEntry> entries = сhatRoster.getEntries();

A ConnectycubeRosterEntry describes a user entity in your contact list. To get a user ID of an entry - use getUserId() method.

Then, you can get a user's status:

int userID = 34;

ConnectycubePresence presence = chatRoster.getPresence(userID);

if (presence == null) {
    // No user in your roster
    return;
}

if (presence.getType() == ConnectycubePresence.Type.online) {
    // User is online
}else{
    // User is offline
}

Add user to your contact list

To add user to the contact list use the following snippet:

int userID = 34;

if (chatRoster.contains(userID)) {
    try {
        chatRoster.subscribe(userID);
    } catch (Exception e) {

    }
} else {
    try {
        chatRoster.createEntry(userID, null);
    } catch (Exception e) {

    }
}

Note

Maximum number of contacts is 300.

Other user will receive the request to be added to the contact list:

// SubscriptionListener

@Override
public void subscriptionRequested(int userId) {

}

Confirm the contact request

To confirm the request use the following method:

try {
    chatRoster.confirmSubscription(userID);
} catch (Exception e) {

}

Reject the contact request

To reject the request use the following method:

try {
    chatRoster.reject(userID);
} catch (Exception e) {

}

Remove user from the contact list

To remove a previously added user from the contact list use the following method:

int userID = 67;

try {
    chatRoster.unsubscribe(userID);
} catch (Exception e) {

}

Contact list updates

So the above RosterListener listener will give you all the updates regarding contact list changes and users' statuses updates.

Privacy (black) list

Privacy list API allows enabling or disabling communication with other users in a chat. You can create, modify, or delete privacy lists, define a default list.

The user can have multiple privacy lists, but only one can be active.

Create privacy list

A privacy list must have at least one element in order to be created. If no elements specified, then the list with given name will be deleted.

ConnectycubePrivacyList list = new ConnectycubePrivacyList();
list.setName("myList");

ArrayList<ConnectycubePrivacyListItem> items = new ArrayList<ConnectycubePrivacyListItem>();

ConnectycubePrivacyListItem item1 = new ConnectycubePrivacyListItem();
item1.setAllow(false);
item1.setType(ConnectycubePrivacyListItem.Type.USER_ID);
item1.setValueForType(String.valueOf(3678));
item1.setMutualBlock(true);

items.add(item1);

list.setItems(items);

PrivacyListsManager privacyListsManager = chatService.getPrivacyListsManager();
try {
    privacyListsManager.createPrivacyList(list);
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
    e.printStackTrace();
} catch (SmackException.NoResponseException e) {
    e.printStackTrace();
}

The ConnectycubePrivacyListItem class takes 4 arguments:

  • type - use USER_ID to block a user in 1-1 chat or GROUP_USER_ID to block in a group chat.
  • valueForType - ID of a user to apply an action
  • allow - can be true/false.
  • mutualBlock - can be true/false - to block user's message in both directions or not.

In order to be used the privacy list should be not only set, but also activated(set as default).

Activate privacy list

In order to activate rules from a privacy list you should set it as default:

try {
    privacyListsManager.applyPrivacyList("myList");
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
    e.printStackTrace();
} catch (SmackException.NoResponseException e) {
    e.printStackTrace();
}

Update privacy list

There are some rules you should follow to update a privacy list:

  • Include all of the desired items (not a "delta").
  • If you want to update or set new privacy list instead of current one, you should decline current default list first.
// Deactivate active list
try {
    privacyListsManager.declinePrivacyList();
} catch (SmackException|XMPPException.XMPPErrorException e) {

}

// Create new list
// ...

// Activate again active list
try {
    privacyListsManager.applyPrivacyList("myList");
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
    e.printStackTrace();
} catch (SmackException.NoResponseException e) {
    e.printStackTrace();
}

Retrieve privacy lists

To get a list of all your privacy lists use the following request:

PrivacyListsManager privacyListsManager = ConnectycubeChatService.getInstance().getPrivacyListsManager()

List<ConnectycubePrivacyList> lists = null;
try {
    lists = privacyListsManager.getPrivacyLists();
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
    e.printStackTrace();
} catch (SmackException.NoResponseException e) {
    e.printStackTrace();
}

Retrieve privacy list with name

To get the privacy list by name you should use the following method:

ConnectycubePrivacyList list = null;
try {
    list = privacyListsManager.getPrivacyList("myList");
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
    e.printStackTrace();
} catch (SmackException.NoResponseException e) {
    e.printStackTrace();
}

Remove privacy list

Note: Before deleting privacy list you should decline it.

try {
    privacyListsManager.declinePrivacyList();
    privacyListsManager.deletePrivacyList("myList");
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
    e.printStackTrace();
} catch (SmackException.NoResponseException e) {
    e.printStackTrace();
}

Blocked user attempts to communicate with user

Blocked users will be receiving an error when trying to chat with a user in a 1-1 chat and will be receiving nothing in a group chat:

ConnectycubeChatMessage chatMessage = new ConnectycubeChatMessage();
chatMessage.setBody("How is going on?");

ConnectycubeChatDialog chatDialog = ...;

chatDialog.sendMessage(chatMessage);

...

privateDialog.addMessageListener(new ChatDialogMessageListener() {
    @Override
    public void processMessage(String dialogId, ConnectycubeChatMessage message, Integer senderId) {

    }

    @Override
    public void processError(String dialogId, ChatException exception, ConnectycubeChatMessage message, Integer senderId) {
      log("processError: " + error.getLocalizedMessage());
    }
});
Log output:
processError: Service not available.