The messaging service API provides instant messaging functionality to the client application. It deals with retrieving data from the server, managing and performing business logic on this data and finally, presenting it to the UI layer. This API attempts to use closures where possible.
Most of the API calls allow a listener to pass in to handle success or fail.
MessagingService supports different features based on its type. To recognize whether the feature is available or not, you need to check the appropriate capability. UI elements should be enabled, disabled or hidden depending on these capabilities. Such capabilities exist at the MessagingService level:
Capability | Conditions Required | API to check the capability |
---|---|---|
Create Conversation | The Client is connected to the messaging server. | getCreateConversationCapability |
Remove Conversation | The Conversation is in the draft state. | getRemoveConversationCapability |
Retrieve Conversation | The Client is connected to the messaging server. The messaging server supports Retrieve. | getRetrieveConversationCapability |
Search Conversation | The Client is connected to the messaging server. The messaging server supports Search. | getSearchConversationCapability |
Update Refresh Mode | The Client is connected to the messaging server. The messaging server supports changing the refresh mode. | getUpdateRefreshModeCapability |
Validate Participant Addresses | The Client is connected to the messaging server. The messaging server supports validation of participant addresses. | getValidateParticipantAddressesCapability |
Automatically Update Last Access Time | The Client is connected to the messaging server. The messaging server supports automatic update of conversation last access timestamps. | getAutomaticallyUpdateLastAccessTimeCapability |
The MessagingService object is obtained from the Client SDK User object. The UserConfiguration object is used to define the services that are available to the end users of your application. Each service is configured individually. Its configuration is stored in a dedicated object referenced from the UserConfiguration object.
Note: More information on service configuration can be found in the article Configuring the SDK.
Start by obtaining any existing service configuration:
AMMConfiguration ammConfiguration = userConfiguration.getAMMConfiguration();
Enable the service and configure the AMM parameters supplied by your administrator:
ammConfiguration.setEnabled(true);
ServerInfo serverInfo = new ServerInfo("",
"",
TLS); // True if connection to the server is required to be secure;
ammConfiguration.setServerInfo(serverInfo);
//the poll refresh interval in minutes
ammConfiguration.setPollIntervalInMinutes(0);
Valid username and password are required to successfully register to the AMM server. The password required for the AMM service is not defined as a part of the service configuration. Passwords are requested by and communicated to the Client SDK using the CredentialProvider interface:
ammConfiguration.setCredentialProvider(messagingCredentialProvider);
And finally, save your configuration back to your UserConfiguration object.
userConfiguration.setAMMConfiguration(ammConfiguration);
Note: More information on how to manage passwords using CredentialProvider can be found in the article Working with Credentials.
After you instantiate and set up required configuration objects, now you are ready to create User and then call the start() method of your User to start all services. Then you can get MessagingService for its further usage:
MessagingService messagingService = mUser.getMessagingService();
These capabilities exist on the Client SDK Conversation object:
Capability | Conditions Required | API to check the capability |
---|---|---|
Create Message | The Client is connected to the messaging server. The Conversation is in the draft state and has been started, or the Conversation is in the published state. | getCreateMessageCapability |
MarkAllContentAsRead | The Client is connected to the messaging server. The messaging server supports marking all content in the conversation as read. The Conversation is published. | getMarkAllContentAsReadCapability |
Update Subject | The Client is connected to the messaging server. The messaging server supports changing the subject of the Conversation. The Conversation is active. The Conversation is either draft or published. | getUpdateSubjectCapability |
Update Last Access Time Capability | The Client is connected to the messaging server. The messaging server supports changing the LastAccessTime of the Conversation. The Conversation is published. | getUpdateLastAccessTimeCapability |
Leave | The Client is connected to the messaging server. The Conversation is in the published state. | getLeaveCapability |
Add Participants | The Client is connected to the messaging server. The Conversation is active. The Conversation is either draft or published. | getAddParticipantsCapability |
Remove Participants | The Conversation is in the draft state. | getRemoveParticipantsCapability |
Update Sensitivity | The Conversation is in the draft state. | getUpdateSensitivityCapability |
Older Content | The Client is connected to the messaging server. The Conversation is published. | getOlderContentCapability |
Start | The Conversation is in the draft state and has not yet been started. | getStartCapability |
Remove | The Conversation is in the draft state. | getRemoveCapability |
The retrieveActiveConversations() method retrieves the dynamically updated collection of conversations that are associated with the currently logged in user. Normally, the client application will only need to call this method once to install a watcher object to monitor the initial download of conversations and then continue to watch for updates to the collection.
DataRetrievalWatcher watcher = new DataRetrievalWatcher<>();
watcher.addListener(this);
messagingService.retrieveActiveConversations(watcher);
First, create new Conversation and then call the start() method of your Conversation object. Then you can add a participant to Conversation by specifying a valid extension and domain.
Conversation newConversation = messagingService.createConversation();
newConversation.start(new MessagingCompletionHandler() {
@Override
public void onSuccess() {
newConversation.addParticipantAddresses(addresses,
new AddParticipantAddressesCompletionHandler() {
@Override
public void onSuccess(List list) {
Log.d(LOG_TAG, "addParticipantAddresses - onSuccess");
}
@Override
public void onError(MessagingException e) {
Log.e(LOG_TAG, "Failed to add participant address", error);
}
});
}
@Override
public void onError(MessagingException e) {
// Update UI elements that new conversation was not started
}
});
These capabilities exist on the Client SDK Message object:
Capability | Conditions Required | API to check the capability |
---|---|---|
Update Body | The Message is in the draft or error state. | getUpdateBodyCapability |
Update InReplyTo | The Message is in the draft or error state. | getUpdateInReplyToCapability |
Update DoNotForward | The Message is in the draft or error state. | getUpdateDoNotForwardCapability |
Update Importance | The Message is in the draft or error state. | getUpdateImportanceCapability |
Create Attachment | The Message is in the draft or error state. | getCreateAttachmentCapability |
Send | The Client is connected to the messaging server. The Message is in the draft or error state. | getSendCapability |
MarkAsRead | The Client is connected to the messaging server. The messaging server supports marking messages as read. The Message is published. | getMarkAsReadCapability |
Remove | The Message is in the draft or error state. | getRemoveCapability |
Once Conversation has been created successfully, new Message can be created and sent in the scope of Conversation.
Message message = newConversation.createMessage();
message.setBodyAndReportTyping(newMessage, new MessagingCompletionHandler() {
@Override
public void onSuccess() {
message.send(new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "sending new Message: " + message.getBody() +
" is Success");
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Send message failed due to " +
error.getMessage());
}
});
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Create message failed due to" + error.getMessage());
}
});
If new Message has been received in the scope of existing Conversation your application will be notified via onConversationMessagesAdded(). The content of received Message should be added to active Conversation.
@Override
public void onConversationMessagesAdded(Conversation conversation,
List messages) {
for (Message message: messages) {
mMessages.add(message);
// Display received message on UI
}
}
When your application receives the onNumberOfConversationsWithUnreadContentSinceLastAccessChanged() callback, you need to retrieve all active conversations via the retrieveActiveConversations() method to update the list of current conversations. This callback is called to report that the number of conversations with unread content has changed since the last accessed time. Only new content since the last time when Conversation was accessed, will be flagged.
@Override
public void onNumberOfConversationsWithUnreadContentSinceLastAccessChanged
(MessagingService messagingService, int i) {
messagingService.retrieveActiveConversations(watcher);
}
To mark selected Message as read use the markAsRead() method of the Message object.
if (message.getMarkAsReadCapability().isAllowed()) {
message.markAsRead();
}
You can also mark all content in Conversation as read using the markAllContentAsRead() method.
if (conversation.getMarkAllContentAsReadCapability().isAllowed()) {
conversation.markAllContentAsRead(new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "Successfully marked all content as read");
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Failure marking all content as read due to "
+ error.getProtocolErrorReason());
}
});
}
These capabilities exist on the Client SDK Attachment object:
Capability | Conditions Required | API to check the capability |
---|---|---|
Update Name | The Attachment is in the draft or error state. | getUpdateNameCapability |
Update IsThumbnail | The Attachment is in the draft or error state. | getUpdateThumbnailCapability |
Update IsGeneratedContent | The Attachment is in the draft or error state. | getUpdateGeneratedContentCapability |
Update Location | The Attachment is in the draft or error state. | getUpdateLocationCapability |
Update MIME Type | The Attachment is in the draft or error state. | getUpdateMimeTypeCapability |
Download | The Client is connected to the messaging server. The Attachment is in the "ready to download" state. | getDownloadCapability |
Consume | The Attachment is in the "downloaded" or "consumed" state. | getConsumeCapability |
Remove | The Attachment is in the draft or error state. | getRemoveCapability |
Message is a crucial part of Conversation. An important part of Message is also represented as attachments. In order to create new Attachment in the Message object, use the createAttachment() method. You can attach Audio (".m4a"), Video (".mp4") and Pictures (".jpg") to your Message. First, create new Attachment in the Message object via the createAttachment() method and then set desired values (location, name, MIME types, etc.) for this attachment object.
Attachment attachment = draftMessage.createAttachment();
attachment.setLocation(attachmentPath, new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "Successfully set location to " + location);
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Failed setting location due to "
+ error.getProtocolErrorReason());
}
});
attachment.setMimeType(mimeType, new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "Successfully set mime");
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Failed setting mime due to "
+ error.getProtocolErrorReason());
}
});
attachment.setName(filename, new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "Successfully set name");
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Failed setting name due to "
+ error.getProtocolErrorReason());
}
});
attachment.setThumbnail(isThumbnail, new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "Successfully set isThumbnail to " + isThumbnail);
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Failed setting isThumbnail due to "
+ error.getProtocolErrorReason());
}
});
attachment.setGeneratedContent(isGeneratedContent,
new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "Successfully set isGeneratedContent to "
+ isGeneratedContent);
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Failed setting isGenerateContent due to "
+ error.getProtocolErrorReason());
}
});
To remove Attachment from Message, use the removeAttachment() method. Operation success or failure is reported through the completion handler.
for (Attachment attachment : draftMessage.getAttachments()) {
draftMessage.removeAttachment(attachment, new MessagingCompletionHandler() {
Override
public void onSuccess() {
Log.d(LOG_TAG, "Attachment removed successfully");
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Attachment removal failed due to "
+ error.toString());
}
});
}
Now you are ready to send your draft Message using the methods described above in the article.
You can download Attachment from Message by specifying the path to write the file to. To start downloading Attachment asynchronously you can use the download() method.
if (message.hasAttachment()) {
for (final Attachment attachment : message.getAttachments()) {
if (!attachment.isThumbnail()) {
inProgressDownload = attachment.download(file.getAbsolutePath(),
new MessagingCompletionHandler() {
@Override
public void onSuccess() {
Log.d(LOG_TAG, "Downloaded attachment");
Log.d(LOG_TAG, "Attachment was saved to: "
+ attachment.consume());
inProgressDownload = null;
}
@Override
public void onError(MessagingException error) {
Log.e(LOG_TAG, "Downloading attachment failed due to "
+ error.getProtocolErrorReason());
}
});
}
}
}
The consume() from the example above returns the location of Attachment (or empty string if the location is not available) so that it can be opened by the application. This method has additional effect of changing the status of Attachment to Opened.
You can cancel downloading Attachment as follows:
if (inProgressDownload != null) {
inProgressAttachmentDownload.cancel();
Log.d(LOG_TAG, "Cancelled download attachment");
}
else {
Log.d(LOG_TAG, "No download in progress");
}
Please note that the location of attachments is not stored across user session. Therefore, after logout/login there are no local storage paths and the client needs to download attachments again.