Introduction
QuickBlox Chat is a quick and reliable chat solution which combines benefits of scalable cloud hosted XMPP chat server, seamless Single Sign-On authorization via Users, incoming IM / chat alerts via Push Notifications and file attachments via Content.
SDKs and code samples are available for iOS, Android, Windows Phone, BlackBerry 5-7 and BB10, also Web and desktop – QuickBlox Chat is the best and most comprehensive solution so far to have your users communicate cross-platform.
Features
Robust, quick, ‘keep-alive’ connection. Unlimited concurrent connections thanks to QuickBlox auto-scalable AWS powered cloud chat servers infrastructure.
- 1:1 chat (private user to user chat / IM)
- Group chat (unlimited chat rooms)
- Incoming chat alerts (push notifications) for offline users (via Messages)
- File attachments - cloud hosted via Content so both users don’t have to be online for the transfer to take place. XMPP p2p file transfers are also supported. Allow users to send photos, videos and other files.
- Location based chat – integrated with Location, have your users chat over map (Google Map, Apple maps, Bing) and see distance to each other, hide or share their location, see internal or Facebook check-ins of other users, manage POIs
- Voice chat / call – enable 1:1 voice calls in your app
- Video chat / call – best video chat SDK for your app
- NAT traversal – our TURN server and optimization system take care of NAT traversal and traffic compression making sure your chat, voice and video traffic reaches all users across networks with different configurations
XMPP features supported
All standard XMPP libraries are supported (please check the list here http://xmpp.org/xmpp-software/libraries/). All standard XEPs and the following additional ones (below) are supported:
- RFC-6120 - http://xmpp.org/rfcs/rfc6120.html - Core: SSL/TLS stream encryption, SASL authentication, Resource binding etc
- RFC-6121 - http://xmpp.org/rfcs/rfc6121.html - Instant Messaging and Presence
- XEP-0016 - http://xmpp.org/extensions/xep-0016.html - Privacy Lists
- XEP-0203 - http://xmpp.org/extensions/xep-0203.html - Offline Message Storage
- XEP-0280 - http://xmpp.org/extensions/xep-0280.html - Message Carbons
- XEP-0198 - http://xmpp.org/extensions/xep-0198.html - Stream Management
- XEP-0085 - http://xmpp.org/extensions/xep-0085.html - Chat State Notifications
- XEP-0079 - http://xmpp.org/extensions/xep-0079.html - Advanced Message Processing
- XEP-0045 - http://xmpp.org/extensions/xep-0045.html - Multi User Chat - our server is @muc.chat.quickblox.com.
- XEP-0047 - http://xmpp.org/extensions/xep-0047.html - In-Band Bytestreams (p2p file transfer)
- XEP-0333 - http://xmpp.org/extensions/xep-0333.html - Chat Markers
- XEP-0308 - http://xmpp.org/extensions/xep-0308.html - Last Message Correction
- XEP-0174 - http://xmpp.org/extensions/xep-0174.html - Serverless Messaging
- XEP-0237 - http://xmpp.org/extensions/xep-0237.html - Roster Versioning
- XEP-0012 - http://xmpp.org/extensions/xep-0012.html - Last Activity
- XEP-0352 - http://xmpp.org/extensions/xep-0352.html - Client State Indication
- XEP-0202 - http://xmpp.org/extensions/xep-0202.html - Entity Time
- XEP-0033 - http://xmpp.org/extensions/xep-0033.html - Extended Stanza Addressing (not supported yet)
- XEP-0334 - http://xmpp.org/extensions/xep-0334.html - Message Processing Hints (not supported yet)
XEP-0095 & XEP-0096 are not supported, instead QuickBlox own TURN server takes care of NAT traversal for voice and video traffic streaming.
Connecting to server
Note: these settings are already integrated into iOS/Android/Web SDKs and code samples so you may ignore this section if you’re iOS/Android/Web developer.
Server
Main server: chat.quickblox.com.
MUC (Multi Users Chat): muc.chat.quickblox.com.
Important: users registration, authentication and removal must be done via Users API (and not XMPP).
Login / ID
In order to login to chat you have to create a user. You can do it on QuickBlox dashboard or via API.
Each user gets a JID (Jabber ID) in the following format:
<user_id>-<app_id>@chat.quickblox.com
Note: JID is assigned automatically provided users has authenticated at least once in the context of this application. Also note that users will have different JIDs for different apps. For example, user freddy (user_id = 128) chats in both Gunslinger (application_id = 44) and Shoot-a-Zombie (application_id = 78), he will get the following JIDs: 128-44@chat.quickblox.com, 128-78@chat.quickblox.com.
Password
Your user’s password for XMPP connection depends on what type of user authentication via Users you have applied for this particular user:
- standard login+password authentication: use same password
- Facebook/Twitter/Twitter Digits/Custom Identity Provider: use QuickBlox session token as password:
QBUUser *user = [QBUUser user]; user.ID = 47892; user.password = [QBSession currentSession].token;
QBUser user = new QBUser(); user.setId(47892); try { user.setPassword(QBSessionManager.getInstance().getToken()); }catch(Exception e) { e.printStackTrace(); // means you have not created a session before }
var session = QB.service.getSession(); var params = {userId: session.user_id, password: session.token};
Server-side chat history
Chat introduces a very simple server-side chat history functionality. This features is useful for many cases such as moderation, restoring messages on a new device via REST, making chat logs be easily downloadable, etc. We (Quickblox) are not able to read your messages - only you, as the account owner, have access to them.
Just by adding a few custom parameters to your XMPP messages, the messages will be stored on the server (in a Custom Objects like format).
Note: By using Chat 2.0, you are not automatically storing your messages. Also a dialog entity won't be created/updated without saving a message to history.
See below for how to enable server-side chat history in the iOS and Android SDK.
QBChatMessage *message = [QBChatMessage message]; ... [message setCustomParameters:@{@"save_to_history": @YES}]; ...
QBChatMessage chatMessage = new QBChatMessage(); ... chatMessage.setProperty("save_to_history", "1"); ...
QB.chat.send(jid, { ... extension: {save_to_history: 1} ... });
The correctly formatted XML message will look something like this:
<message id="1114269126" to="11492_53fc460b515c128132016675@muc.chat.quickblox.com" type="groupchat"> <body xmlns="jabber:client">This is the message text!</body> <extraParams xmlns="jabber:client"> <save_to_history>1</save_to_history> <date_sent>1409146118</date_sent> </extraParams> </message>
It doesn't matter what is the value of save_to_history parameter. Chat server just checks a presence of it.
You'll notice there's also a date_sent
field in the extra parameters. This is optional - if you don't supply it, the server will automatically add it when it receives the message. But if for example, you need to "resend" a message that failed, you can use this field to specify the correct time. It is in a unix timestamp format.
You can then view this history in the dashboard, or you can retrieve messages via the REST API.
REST API
Chat REST API provides an access to Chat history. We operate with 2 models: Chat Dialog and Chat Message.
Dialog model
Chat Dialog model describes a dialog entity between users (1-1 chat or group chat). Dialog can have custom parameters (described here)
Fields:
Field name | Type | Description | Value Example |
---|---|---|---|
_id | ObjectID | ID of dialog. Generated automatically by server after dialog creation | 53a1be95e4b08a80c999dccd |
user_id | Integer | ID of dialog's owner. | 4523 |
created_at | Integer | Integer (contains Unix timestamp - date & time when record was updated, filled automatically) | 1344256366 |
updated_at | Integer | Integer (contains Unix timestamp - date & time when record was created, filled automatically) | 1344256366 |
type | Enum | Type of dialog. Possible values: 1(PUBLIC_GROUP), 2(GROUP), 3(PRIVATE) | 2 |
name | String | Name of a group chat. Make sense if type=1(PUBLIC_GROUP) or 2(GROUP) | Chat with Bob, Sam, Garry |
photo | String | Photo of a group chat. Make sense if type=1(PUBLIC_GROUP) or 2(GROUP). Can contain a link to a file in Content module, Custom Objects module or just a web link | 454533 |
xmpp_room_jid | String | JID of XMPP room for group chat to connect. Nil if type=3(PRIVATE). Generated automatically by server after dialog creation | 92_53a1bdaf535c12eae7000dd1 @muc.chat.quickblox.com |
occupants_ids | Array of UInteger | Array of users' IDs - dialog occupants. Does not make sense if type=1(PUBLIC_GROUP) | 44,7893,4567 |
last_message | String | Last sent message in this dialog | Is anybody here? |
last_message_date_sent | Timestamp | Timestamp of last sent message in this dialog | 1403174078 |
last_message_user_id | UInteger | ID of user who sent last message in this dialog | 45643 |
unread_messages_count | Integer | Number of unread messages in this dialog for current user. | 12 |
Message model
Chat Message model describes a chat message in a dialog
Fields:
Field name | Type | Description | Value Example |
---|---|---|---|
_id | ObjectID | ID of message. Generated automatically by server after message creation | 43a1be9554b08a87c999d8cd |
created_at | Integer | Integer (contains Unix timestamp - date & time when record was updated, filled automatically) | 1344256366 |
updated_at | Integer | Integer (contains Unix timestamp - date & time when record was created, filled automatically) | 1344256366 |
chat_dialog_id | ObjectID | ID of dialog to which current message is connected. Generated automatically by server after message creation | 63a18e95e4308a80c993dccd |
message | String | Message body | Is anybody here? |
date_sent | Timestamp | Message date sent | 1403174078 |
sender_id | UInteger | Message sender ID | 564444 |
recipient_id | UInteger | Message recipient ID | 39572 |
(deprecated) read | Boolean | Flag which indicates was this message read or not by opponent. Will be always 0 for the group chat. | 1 |
read_ids | Array of integers | Array of users' ids who read the messages | [5,6,23] |
delivered_ids | Array of integers | Array of users' ids who received the messages | [7,8,23] |
attachments | Array of attachments objects | Each attachment object contains 3 keys:type(audio/video/image), id(link to file ID in QuickBlox), url(link to file in Internet) | [{"type":"video","id":"12312"},{"type":"audio","url":"http://mysite.com/audio.wav"}] |
Custom parameters | Key-value | Chat message can contain any other user custom parameters | age=25 |
API requests
URL | HTTP Verb | Action Description | Success HTTP Status Code |
---|---|---|---|
/chat/Dialog | GET | Retrieve dialogs | 200 |
/chat/Dialog | POST | Create dialog | 201 |
/chat/Dialog/{id} | PUT | Update dialog | 200 |
/chat/Dialog/{id1},{id2},{id3}... | DELETE | Delete dialog | 200 |
/chat/Dialog/{id}/notifications.json | PUT | Update notifications settings | 200 |
/chat/Dialog/{id}/notifications.json | GET | Get notifications settings | 200 |
/chat/Message | GET | Retrieve messages | 200 |
/chat/Message/unread | GET | Retrieve unread messages count | 200 |
/chat/Message | POST | Create message | 201 |
/chat/Message/{id1},{id2},{id3}...?chat_dialog_id={id} | PUT | Update message | 200 |
/chat/Message/{id1},{id2},{id3}... | DELETE | Delete message | 200 |
Retrieve dialogs
Get all dialogs associated with current user. Server will return all dialogs where current user id is in occupants_ids field OR if type=1(PUBLIC_GROUP). To detect current user id server uses session token.
Search also available for custom parameters (described here).
Parameters
Operator | Applied fields | Description | Usage example |
---|---|---|---|
{field_name} | _id, type, name, last_message_date_sent, created_at, updated_at | Search records with field which contains exactly specified value | type=2 |
{field_name}[{search_operator}] | _id, type, name, last_message_date_sent, created_at, updated_at | Search record with field which contains value according to specified value and operator. Possible filters: lt (Less Than operator), lte (Less Than or Equal to operator), gt (Greater Than operator), gte (Greater Than or Equal to operator), ne (Not Equal to operator), in (Contained IN array operator), nin (Not contained IN array), all (ALL contained IN array), ctn (Contains substring operator) |
type[in]=1,2 |
limit | standalone operator | Limit search results to N records. Useful for pagination. Default value - 100 | limit=50 |
skip | standalone operator | Skip N records in search results. Useful for pagination. Default (if not specified): 0 | skip=50 |
count | standalone operator | Count search results. Response will contain only count of records found | count=1 |
sort_desc/sort_asc | last_message_date_sent | Search results will be sorted by specified field in ascending/descending order | sort_desc=last_message_date_sent |
Request
curl -X GET -H "QB-Token: 4d617908bf432bd0a72e2e089ed500e76a2c1a3b" https://api.quickblox.com/chat/Dialog.json
Response
{ "limit" : 100, "skip" : 0 "items" : [ { "_id" : "53a2bd40e4b0ffe278f44a66", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "last_message" : "Is anybody here?", "last_message_date_sent" : 1403606412, "last_message_user_id" : 299, "name" : null, "photo" : null, "occupants_ids" : [ 298, 299 ], "type" : 3, "unread_messages_count" : 0, "xmpp_room_jid" : null }, { "_id" : "53a970c5535c123fed00053b", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "last_message" : "Hey guys!", "last_message_date_sent" : "1403550532", "last_message_user_id" : 299, "name" : "Chat with Sam, Bob, Garry", "photo" : "567681", "occupants_ids" : [ 290, 299, 3105 ], "type" : 2, "unread_messages_count" : 5, "xmpp_room_jid" : "92_53a970c5535c123fed00053b@muc.chat.quickblox.com" } ] }
Create dialog
Use type=1(PUBLIC_GROUP) to create a public group dialog. All the users from your application will be able to join it. Server will create a public group chat and return a detailed information about newly created dialog. Field xmpp_room_jid will contain a Chat room JID to which you should connect to start chatting.
Use type=2(GROUP) to create a group dialog only for specific users provided in occupants_ids.
Server will create an only members group chat and return a detailed information about newly created dialog. Field xmpp_room_jid will contain a Chat room JID to which you should connect to start chatting.
Use type=3(PRIVATE) to create a private dialog between 2 users. Server will return a detailed information about newly created dialog. If user sends a chat message to some user and private dialog wasn't created - it will be created automatically with 1st chat message.
Parameters
Parameter | Required | Description | Usage example |
---|---|---|---|
type | Yes | Type of new dialog. Possible values:
|
type=2
|
occupants_ids | Yes if type=2(GROUP) or 3(PRIVATE) | IDs of dialog occupants - users, who will be able to chat in this dialog. Don't need to pass current user ID - it will be added automatically | occupants_ids=56,558,12334
|
name | Yes (except when type=3 (PRIVATE) | Name of a new dialog. Ignored when type=3(PRIVATE) | name=Chat with Bob, Sam, Garry
|
photo | No | Photo of a new dialog. Ignored when type=3(PRIVATE) | photo=67834
|
Request
curl -X POST \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ -d '{"type": 2, "name": "Chat with Bob, Sam, Garry", "occupants_ids": "55,678,22"}' \ https://api.quickblox.com/chat/Dialog.json
Response
{ "_id": "53aaa06f535c12cea9007496", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "last_message": null, "last_message_date_sent": null, "last_message_user_id": null, "name": "Chat with Bob, Sam, Garry", "photo": null, "occupants_ids": [ 55, 678, 22 ], "type": 2, "xmpp_room_jid": "92_53aaa06f535c12cea9007496@muc.chat.quickblox.com", "unread_messages_count": 0 }
Custom parameters
Dialogs can store additional parameters. These parameters can be used to store an additional data. Also these parameters can be used in dialogs retrieval requests.
To start use additional parameters it needs to create an additional schema of your parameters. This is a CustomObjects class. Just create an empty class with all needed fields. These fields will be your dialog additional parameters.
Next, to set additional parameters to a dialog use next additional parameters in a creation request:
- data[class_name] - should contain CustomObjects class name created above
- data[field1]
- data[...]
- data[fieldN]
Set custom parameters
For example, we have class "CoolDialog" with string field "category". Next request will create a dialog with the custom parameter category and the value friends:
curl -X POST \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ -d '{"type": 2, "name": "Chat with Bob, Sam, Garry", "occupants_ids": "55,678,22", "data" : { "class_name" : "CoolDialog", "category" : "friends" }' \ https://api.quickblox.com/chat/Dialog.json
Filter dialogs by custom parameters
Dialogs can be filtered through custom parameters. For example, request for dialogs with parameter category=friends:
curl -X GET -d "data[class_name]=CoolDialog&data[category]=friends" -H "QB-Token: 4d617908bf432bd0a72e2e089ed500e76a2c1a3b" https://api.quickblox.com/chat/Dialog.json
Update dialog
Update a dialog.
The following rules are applied if dialog's type is 2(GROUP):
- Any user from occupants_ids can add other users.
- Any user from occupants_ids can remove only himself.
- Only dialog's creator(owner) can remove any users from occupants_ids.
The following rules are applied if dialog's type is 1(PUBLIC_GROUP):
- Only dialog’s owner can update it.
Fields to update
Field | Available operators | Description | Usage example |
---|---|---|---|
occupants_ids | pull_all,push_all | Update dialog occupants. Use push_all operator to add new occupants. Use pull_all to remove occupants |
push_all[occupants_ids][]=55,56 pull_all[occupants_ids][]=22,23 |
name | Name of the dialog | name=Chat with Garry and John | |
photo | Photo of the dialog | photo=674 |
Update custom parameters
To update additional parameters in a dialog use next parameters in a request:
- data[class_name]=... - should contain CustomObjects class name created before
- data[field1]=value1
- data[...]
- data[fieldN]=valuen
Request
curl -X PUT \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ -d '{"name": "Chat with Garry and John", "pull_all": {"occupants_ids": [22]}}' \ https://api.quickblox.com/chat/Dialog/53aac0cd535c12b50600962c.json
Response
{ "_id": "53aac0cd535c12b50600962c", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "last_message": null, "last_message_date_sent": null, "last_message_user_id": null, "name": "Chat with Bob, Sam, Garry", "photo": null, "occupants_ids": [ 55, 678, ], "type": 2, "xmpp_room_jid": "92_53aac0cd535c12b50600962c@muc.chat.quickblox.com", "unread_messages_count": 0 }
Delete dialog
Delete chat dialog.
- Each user from dialog’s occupant_ids field can remove the dialog. This doesn’t mean that this dialog will be removed completely for all the users in this dialog. It will be removed only for current user.
- To completely remove a dialog - pass force=1. Only owner can do it.
Request
curl -X DELETE \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ https://api.quickblox.com/chat/Dialog/53aabe15e4b077ddd43e7fd6,23aabe15e4b077ddd43e7fd1.json
Response
In a case of deletion single dialog:
200 OK (empty body)
In a case of deletion multiple dialogs:
{ "SuccessfullyDeleted": { "ids": [ "53aabe15e4b077ddd43e7fd6" ] }, "WrongPermissions": { "ids": [] }, "NotFound": { "ids": [ "23aabe15e4b077ddd43e7fd1" ] } }
Update notifications settings
User can turn on/off push notifications for offline messages in a dialog. Default value is ON. By default when a user is offline and other user sent a message to him then he will receive a push notification. It is possible to disable this feature.
Request
curl -X PUT \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ -d '{"enabled":"0"}' \ https://api.quickblox.com/chat/Dialog/56c2e338a28f9a9ebe00017d/notifications.json
Response
{ "notifications": { "enabled": 0 } }
Get notifications settings
User can turn on/off push notifications for offline messages in a dialog. You can get the status of this option via this API.
Request
curl -X GET \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ https://api.quickblox.com/chat/Dialog/56c2e338a28f9a9ebe00017d/notifications.json
Response
{ "notifications": { "enabled": 1 } }
Retrieve messages
Retrieve all chat messages within particular dialog. It's only possible to read chat messages in dialog if current user id is in occupants_ids field or if dialog's type=1(PUBLIC_GROUP). Server will return dialog's chat messages sorted ascending by date_sent field.
All retrieved chat messages will be marked as read after request.
Parameters
Operator | Applied fields | Description | Usage example |
---|---|---|---|
{field_name} | _id, message, date_sent, sender_id, recipient_id, attachments.type, updated_at | Search records with field which contains exactly specified value | sender_id=2960 |
{field_name}[{search_operator}] | _id, message, date_sent, sender_id, recipient_id, attachments.type, updated_at | Search record with field which contains value according to specified value and operator. Possible filters: lt (Less Than operator), lte (Less Than or Equal to operator), gt (Greater Than operator), gte (Greater Than or Equal to operator), ne (Not Equal to operator), in (Contained IN array operator), nin (Not contained IN array), all (ALL contained IN array), or (OR operator), ctn (Contains substring operator) |
sender_id[in]=134,2566 |
limit | standalone operator | Limit search results to N records. Useful for pagination. Default value - 100 | limit=50 |
skip | standalone operator | Skip N records in search results. Useful for pagination. Default (if not specified): 0 | skip=50 |
count | standalone operator | Count search results. Response will contain only count of records found | count=1 |
sort_desc/sort_asc | date_sent | Search results will be sorted by specified field in ascending/descending order | sort_desc=date_sent |
mark_as_read | Do not mark the received messages as read | mark_as_read=0 |
Request
curl -X GET -H "QB-Token: 4d617908bf432bd0a72e2e089ed500e76a2c1a3b" \ https://api.quickblox.com/chat/Message.json?chat_dialog_id=53aadc78535c127f15009b6c
Response
{ "skip": 0, "limit": 100, "items": [ { "_id": "53aadcc7e4b077ddd43e804d", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "attachments": [], "read_ids": [2792283,4374458], "delivered_ids": [2792283,4374458], "chat_dialog_id": "53aadc78535c127f15009b6c", "date_sent": 1403706567, "message": null, "recipient_id": null, "sender_id": 298, "read": 1 }, { "_id": "53aadcc8e4b077ddd43e804f", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "attachments": [], "read_ids": [2792283,4374458], "delivered_ids": [2792283,4374458], "chat_dialog_id": "53aadc78535c127f15009b6c", "date_sent": 1403706568, "message": null, "recipient_id": null, "sender_id": 298, "read": 1 }, { "_id": "53aadcd0e4b077ddd43e8051", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "attachments": [], "read_ids": [2792283,4374458], "delivered_ids": [2792283,4374458], "chat_dialog_id": "53aadc78535c127f15009b6c", "date_sent": 1403706577, "message": null, "recipient_id": null, "sender_id": 298, "read": 1 } ] }
Retrieve unread messages count
Retrieve an unread count of your chat messages, split across dialogs or just a total value.
Parameters
Operator | Description | Usage example |
---|---|---|
chat_dialog_ids | Array of dialogs ids to get a count of unread messages for. You also can omit this parameter to receive just a total count of all unread messages | chat_dialog_ids=53aadc78535c127f15009b6c,23aadc78535c127f15009b64 |
Request
curl -X GET -H "QB-Token: 4d617908bf432bd0a72e2e089ed500e76a2c1a3b" \ https://api.quickblox.com/chat/Message/unread.json?chat_dialog_ids=53aadc78535c127f15009b6c,23aadc78535c127f15009b64
Response
{ "total": 3, "55ba0b3c535c12f7a4001f13": 1, "55ba0b3e535c12a0e60032c4": 0 }
Create message
Create a chat message. It’s possible to inject a new chat message to the chat history. In this case this new message won't be delivered to the recipient(s) by XMPP real time transport, it will be just added to the history. If you want to initiate a real 'send to chat' - pass send_to_chat=1 parameter.
Fields to set
Parameter | Required | Description | Usage example |
---|---|---|---|
chat_dialog_id | yes if the recipient_id key is not specified | ID of a dialog to which this messages will be added | chat_dialog_id=53db8798535c125e8e000902 |
message | no | text of the message (CGI-escaped) | message=hello! |
recipient_id | yes if the chat_dialog_id key is not specified | ID of a recipient. Useful only when dialog's type=3(PRIVATE) | recipient_id=4124234 |
attachments[n][type/id/url] | no | Array of attachments objects. Each attachment object contains 3 keys:type(audio/video/image/...), id(link to file ID in QuickBlox), url(link to file in Internet) | attachments[0][id]=47863&attachments[0][type]=image&attachments[1][url]=www.mysite.com/image.png&attachments[1][type]=image |
Custom parameters | no | Key-value parameters. Chat message can contain any other custom parameters | age=25 |
send_to_chat | no | Sends a message to chat | send_to_chat=1 |
markable | no | Mark the messages to support read/delivered statuses | markable=1 |
Request
curl -X POST \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ -d '{"chat_dialog_id": "53a99a7be4b094c7c6d31b41", "message": "hello!", "recipient_id": 343,"attachments": {"0": {"type": "image", "id": "47863"}, "1": {"type": "image", "id": "47863"} }, "age": "25"}' \ https://api.quickblox.com/chat/Message.json
Response
{ "_id":"53e8a3a4535c1242aa0270b9", "created_at": "2016-03-23T17:00:42Z", "updated_at": "2016-03-23T17:00:42Z", "age":"25", "attachments":[{"id":"47863","type":"image"}], "read_ids": [], "delivered_ids": [], "chat_dialog_id":"53db8798535c125e8e000902", "date_sent":1407755172, "message":"hello!", "recipient_id":343, "sender_id":1279282 }
Update message
Update chat message.
It's possible to mark all messages as read/delivered - just don't pass a message id.
Fields to update
Field | Description | Usage example |
---|---|---|
read | Mark message as read | read=1/0 |
delivered | Mark message as delivered | delivered=1 |
message | Update message's text | message=HelloWorld |
Request
curl -X PUT \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ -d '{"read": "1", "chat_dialog_id": "53a99a7be4b094c7c6d31b41"}' \ https://api.quickblox.com/chat/Message/53aabe15e4b077ddd43e7fd3.json
Response
Status 200 OK
Delete message
Removes a chat message for the current user
Any user in the dialog’s occupant_ids
is able to remove a message from the dialog. The message will only be removed for the current user - the message will still be viewable and in the chat history for all other users in the dialog.
- You may be wondering why this request only deletes the message for the current user. It is to allow deletion functionality within your app and ensuring the message does not reappear in their chat history, but without affecting the history of other users.
- It is possible to completely remove a message by owner - pass force=1
Request
curl -X DELETE \ -H "Content-Type: application/json" \ -H "QB-Token: eddf864695d72d33b959eec2ae6c640d817dfada" \ https://api.quickblox.com/chat/Message/53aabe15e4b077ddd43e7fd3,53aabe15e4b077ddd43e7fd6.json
Response
Status 200 OK
System Notifications
There is a special channel for any system notifications. The end user can use it to split regular chat messages and other system events.
All such messages should contain extraParams.moduleIdentifier=SystemNotifications and use type=headline.
Format:
<message id="..." type="headline" to="...@chat.quickblox.com"> <extraParams xmlns="jabber:client"> <moduleIdentifier>SystemNotifications</moduleIdentifier> <param1>value1</param1> <param2>value2</param2> ... </extraParams> </message>
Stream management
Stream management (XEP-0198) defines an XMPP protocol extension for active management of an XML stream between two XMPP entities, including features for stanza acknowledgements and stream resumption.
The basic concept behind stream management is that the initiating entity (either a client or a server) and the receiving entity (a server) can exchange "commands" for active management of the stream. The following stream management features are of particular interest because they are expected to improve network reliability and the end-user experience:
- Stanza Acknowledgements -- the ability to know if a stanza or series of stanzas has been received by one's peer.
- Stream Resumption -- the ability to quickly resume a stream that has been terminated.
The main interesting part here is Stanza Acknowledgements because it allows to achieve 100% reliability.
To better understand how it works we prepared next picture:
QuickBlox Chat server does support stream management, both Stanza Acknowledgements and Stream Resumption. More info how it works you can check in xep-0198 extention page.
Use SDKs sections to check platform support.
XML stanza formats
Send/Receive a message
Send message format:
<message id="54789d5e6df5e6f921b7acda" type="groupchat" to="92_54789d40535c12b1a5001172@muc.chat.quickblox.com"> <body>Nice to met you!</body> <extraParams xmlns="jabber:client"> <save_to_history>1</save_to_history> </extraParams> </message>
Receive message format:
<message xmlns="jabber:client" from="92_54789d40535c12b1a5001172@muc.chat.quickblox.com/1501966" to="1501966-92@chat.quickblox.com/0C1E1229-6B3C-47F3-BFDC-D1CFD351D274" type="groupchat" id="54789d5e6df5e6f921b7acda"> <body>Nice to met you!</body> <extraParams xmlns="jabber:client"> <save_to_history>1</save_to_history> <message_id>54789d5e6df5e6f921b7acda</message_id> <dialog_id>54789d40535c12b1a5001172</dialog_id> </extraParams> </message>
As you can see, server automatically adds the message_id and dialog_id of a message from history, so a recipient knows this data.
File attachments
Each attachment should be included into extraParams part of a message.
Each attachment contains next attributes:
- type - type of the attachment. Could be any. Recommended values: video, audio, photo
- id (optional)- link to a file, for example ID of a file in Content or Custom Objects modules
- url (optional) - url to a file in the Internet
<message id="546dbf438c54ad2aded63b25" type="groupchat" to="2_546d14c19c29532398000496@muc.chat.quickblox.com"> <body>Nice to met you!</body> <extraParams xmlns="jabber:client"> <save_to_history>1</save_to_history> <attachment type="video" id="47863"></attachment> <attachment type="photo" url="..."></attachment> </extraParams> </message>
'Is typing' status
A type can be chat or groupchat.
<message id="55e416e3854516bc190041a8" type="chat" to="4374458-92@chat.quickblox.com"> <composing xmlns="http://jabber.org/protocol/chatstates"/> </message>
<message id="55e4175a854516bc190041a9" type="chat" to="4374458-92@chat.quickblox.com"> <paused xmlns="http://jabber.org/protocol/chatstates"/> </message>
Delivered status
A type can be only chat.
<message to="2308497-92@chat.quickblox.com" type="chat" id="55e821cd0ce78744090041b2"> <received xmlns="urn:xmpp:chat-markers:0" id="55e818f6e24a0998640041ed"/> <extraParams xmlns="jabber:client"> <dialog_id>55e6a9c8a28f9a3ea6001f15</dialog_id> </extraParams> </message>
Read status
A type can be only chat.
<message to="2308497-92@chat.quickblox.com" type="chat" id="55e821cd0ce78744090041b2"> <displayed xmlns="urn:xmpp:chat-markers:0" id="55e818f6e24a0998640041ed"/> <extraParams xmlns="jabber:client"> <dialog_id>55e6a9c8a28f9a3ea6001f15</dialog_id> </extraParams> </message>
Dashboard
Chat 2.0 provides a really powerful way to manage Chat history in Dashboard. Go to admin panel, Chat module. There are 2 new tabs: Dialogs and Alerts.
Dialogs
Dialogs tab contains all dialogs in your application, with next columns:
- id - ID of a dialog
- type - Type of a dialog: PRIVATE, GROUP or PUBLIC GROUP
- name - Name of a dialog
- occupants ids - Users IDs who chat in this dialog
- last message - Latest sent message in this dialog
- last message user id - ID of User who sent latest message in this dialog
- room_jid - JID of XMPP room for group chat to connect. Empty if type is PRIVATE
- last message date sent - Timestamp of latest sent message in this dialog
- history - link to chat history for this dialog
You can create new dialog here or update existing one. To edit dialog just click on dialog's ID - popup with dialog's info will appear. To create a new dialog click on New Dialog button, New Dialog popup will appear:
Enter name, choose type and set occupants for this group. Then click Create button - newly created dialog will be added to the dialogs list.
History
By clicking history link in each dialog you can view chat messages in this dialog:
There are next columns:
- message - chat message body
- Sender Id - User who sent message
- Recipient Id - User who received message
- Attachments - Information about message attachments
- Custom parameters - Message custom parameters
- Date sent - Date sent of message
You can use Search box to filter messages.
Alerts
Alerts tab allows you to setup automatic push notifications for offline user. It means if your opponent is offline while you writing a message - he can automatically receive push notification.
Go to admin panel, Chat module. There is a tab Alerts.
Offline pushes only work if you use save_to_history=1 key when send messages.
There are the following settings:
- Alert text - text of your push notification
- Environment - set Push Notifications environment here
- Templates - set push notification template here. Use template variables to engage your push message
- Badge counter - set badge counter to include a counter info into your push message. Useful to include unread counter - number of unread messages user has
- Sound - set push notification sound (for iOS only)
- Category - describes "actions" that should be presented in app notification in various views (for iOS only)
- Content Available - provide this key with a value of 1 to indicate that new content is available (for iOS only)
Pushes work automatically, one thing that you need is to subscribe users to pushes using SDKs.
Payload
Here are examples of push notification payload. There are 2 additional parameters which are added automatically to each push:
- user_id - the message sender's ID
- dialog_id - the ID of a dialog in which message was sent
Other parameters are standart or configured via Dashboard:
iOS
{ aps = { alert = "Garry Bones: Hey Sam, how things are going on?", badge = 10, sound = 1, }, "dialog_id" = 55351e7fefa357af64000006, "user_id" = 1529813 }
Android
{ user_id=1529813, from=761750217637, badge=10, message=Garry Bones: Hey Sam, how things are going on?, dialog_id=55351e7fefa357af64000006, android.support.content.wakelockid=4, collapse_key=event2191 }
Use cases
All typical use cases you can find in iOS/Android chat samples:
Datetime issue
All the users in conversation have to have same date_sent value for chat messages. In additional, the same value should be stored to chat history.
To resolve this issue we recommend a flow when each user sets by himself a date_sent value when sending a message:
QBChatMessage *message = [QBChatMessage message]; ... NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"date_sent"] = @((int)[[NSDate date] timeIntervalSince1970]; ... [message setCustomParameters:params];
QBChatMessage chatMessage = new QBChatMessage(); ... long time = System.currentTimeMillis()/1000; chatMessage.setProperty("date_sent", time + ""); ...
Chat server validates this value (check a difference between client's and server's timestamps - it should not be more than 5 seconds). If a difference is less then 5 seconds - server will use client's value, otherwise - ignore client's value and use own.