QuickBlox Documentation

QuickBlox provides powerful Chat API and SDK to add real-time messaging and video calls to your web and mobile apps. Learn how to integrate QuickBlox across multiple platforms and devices. Check out our detailed guides to make integration easy and fast.

Advanced

Learn how to manage message statuses, attachments, contact list, offline messaging, and privacy list.

Message statuses

Every message has statuses as sent, delivered and read. Thus, in the message model you can find IDs of users who have read the message (status read) or who have received the message but it still unread (status delivered). There is no field for a sent status in the message model. We send a message to the server and if no error is returned, then it is considered as sent (by default).

Receive message status

To receive callbacks when your message becomes delivered or read, use the QBMessageStatusListener.

QBMessageStatusesManager qbMessageStatusesManager = QBChatService.getInstance().getMessageStatusesManager();
qbMessageStatusesManager.addMessageStatusListener(new QBMessageStatusListener() {
    @Override
    public void processMessageDelivered(String messageID, String dialogID, Integer userID) {

    }

    @Override
    public void processMessageRead(String messageID, String dialogID, Integer userID) {

    }
});
val qbMessageStatusesManager = QBChatService.getInstance().messageStatusesManager
qbMessageStatusesManager.addMessageStatusListener(object : QBMessageStatusListener {
    override fun processMessageDelivered(messageID: String?, dialogID: String?, userID: Int?) {

    }

    override fun processMessageRead(messageID: String?, dialogID: String?, userID: Int?) {

    }
})

To receive typing and stopped typing events, use the QBChatDialogTypingListener.

QBChatDialogTypingListener typingListener = new QBChatDialogTypingListener() {
    @Override
    public void processUserIsTyping(String s, Integer integer) {

    }

    @Override
    public void processUserStopTyping(String s, Integer integer) {

    }
};

dialog.addIsTypingListener(typingListener);
val typingListener = object : QBChatDialogTypingListener {
    override fun processUserIsTyping(s: String?, integer: Int?) {

    }

    override fun processUserStopTyping(s: String?, integer: Int?) {

    }
}

dialog.addIsTypingListener(typingListener)

How to define message status when you are displaying an old message from chat history.

private void defineStatus(QBChatMessage message) {
    Collection<Integer> deliveredToIDs = message.getDeliveredIds();
    Collection<Integer> readByIDs = message.getReadIds();

    if (readByIDs.size() > 0) {
        // You may define the message as Read
    } else if (deliveredToIDs.size() > 0) {
        // You may define the message as Delivered
    } else {
        // You may define the message as Sent
    }
}
private fun defineStatus(message: QBChatMessage) {
    val deliveredToIDs = message.deliveredIds
    val readByIDs = message.readIds

    if (readByIDs.size > 0) {
        // You may define the message as Read
    } else if (deliveredToIDs.size > 0) {
        // You may define the message as Delivered
    } else {
        // You may define the message as Sent
    }
}

Sent status

If you want to definitely know that your message has been delivered to the server, you should enable Stream Management before connecting to Chat.

// If you use QBChatService.ConfigurationBuilder
configurationBuilder.setUseStreamManagement(true);

// Or you can do it straight in QBChatService
chatService.setUseStreamManagement(true);

// Connect to chat
// chatService.login(qbUser...
// If you use QBChatService.ConfigurationBuilder
configurationBuilder.isUseStreamManagement = true

// Or you can do it straight in QBChatService
chatService.setUseStreamManagement(true)

// Connect to chat
// chatService.login(qbUser...

🚧

Pay attention

You should enable Stream Management before you do the chatService.login() because the Stream Management is initialized while Chat login is performed.

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

The following callback is used to track the status.

QBChatDialogMessageSentListener messageSentListener = new QBChatDialogMessageSentListener() {
    @Override
    public void processMessageSent(String dialogId, QBChatMessage qbChatMessage) {

    }

    @Override
    public void processMessageFailed(String dialogId, QBChatMessage qbChatMessage) {

    }
};

chatDialog.addMessageSentListener(messageSentListener);
val messageSentListener = object : QBChatDialogMessageSentListener {
    override fun processMessageSent(dialogId: String?, qbChatMessage: QBChatMessage?) {

    }

    override fun processMessageFailed(dialogId: String?, qbChatMessage: QBChatMessage?) {

    }
}

chatDialog.addMessageSentListener(messageSentListener)

Delivered status

To handle the message delivered event, the following code can be used.

// to notify the server that the message has delivered to you
try {
    dialog.deliverMessage(message);
} catch (XMPPException | SmackException.NotConnectedException e) {

}
// to notify the server that the message has delivered to you
try {
    dialog.deliverMessage(message)
} catch (e: XMPPException) {

} catch (e: SmackException.NotConnectedException) {
    
}

The SDK sends the delivered status automatically when the message is received by the recipient. This is controlled by chatMessage.setMarkable parameter when you send a message. Set this parameter as true to be able to receive the delivered status automatically.

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

Read status

To send the read status use the following code snippet.

// to notify the server about displaying message to the user
try {
    dialog.readMessage(message);
} catch (XMPPException | SmackException.NotConnectedException e) {

}
// to notify the server about displaying message to the user
try {
    dialog.readMessage(message)
} catch (e: XMPPException) {

} catch (e: SmackException.NotConnectedException) {

}

Is typing status

The following 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 typing status.

// When user starts typing in the message input field
try {
    dialog.sendIsTypingNotification();
} catch (XMPPException | SmackException.NotConnectedException e) {

}
// When user starts typing in the message input field
try {
    dialog.sendIsTypingNotification()
} catch (e: XMPPException) {

} catch (e: SmackException.NotConnectedException) {

Send the stopped typing status.

// When the user stops typing and not interact with message input field
try {
    dialog.sendStopTypingNotification();
} catch (XMPPException | SmackException.NotConnectedException e) {

}
// When the user stops typing and not interact with message input field
try {
    dialog.sendStopTypingNotification()
} catch (e: XMPPException) {

} catch (e: SmackException.NotConnectedException) {

Add extra data to a message

You have the option to extend the message with additional fields. Specify one or more key-value items to the message. Using these items, you can implement the ability for a user to send self-location information to another user or notification messages signifying that a user has left a group, etc.

QBChatMessage qbChatMessage = new QBChatMessage();
qbChatMessage.setSaveToHistory(true);
qbChatMessage.setMarkable(true);
qbChatMessage.setBody("How are you today?");
qbChatMessage.setProperty("customParam1", "book");
qbChatMessage.setProperty("customParam2", "21");
        
qbChatDialog.sendMessage(qbChatMessage, new QBEntityCallback<Void>() {
    @Override
    public void onSuccess(Void v, Bundle b) {
                
    }

    @Override
    public void onError(QBResponseException e) {

    }
});
val qbChatMessage = QBChatMessage()
qbChatMessage.setSaveToHistory(true)
qbChatMessage.isMarkable = true
qbChatMessage.body = "How are you today?"
qbChatMessage.setProperty("customParam1", "book")
qbChatMessage.setProperty("customParam2", "21")

qbChatDialog.sendMessage(qbChatMessage, object : QBEntityCallback<Void> {
    override fun onSuccess(v: Void?, b: Bundle?) {

    }

    override fun onError(e: QBResponseException?) {

    }
})

Attachments

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

File filePhoto = new File("image.png");
boolean fileIsPublic = false;
String [] tags = new String[]{"tag_1", "tag_2"};

QBContent.uploadFileTask(filePhoto, fileIsPublic, String.valueOf(tags), new QBProgressCallback() {
    @Override
    public void onProgressUpdate(int i) {
        // i - progress in percents
    }
}).performAsync(new QBEntityCallback<QBFile>() {
    @Override
    public void onSuccess(QBFile qbFile, Bundle bundle) {
        // create a message
        QBChatMessage chatMessage = new QBChatMessage();
        chatMessage.setSaveToHistory(true); // Save a message to history

        // attach a photo
        QBAttachment attachment = new QBAttachment("photo");
        attachment.setId(qbFile.getId().toString());
        chatMessage.addAttachment(attachment);

        // send the message
        // ...
    }

    @Override
    public void onError(QBResponseException e) {
        // error
    }
});
val filePhoto = File("image.png")
val fileIsPublic = false
val tags = arrayOf("tag_1", "tag_2")

QBContent.uploadFileTask(filePhoto, fileIsPublic, tags.toString()) {
    // i - progress in percents
}.performAsync(object : QBEntityCallback<QBFile> {
    override fun onSuccess(qbFile: QBFile?, bundle: Bundle?) {
        // create a message
        val chatMessage = QBChatMessage()
        chatMessage.setSaveToHistory(true) // Save a message to history

        // attach a photo
        val attachment = QBAttachment("photo")
        attachment.id = qbFile.id.toString()
        chatMessage.addAttachment(attachment)

        // send the message
        // ...
    }

    override fun onError(e: QBResponseException?) {
        // error
    }
})

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

// QBChatDialogMessageListener
@Override
public void processMessage(String dialogID, QBChatMessage qbChatMessage, Integer integer) {
    // count of attachments might be more than one
    for (QBAttachment attachment : qbChatMessage.getAttachments()) {
        String fileID = attachment.getId();

        // download a file
        QBContent.downloadFile(fileID).performAsync(new QBEntityCallback<InputStream>() {
            @Override
            public void onSuccess(InputStream inputStream, Bundle bundle) {
                // process file
            }

            @Override
            public void onError(QBResponseException e) {

            }
        });
    }
}
// QBChatDialogMessageListener 
override fun processMessage(dialogID: String, qbChatMessage: QBChatMessage, integer: Int?) {
    // count of attachments might be more than one
    for (attachment in qbChatMessage.attachments) {
        val fileID = attachment.id

        // download a file
        QBContent.downloadFile(fileID).performAsync(object : QBEntityCallback<InputStream> {
            override fun onSuccess(inputStream: InputStream?, bundle: Bundle?) {
                // process file
            }

            override fun onError(e: QBResponseException?) {

            }
        })
    }
}

Update message

To update a message, use the messageUpdateBuilder.

QBMessageUpdateBuilder messageUpdateBuilder = new QBMessageUpdateBuilder();
messageUpdateBuilder.updateText("Updated message body string");

// If you want to mark message as Delivered or Read on the server
//messageUpdateBuilder.markDelivered();
//messageUpdateBuilder.markRead();

QBRestChatService.updateMessage(message.getId(), message.getDialogId(), messageUpdateBuilder).performAsync(new QBEntityCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid, Bundle bundle) {

    }

    @Override
    public void onError(QBResponseException e) {

    }
});
val messageUpdateBuilder = QBMessageUpdateBuilder()
messageUpdateBuilder.updateText("Updated message body string")

// If you want to mark message as Delivered or Read on the server
//messageUpdateBuilder.markDelivered();
//messageUpdateBuilder.markRead();

QBRestChatService.updateMessage(message.id, message.dialogId, messageUpdateBuilder).performAsync(object : QBEntityCallback<Void> {
    override fun onSuccess(aVoid: Void?, bundle: Bundle?) {

    }

    override fun onError(e: QBResponseException?) {

    }
})

📘

Note

This functionality is not convenient to update messages statuses for the sender. To update message statuses, use MessageStatusListener.

Delete message

The request below will remove the messages only from current user history, without affecting the history of other users.

Set<String> messagesIDs = new HashSet<>();
messagesIDs.add("456abcdefg9876lmnop23qrst");
messagesIDs.add("456gfedcba5432ponml09xyz0");

boolean forceDelete = false;

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

    }

    @Override
    public void onError(QBResponseException e) {

    }
});
val messagesIDs = HashSet<String>()
messagesIDs.add("456abcdefg9876lmnop23qrst")
messagesIDs.add("456gfedcba5432ponml09xyz0")

val forceDelete = false

QBRestChatService.deleteMessages(messagesIDs, forceDelete).performAsync(object : QBEntityCallback<Void> {
    override fun onSuccess(aVoid: Void?, bundle: Bundle?) {

    }

    override fun onError(e: QBResponseException?) {

    }
})

📘

Note

If you want to completely remove the messages from all user's history, use the forceDelete = true parameter.

Offline messaging

The offline messaging functionality allows for displaying automatic push notifications on a user's device when they are offline. In other words, if your opponent is offline when you are writing a message, they can automatically receive a push notification.

🚧

Note

To become online you should log in to Chat (connect).

chatService.login(qbUser, new QBEntityCallback() {
    @Override
    public void onSuccess(Object o, Bundle bundle) {

    }

    @Override
    public void onError(QBResponseException e) {

    }
});
chatService.login(qbUser, object : QBEntityCallback<Void> {
    override fun onSuccess(o: Void?, bundle: Bundle?) {

    }

    override fun onError(e: QBResponseException?) {

    }
})

The user becomes offline after logout from Chat.

chatService.logout(new QBEntityCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid, Bundle bundle) {
        chatService.destroy();
    }

    @Override
    public void onError(QBResponseException e) {

    }
});
chatService.logout(object : QBEntityCallback<Void> {
    override fun onSuccess(aVoid: Void?, bundle: Bundle?) {
        chatService.destroy()
    }

    override fun onError(e: QBResponseException?) {

    }
})

Offline messages are customized from the Dashboard. Just follow Dashboard => YOUR_APP => Chat => Offline messaging directory to locate offline messaging settings.

📘

Note

Make sure to subscribe your users to pushes using SDKs. Review Push Notifications section for more details.

Here you will find the following settings:

  • Enable automatic push notifications for offline users - check it to receive push notifications from the server automatically.
  • Offline messaging text - text of your push notification.
  • Templates - set push notification template here. Use template variables to engage your push message.
  • Badge counter - set badge counter to include counter info into your push message. Useful to include unread counter - the number of unread messages a user has.
  • Sound - set push notification sound (for iOS only).
  • Category - describes "actions" that should be presented in the app notification in various views (for iOS only).
  • Content Available - enable it to indicate that new content is available (for iOS only).
  • Mutable content - enable it to modify the content of newly delivered notifications before the user is alerted. Use a notification service app extension to be able to modify the content of the notification. If the option is enabled, the system passes the notification to the service app extension for the subsequent modification of the notification payload before the actual delivery (for iOS only).

🚧

Note

Currently, push notifications are supported in the mobile environment only.

📘

Note

Set setSaveToHistory when sending messages to apply offline pushes. Review this section for more details.

Send system messages

There is a way to send system messages to other users about some events. For example, a system message can be sent when a user has joined or left a group dialog. These messages are handled over a separate channel and are not be mixed up with regular chat messages. Thus, they are handled by the systemMessagesListener listener. See how to add the listener in the snippet below.

System messages are also not shown in the dialog history and, consequently, are not stored on the server. This means that these messages will be delivered only to online users. Send system messages using the sendSystemMessage() method.

private QBSystemMessagesManager systemMessagesManager;
private QBSystemMessageListener systemMessageListener;
 
void setSystemMessagesManager() {
    systemMessagesListener = new QBSystemMessageListener(){
        @Override
        public void processMessage(QBChatMessage qbChatMessage) {
            // New System Message Received
        }

        @Override
        public void processError(QBChatException e, QBChatMessage qbChatMessage) {
            // New System Message Received with Exception
        }
    };
    systemMessagesManager = QBChatService.getInstance().getSystemMessagesManager();
    systemMessagesManager.addSystemMessageListener(systemMessagesListener);
}

void sendSystemMessage(QBChatDialog qbChatDialog, Integer opponentID) {
    QBChatMessage qbChatMessage = new QBChatMessage();

    qbChatMessage.setDialogId(qbChatDialog.getDialogId());
    qbChatMessage.setRecipientId(opponentID);

    qbChatMessage.setProperty("custom_property_1", "custom_value_1");
    qbChatMessage.setProperty("custom_property_2", "custom_value_2");
    qbChatMessage.setProperty("custom_property_3", "custom_value_3");

    try {
        systemMessagesManager.sendSystemMessage(qbChatMessage);
    } catch (SmackException.NotConnectedException e) {
        e.printStackTrace();
    }
}
private lateinit var systemMessagesListener: QBSystemMessageListener
private lateinit var systemMessagesManager: QBSystemMessagesManager
    
fun setSystemMessagesManager() {
    systemMessagesListener = object : QBSystemMessageListener {
        override fun processMessage(qbChatMessage: QBChatMessage) {
            // New System Message Received
    }

        override fun processError(e: QBChatException, qbChatMessage: QBChatMessage) {
            // New System Message Received with Exception
        }
    }
    systemMessagesManager = QBChatService.getInstance().systemMessagesManager
    systemMessagesManager.addSystemMessageListener(systemMessagesListener)
}

fun sendSystemMessage(qbChatDialog: QBChatDialog, opponentID: Int?) {
    val qbChatMessage = QBChatMessage()

    qbChatMessage.dialogId = qbChatDialog.dialogId
    qbChatMessage.recipientId = opponentID

    qbChatMessage.setProperty("custom_property_1", "custom_value_1")
    qbChatMessage.setProperty("custom_property_2", "custom_value_2")
    qbChatMessage.setProperty("custom_property_3", "custom_value_3")

    try {
        systemMessagesManager.sendSystemMessage(qbChatMessage)
    } catch (e: SmackException.NotConnectedException) {
        e.printStackTrace()
    }
}

Parameters

Description

qbChatMessage

Specifies system message fields that should be set.

Set the following fields of the qbChatMessage:

Fields

Required

Description

recipientId

yes

ID of the recipient.

dialogId

no

ID of the Dialog.

property

no

Extra data. Specify any key-value pairs. In each pair, the key and value are both string values.

Check if a user is online

You can check user presence using a Contact List. UsegetPresence() method to check is a user is online. To learn more about the Contact List feature, see this section.

QBPresence presence = contactsRoster.getPresence(user.getId());

if (presence == null) {
    // no user in your contact list
    return;
}
if (presence.getType() == QBPresence.Type.online) {
    // user is online
} else {
    // user is offline
}
val presence = contactsRoster.getPresence(user.id)

if (presence == null) {
    // no user in your contact list
    return
}
if (presence.type == QBPresence.Type.online) {
    // user is online
} else {
    // user is offline
}

Contact list

The Contact List API is rather straightforward. A user A sends a request to become "friends" with a user B. The user B accepts the friend request. And now the user A and B appear in each other roster.
This feature is also useful to get online/offline statuses of the users from the user's Contact List.

Add listener

To use a contact list, you have to obtain it and set all needed listeners.

QBRosterListener rosterListener = new QBRosterListener() {
    @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(QBPresence presence) {
 
    }
};

QBSubscriptionListener subscriptionListener = new QBSubscriptionListener() {
    @Override
    public void subscriptionRequested(int userId) {
    // Subscription was requested by user with ID = userId
    }
};

// You should do this after login (connect) to the Chat
QBRoster chatRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener);
chatRoster.addRosterListener(rosterListener);
val rosterListener = object : QBRosterListener { 
    override fun entriesDeleted(collection: Collection<Int>?) {

    }

    override fun entriesAdded(collection: Collection<Int>?) {

    }

    override fun entriesUpdated(collection: Collection<Int>?) {

    }

    override fun presenceChanged(qbPresence: QBPresence?) {

    }
}

val subscriptionListener = QBSubscriptionListener { userId: Int -> {
    // Subscription was requested by user with ID = userId
    }
}

// You should do this after login (connect) to the Chat
val contactsRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener)
contactsRoster.addRosterListener(rosterListener)

🚧

Pay attention

You should call chatService.getRoster() only after successful connecting to Chat. To learn how to this, review Connect to Chat section.

QBRosterListener 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 (e.g. user becomes online/offline).

QBSubscriptionListener is a listener that is called subscriptionRequested when the current user has been requested for adding to the Contact List from any user.

Access contact list

The following function gives you access to all contact list items.

Collection<QBRosterEntry> entries = contactsRoster.getEntries();
val entries = contactsRoster.entries

A QBRosterEntry describes a user entity in your contact list. To get the Presence of a user, use getPresence(userID) method. Then, you can get a user's status.

QBPresence presence = contactsRoster.getPresence(user.getId());

if (presence == null) {
    // no user in your contact list
    return;
}
if (presence.getType() == QBPresence.Type.online) {
    // user is online
} else {
    // user is offline
}
val presence = contactsRoster.getPresence(user.id)

if (presence == null) {
    // no user in your contact list
    return
}
if (presence.type == QBPresence.Type.online) {
    // user is online
} else {
    // user is offline
}

Add user to your contact list

To add a user to the contact list, use the following snippet.

try {
    contactsRoster.subscribe(user.getId());
} catch (SmackException.NotConnectedException e) {

}
try {
    contactsRoster.subscribe(user.id)
} catch (e: SmackException.NotConnectedException) {

}

After that, the User you have just subscribed to, receives a callback subscriptionRequested in QBSubscriptionListener. This is a request to be added to the contact list.

// QBSubscriptionListener

// ...

@Override
public void subscriptionRequested(int userId) {

}
// QBSubscriptionListener()

// ...

@Override
public void subscriptionRequested(int userId) {

}

📘

Pay attention

Maximum number of contacts is 300.

Confirm the contact request

To confirm the request, use contactsRoster.confirmSubscription() method.

try {
    contactsRoster.confirmSubscription(user.getId());
} catch (SmackException.NotConnectedException | SmackException.NotLoggedInException | SmackException.NoResponseException | XMPPException e) {

}
try {
    contactsRoster.confirmSubscription(user.id)
} catch (e: SmackException.NotConnectedException) {

} catch (e: SmackException.NotLoggedInException) {

} catch (e: SmackException.NoResponseException) {

} catch (e: XMPPException) {

}

Reject the contact request

To reject the request, use the contactsRoster.reject() method.

try {
    contactsRoster.reject(user.getId());
} catch (SmackException.NotConnectedException e) {

}
try {
    contactsRoster.reject(user.id)
} catch (e: SmackException.NotConnectedException) {

}

Remove user from the contact list

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

try {
    contactsRoster.unsubscribe(user.getId());
} catch (SmackException.NotConnectedException e) {

}
try {
    contactsRoster.unsubscribe(user.id)
} catch (e: SmackException.NotConnectedException) {

}

Contact list updates

The above-specified RosterListener listener will give you all 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, delete privacy lists or define a default list.

📘

Note

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 are specified, then the list with a given name will be deleted.

QBPrivacyListsManager privacyListsManager = QBChatService.getInstance().getPrivacyListsManager();

QBPrivacyList privacyList = new QBPrivacyList();
privacyList.setName("My_Privacy_List");

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

QBPrivacyListItem item = new QBPrivacyListItem();
item.setAllow(false);
item.setType(QBPrivacyListItem.Type.USER_ID);
item.setValueForType(String.valueOf(qbUser.getId()));

items.add(item);

privacyList.setItems(items);

try {
    privacyListsManager.createPrivacyList(privacyList);
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException e) {

}
val privacyListsManager = QBChatService.getInstance().privacyListsManager

val privacyList = QBPrivacyList()
privacyList.name = "My_Privacy_List"

val items = ArrayList<QBPrivacyListItem>()

val item = QBPrivacyListItem()
item.isAllow = false
item.type = QBPrivacyListItem.Type.USER_ID
item.valueForType = qbUser.id.toString()

items.add(item)

privacyList.items = items

try {
    privacyListsManager.createPrivacyList(privacyList)
} catch (e: SmackException.NotConnectedException) {

} catch (e: SmackException.NoResponseException) {
    
} catch (e: XMPPException) {
    
}

The QBPrivacyListItem class takes 4 arguments:

  • type - use USER_ID to block a user in a 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 or false.
  • mutualBlock - can be true or false to block user's message in both directions or not.

📘

Note

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("My_Privacy_List");
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException e) {

}
try {
    privacyListsManager.applyPrivacyList("My_Privacy_List")
} catch (e: SmackException.NotConnectedException) {

} catch (e: SmackException.NoResponseException) {
    
} catch (e: XMPPException) {
    
}

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 a new privacy list instead of the current one, you should decline the 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("New_Privacy_List");
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException e) {

}
// deactivate active list
try {
    privacyListsManager.declinePrivacyList()
} catch (e: SmackException) {

} catch (e: XMPPException.XMPPErrorException) {
}

// create new list
// ...

// activate again active list
try {
    privacyListsManager.applyPrivacyList("New_Privacy_List")
} catch (e: SmackException.NotConnectedException) {

} catch (e: SmackException.NoResponseException) {
    
} catch (e: XMPPException) {
    
}

Retrieve privacy lists

To get a list of all your privacy lists names, use the following request.

QBPrivacyListsManager privacyListsManager = QBChatService.getInstance().getPrivacyListsManager();

// get all privacy lists
List<QBPrivacyList> lists = new ArrayList<>();

try {
    lists = privacyListsManager.getPrivacyLists();
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException e) {

}
val privacyListsManager = QBChatService.getInstance().privacyListsManager

// get all privacy lists
var lists: List<QBPrivacyList> = ArrayList()

try {
    lists = privacyListsManager.privacyLists
} catch (e: SmackException.NotConnectedException) {

} catch (e: SmackException.NoResponseException) {

} catch (e: XMPPException) {

}

Retrieve privacy list by name

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

QBPrivacyListsManager privacyListsManager = QBChatService.getInstance().getPrivacyListsManager();

// get privacy list by name
QBPrivacyList privacyList = new QBPrivacyList();
try {
    privacyList = privacyListsManager.getPrivacyList("New_Privacy_List");
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException e) {

}
val privacyListsManager = QBChatService.getInstance().privacyListsManager

// get privacy list by name
var privacyList = QBPrivacyList()
try {
    privacyList = privacyListsManager.getPrivacyList("New_Privacy_List")
} catch (e: SmackException.NotConnectedException) {

} catch (e: SmackException.NoResponseException) {

} catch (e: XMPPException) {

}

Remove privacy list

To delete a list, you can call a method below or you can edit a list and set items to nil.

QBPrivacyListsManager privacyListsManager = QBChatService.getInstance().getPrivacyListsManager();

try {
    privacyListsManager.declinePrivacyList();
    privacyListsManager.deletePrivacyList("New_Privacy_List");
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException e) {

}
val privacyListsManager = QBChatService.getInstance().privacyListsManager

try {
    privacyListsManager.declinePrivacyList()
    privacyListsManager.deletePrivacyList("New_Privacy_List")
} catch (e: SmackException.NotConnectedException) {

} catch (e: SmackException.NoResponseException) {

} catch (e: XMPPException) {

}

🚧

Note

Before deleting the privacy list, you should decline it.

Blocked user attempts to communicate with user

A user can be blocked in 1-1 dialog and group dialog. In this case, the blocked user receives an error when trying to send a message in a 1-1 dialog and receives nothing when trying to send a message in group dialog.

QBChatMessage qbChatMessage = new QBChatMessage();
qbChatMessage.setBody("I am blocked. I am trying to send message to you");

try {
    privateDialog.sendMessage(qbChatMessage);
} catch (SmackException.NotConnectedException e) {
    e.printStackTrace();
}

privateDialog.addMessageListener(new QBChatDialogMessageListener() {
    @Override
    public void processMessage(String dialogID, QBChatMessage qbChatMessage, Integer integer) {
        // When we received a message from dialog
    }

    @Override
    public void processError(String dialogID, QBChatException e, QBChatMessage qbChatMessage, Integer senderID) {
        // When we received an error from dialog
        e.printStackTrace();
    }
});
val qbChatMessage = QBChatMessage()
qbChatMessage.setBody("I am blocked. I am trying to send message to you")

try {
    privateDialog.sendMessage(qbChatMessage)
} catch (e: SmackException.NotConnectedException) {
    e.printStackTrace()
}

privateDialog.addMessageListener(object : QBChatDialogMessageListener() {
    override fun processMessage(dialogID: String?, qbChatMessage: QBChatMessage?, integer: Int?) {
    // When we received a message from dialog
    }

    override fun processError(dialogID: String?, e: QBChatException?, qbChatMessage: QBChatMessage?, senderID: Int?) {
        // When we received an error from dialog
        e?.printStackTrace()
    }
})

Updated about a month ago


What's Next

Video Calling

Advanced


Learn how to manage message statuses, attachments, contact list, offline messaging, and privacy list.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.