diff --git a/articles/error-guide.mdx b/articles/error-guide.mdx index bcfe328e1..d227229fb 100644 --- a/articles/error-guide.mdx +++ b/articles/error-guide.mdx @@ -86,6 +86,11 @@ description: "Common error codes and their descriptions for CometChat REST APIs. | `ERR_WRONG_MESSAGE_THREAD` | Indicates conversation mismatch for parent and a new threaded message. | | `ERR_MESSAGE_THREAD_NESTING` | Indicates nested message threading. | | `ERR_WRONG_MESSAGE_THREAD_CATEGORY` | Indicates conversation mismatch for parent and a new threaded message. | +| `ERR_PINNED_MESSAGES_LIMIT_EXCEEDED` | Indicates that the conversation has reached the maximum number of pinned messages allowed. | +| `ERR_SAVED_MESSAGES_LIMIT_EXCEEDED` | Indicates that the user has reached the maximum number of saved messages allowed. | +| `ERR_PINNED_CONVERSATIONS_LIMIT_EXCEEDED` | Indicates that the user has reached the maximum number of pinned conversations allowed. | +| `ERR_SYSTEM_PINNED_CONVERSATIONS_LIMIT_EXCEEDED` | Indicates that the app has reached the maximum number of global pinned conversations allowed. | +| `ERR_SYSTEM_PINNED_CONVERSATION` | Indicates that the conversation is pinned for all users by the app and cannot be pinned or unpinned by a user. | | **Calling Errors** | | | `ERR_CALLING_SELF` | Indicates user is initiating call with himself. | | `ERR_CALL_BUSY_SELF` | Indicates initiator of the call is participant of another ongoing call. | diff --git a/chat-apis.json b/chat-apis.json index 595147810..9600e05c9 100644 --- a/chat-apis.json +++ b/chat-apis.json @@ -2826,6 +2826,86 @@ ] } }, + "/messages/{id}/interacted": { + "patch": { + "tags": [ + "Messages" + ], + "summary": "Mark Message As Interacted", + "description": "Records that a user interacted with one or more elements of an interactive message. Only messages of the interactive category can be marked, and every element ID sent must be one the message declares as interactable. Interactions are recorded per user, so the onBehalfOf header is required. Idempotent - re-sending an element that is already recorded keeps the original interactedAt.", + "operationId": "mark-message-as-interacted", + "parameters": [ + { + "$ref": "#/components/parameters/requiredonBehalfOf" + }, + { + "name": "id", + "in": "path", + "description": "Id of the message whose details are to be fetched.", + "required": true, + "schema": { + "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" + } + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "interactions" + ], + "properties": { + "interactions": { + "description": "A list of element Ids to be marked as interacted. Each ID must be one that the message declares as interactable.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Marking Message as Interacted", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/deleteSchema" + } + }, + "type": "object" + }, + "example": { + "data": { + "success": true, + "message": "The message id 7 has been marked as interacted for the user superhero1." + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, "/messages/{id}/reactions": { "get": { "tags": [ @@ -3313,294 +3393,274 @@ ] } }, - "/conversations": { - "get": { + "/messages/{id}/pin": { + "post": { "tags": [ - "Conversations" + "Messages" ], - "summary": "List conversations", - "description": "Fetching all the conversations", - "operationId": "list-all-conversations", + "summary": "Pin Message", + "description": "Pins a message in its conversation. Without the onBehalfOf header the message is pinned as the app itself (app_system); with it, the message is pinned as that user and their scope permissions apply.", + "operationId": "pin-message", "parameters": [ { "name": "onBehalfOf", "in": "header", - "description": "UID of the user on whose behalf the action is performed.\n\n\nIf onBehalfOf header is not passed,then list Conversations API will be ordered based on `uid`, `updatedAt` and then `conversationWith`\n\nIf onBehalfOf header is passed, then list Conversations API will be ordered based on `updatedAt` and then `conversationWith`.", + "description": "UID of the user to pin the message as. Leave it out to pin the message as the app itself.", "required": false, "schema": { "type": "string" } }, { - "name": "searchKey", - "in": "query", - "description": "Fetches conversations that include the specified searchKey, allowing you to search for conversations based on the name of a User or Group.", - "schema": { - "type": "string" - } - }, - { - "name": "conversationType", - "in": "query", - "description": "Retrieves only the specified conversation type (user and group) while fetching conversations list.", + "name": "id", + "in": "path", + "description": "Id of the message to pin.", + "required": true, "schema": { "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" + } } - }, - { - "name": "withTags", - "in": "query", - "description": "Includes those groups that have tags.", - "schema": { - "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Pinning a message", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/messageSchema" + } + }, + "type": "object" + }, + "example": { + "data": { + "id": "2", + "conversationId": "superhero1_user_superhero2", + "sender": "superhero1", + "receiverType": "user", + "receiver": "superhero2", + "category": "message", + "type": "text", + "data": { + "text": "Hi," + }, + "sentAt": 1700210266, + "updatedAt": 1700210266, + "pinnedBy": "app_system", + "pinnedAt": 1700210300 + } + } + } } }, - { - "name": "tags", - "in": "query", - "description": "Fetches only those groups that have these tags.", - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "type": "string" + "400": { + "description": "The conversation has reached its pinned message limit", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_PINNED_MESSAGES_LIMIT_EXCEEDED", + "message": "The number of pinned messages for the conversation with id superhero1_user_superhero2 exceeds the allowed limit of 5." + } + } } } }, - { - "name": "withUserAndGroupTags", - "in": "query", - "description": "Retrieves conversations with tags", - "schema": { - "type": "boolean" + "403": { + "description": "Pinned messages are switched off for this app, or the user may not pin", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_PERMISSION_DENIED", + "message": "Permission denied for action pinMessage with role default as per RBAC policy." + } + } + } } - }, + } + }, + "security": [ { - "name": "includeBlockedUsers", - "in": "query", - "description": "Set to true to include conversations with blocked users in the response.", - "schema": { - "type": "boolean", - "default": false - } - }, + "apiKey": [] + } + ] + }, + "delete": { + "tags": [ + "Messages" + ], + "summary": "Unpin Message", + "description": "Unpins a message. Anyone with unpin permission may unpin, not only the user who pinned it. Idempotent.", + "operationId": "unpin-message", + "parameters": [ { - "name": "withBlockedInfo", - "in": "query", - "description": "Set to true to include block status details of users in each conversation.", + "name": "onBehalfOf", + "in": "header", + "description": "UID of the user to unpin the message as. Leave it out to unpin as the app itself.", + "required": false, "schema": { - "type": "boolean", - "default": false + "type": "string" } }, { - "name": "userTags", - "in": "query", - "description": "Filters conversations by tags associated with the user entity in the conversationWith property.", - "style": "form", - "explode": false, + "name": "id", + "in": "path", + "description": "Id of the message to unpin.", + "required": true, "schema": { - "type": "array", - "items": { - "type": "string" + "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" } } - }, - { - "name": "groupTags", - "in": "query", - "description": "Filters conversations by tags associated with the group entity in the conversationWith property.", - "style": "form", - "explode": false, - "schema": { - "type": "array", - "items": { - "type": "string" + } + ], + "responses": { + "200": { + "description": "Unpinning a message. pinnedBy and pinnedAt are left out of the response once the message is no longer pinned.", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/messageSchema" + } + }, + "type": "object" + }, + "example": { + "data": { + "id": "2", + "conversationId": "superhero1_user_superhero2", + "sender": "superhero1", + "receiverType": "user", + "receiver": "superhero2", + "category": "message", + "type": "text", + "data": { + "text": "Hi," + }, + "sentAt": 1700210266, + "updatedAt": 1700210266 + } + } } } }, - { - "name": "unread", - "in": "query", - "description": "Lists only unread conversations by excluding the conversations with conversation.unreadMessageCount=0", - "schema": { - "type": "boolean" - } - }, - { - "name": "perPage", - "in": "query", - "description": "Number of conversations to be fetched in a request. The default value is 100 and the maximum value is 1000.", - "schema": { - "type": "integer", - "default": "100" - } - }, - { - "name": "page", - "in": "query", - "description": "Page number.", - "schema": { - "type": "integer", - "default": "1" - } - }, - { - "name": "hideAgentic", - "in": "query", - "description": "Hides agentic conversations from the list.", - "schema": { - "type": "boolean" + "404": { + "description": "No message with that id", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_MESSAGE_ID_NOT_FOUND", + "message": "Message with the provided info doesn't exist." + } + } + } } - }, + } + }, + "security": [ { - "name": "onlyAgentic", - "in": "query", - "description": "Shows only agentic conversations in the list.", - "schema": { - "type": "boolean" - } - }, + "apiKey": [] + } + ] + } + }, + "/messages/{id}/save": { + "post": { + "tags": [ + "Messages" + ], + "summary": "Save Message", + "description": "Saves a message for a user. Saved messages are private to that user, so the onBehalfOf header is required. Idempotent - re-saving keeps the original savedAt.", + "operationId": "save-message", + "parameters": [ { - "name": "useCursoredIndex", - "in": "query", - "description": "Enables cursor-based pagination for more efficient conversations listing.", - "schema": { - "type": "integer", - "default": 1, - "enum": [ - 0, - 1 - ] - } + "$ref": "#/components/parameters/requiredonBehalfOf" }, { - "name": "unique", - "in": "query", - "description": "Enables unique conversation mode, returning only unique conversations in the response (super-admin only). Cannot be used together with the onBehalfOf header.", + "name": "id", + "in": "path", + "description": "Id of the message to save.", + "required": true, "schema": { - "type": "integer", - "enum": [ - 0, - 1 - ] + "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" + } } } ], "responses": { "200": { - "description": "Get Conversations", + "description": "Saving a message. savedAt appears only for the user the message was saved for.", "content": { "application/json": { "schema": { "properties": { "data": { - "type": "array", - "items": {} - }, - "meta": { - "type": "object" + "$ref": "#/components/schemas/messageSchema" } }, "type": "object" }, "example": { - "data": [ - { - "conversationId": "group_project-group", - "conversationType": "group", - "unreadMessageCount": "0", - "createdAt": 1630071782, - "updatedAt": 1630481413, - "lastMessage": { - "id": "50", - "conversationId": "group_project-group", - "sender": "superhero4", - "receiverType": "group", - "receiver": "project-group", - "category": "action", - "type": "groupMember", - "data": { - "action": "unbanned", - "entities": { - "by": { - "entity": { - "uid": "superhero4", - "name": "Wolverine", - "role": "default", - "avatar": "https://data-us.cometchat.io/assets/images/avatars/wolverine.png", - "status": "offline", - "createdAt": 1629869270 - }, - "entityType": "user" - }, - "on": { - "entity": { - "uid": "superhero3", - "link": "https://data-us.cometchat.io/assets", - "name": "Captain America", - "role": "default", - "avatar": "https://data-us.cometchat.io/assets/images/avatars/captainamerica.png", - "status": "offline", - "createdAt": 1629869270, - "updatedAt": 1629964825, - "conversationId": "superhero3_user_superhero4" - }, - "entityType": "user" - }, - "for": { - "entity": { - "guid": "project-group", - "icon": "http://placehold.it/120x120&text=image1", - "name": "Project Group1", - "type": "private", - "owner": "superhero4", - "createdAt": 1630071341, - "updatedAt": 1630305525, - "updatedBy": "superhero4", - "description": "project related discussions between members", - "membersCount": 4, - "conversationId": "group_project-group" - }, - "entityType": "group" - } - } - }, - "sentAt": 1630305562, - "updatedAt": 1630305562, - "receipts": { - "data": [ - [] - ] - } - }, - "conversationWith": { - "guid": "project-group", - "name": "Project Group1", - "description": "project related discussions between members", - "icon": "http://placehold.it/120x120&text=image1", - "type": "private", - "scope": "participant", - "membersCount": 4, - "joinedAt": 1630071782, - "conversationId": "group_project-group", - "hasJoined": true, - "createdAt": 1630071341, - "owner": "superhero4", - "updatedAt": 1630308875, - "updatedBy": "superhero4" - } - } - ], - "meta": { - "pagination": { - "total": 1, - "count": 1, - "per_page": 100, - "current_page": 1, - "total_pages": 1 - } + "data": { + "id": "2", + "conversationId": "superhero1_user_superhero2", + "sender": "superhero1", + "receiverType": "user", + "receiver": "superhero2", + "category": "message", + "type": "text", + "data": { + "text": "Hi," + }, + "sentAt": 1700210266, + "updatedAt": 1700210266, + "savedAt": 1700210300 + } + } + } + } + }, + "400": { + "description": "The user has reached their saved message limit", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_SAVED_MESSAGES_LIMIT_EXCEEDED", + "message": "The number of saved messages for the user with uid superhero1 exceeds the allowed limit of 100." } } } @@ -3612,58 +3672,281 @@ "apiKey": [] } ] - } - }, - "/conversations/{conversationId}": { - "get": { + }, + "delete": { "tags": [ - "Conversations" + "Messages" ], - "summary": "Get conversation", - "description": "This API is deprecated please use Get User/Group ConversationAPI", - "operationId": "get-conversation", + "summary": "Unsave Message", + "description": "Removes a message from a user's saved list. The onBehalfOf header is required. Idempotent.", + "operationId": "unsave-message", "parameters": [ { - "name": "onBehalfOf", - "in": "header", - "description": "UID of the user on whose behalf the action is performed.", + "$ref": "#/components/parameters/requiredonBehalfOf" + }, + { + "name": "id", + "in": "path", + "description": "Id of the message to remove from the user's saved list.", "required": true, "schema": { "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" + } } - }, - { - "$ref": "#/components/parameters/conversationId" } ], "responses": { "200": { - "description": "Get Conversations", + "description": "Unsaving a message. savedAt is left out of the response once the message is no longer saved.", "content": { "application/json": { "schema": { "properties": { "data": { - "type": "object" + "$ref": "#/components/schemas/messageSchema" } }, "type": "object" }, "example": { - "data": [ - { - "conversationId": "group_project-group", - "conversationType": "group", - "unreadMessageCount": "0", - "createdAt": 1630071782, - "updatedAt": 1630481413, - "lastMessage": { - "id": "50", - "conversationId": "group_project-group", - "sender": "superhero4", - "receiverType": "group", - "receiver": "project-group", - "category": "action", + "data": { + "id": "2", + "conversationId": "superhero1_user_superhero2", + "sender": "superhero1", + "receiverType": "user", + "receiver": "superhero2", + "category": "message", + "type": "text", + "data": { + "text": "Hi," + }, + "sentAt": 1700210266, + "updatedAt": 1700210266 + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, + "/conversations": { + "get": { + "tags": [ + "Conversations" + ], + "summary": "List conversations", + "description": "Fetching all the conversations", + "operationId": "list-all-conversations", + "parameters": [ + { + "name": "onBehalfOf", + "in": "header", + "description": "UID of the user on whose behalf the action is performed.\n\n\nIf onBehalfOf header is not passed,then list Conversations API will be ordered based on `uid`, `updatedAt` and then `conversationWith`\n\nIf onBehalfOf header is passed, then list Conversations API will be ordered based on `updatedAt` and then `conversationWith`.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "searchKey", + "in": "query", + "description": "Fetches conversations that include the specified searchKey, allowing you to search for conversations based on the name of a User or Group.", + "schema": { + "type": "string" + } + }, + { + "name": "conversationType", + "in": "query", + "description": "Retrieves only the specified conversation type (user and group) while fetching conversations list.", + "schema": { + "type": "string" + } + }, + { + "name": "withTags", + "in": "query", + "description": "Includes those groups that have tags.", + "schema": { + "type": "boolean" + } + }, + { + "name": "tags", + "in": "query", + "description": "Fetches only those groups that have these tags.", + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "withUserAndGroupTags", + "in": "query", + "description": "Retrieves conversations with tags", + "schema": { + "type": "boolean" + } + }, + { + "name": "includeBlockedUsers", + "in": "query", + "description": "Set to true to include conversations with blocked users in the response.", + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "withBlockedInfo", + "in": "query", + "description": "Set to true to include block status details of users in each conversation.", + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "userTags", + "in": "query", + "description": "Filters conversations by tags associated with the user entity in the conversationWith property.", + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "groupTags", + "in": "query", + "description": "Filters conversations by tags associated with the group entity in the conversationWith property.", + "style": "form", + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "unread", + "in": "query", + "description": "Lists only unread conversations by excluding the conversations with conversation.unreadMessageCount=0", + "schema": { + "type": "boolean" + } + }, + { + "name": "perPage", + "in": "query", + "description": "Number of conversations to be fetched in a request. The default value is 100 and the maximum value is 1000.", + "schema": { + "type": "integer", + "default": "100" + } + }, + { + "name": "page", + "in": "query", + "description": "Page number.", + "schema": { + "type": "integer", + "default": "1" + } + }, + { + "name": "hideAgentic", + "in": "query", + "description": "Hides agentic conversations from the list.", + "schema": { + "type": "boolean" + } + }, + { + "name": "onlyAgentic", + "in": "query", + "description": "Shows only agentic conversations in the list.", + "schema": { + "type": "boolean" + } + }, + { + "name": "useCursoredIndex", + "in": "query", + "description": "Enables cursor-based pagination for more efficient conversations listing.", + "schema": { + "type": "integer", + "default": 1, + "enum": [ + 0, + 1 + ] + } + }, + { + "name": "unique", + "in": "query", + "description": "Enables unique conversation mode, returning only unique conversations in the response (super-admin only). Cannot be used together with the onBehalfOf header.", + "schema": { + "type": "integer", + "enum": [ + 0, + 1 + ] + } + } + ], + "responses": { + "200": { + "description": "Get Conversations", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": {} + }, + "meta": { + "type": "object" + } + }, + "type": "object" + }, + "example": { + "data": [ + { + "conversationId": "group_project-group", + "conversationType": "group", + "unreadMessageCount": "0", + "createdAt": 1630071782, + "updatedAt": 1630481413, + "lastMessage": { + "id": "50", + "conversationId": "group_project-group", + "sender": "superhero4", + "receiverType": "group", + "receiver": "project-group", + "category": "action", "type": "groupMember", "data": { "action": "unbanned", @@ -3736,64 +4019,177 @@ "updatedBy": "superhero4" } } - ] + ], + "meta": { + "pagination": { + "total": 1, + "count": 1, + "per_page": 100, + "current_page": 1, + "total_pages": 1 + } + } } } } } }, - "deprecated": true, "security": [ { "apiKey": [] } ] - }, - "delete": { + } + }, + "/conversations/pinned": { + "get": { "tags": [ "Conversations" ], - "summary": "Delete Conversation", - "description": "This API is deprecated please use Reset User/GroupConversation API", - "operationId": "deletes-conversation", - "parameters": [ - { - "name": "onBehalfOf", - "in": "header", - "description": "UID of the user on whose behalf the action is performed.", - "required": true, - "schema": { - "type": "string" + "summary": "List Global Pinned Conversations", + "description": "Lists the global pinned conversations - the conversations pinned at the top for every end user - in display order.", + "operationId": "list-global-pinned-conversations", + "responses": { + "200": { + "description": "Listing the global pinned conversations, in display order", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/conversationSchema" + } + } + }, + "type": "object" + }, + "example": { + "data": [ + { + "conversationId": "supergroup", + "conversationType": "group", + "pinnedBy": "app_system", + "pinnedAt": 1700210300 + }, + { + "conversationId": "superhero1_user_superhero2", + "conversationType": "user", + "pinnedBy": "app_system", + "pinnedAt": 1700210299 + } + ] + } + } } - }, + } + }, + "security": [ { - "$ref": "#/components/parameters/conversationId" + "apiKey": [] } + ] + }, + "put": { + "tags": [ + "Conversations" ], + "summary": "Replace Global Pinned Conversations", + "description": "Replaces the whole global pinned conversation list - the conversations pinned at the top for every end user. The array is the desired final state and order - entries that are absent get unpinned, new entries get pinned, and array order becomes display order. Send an empty array to clear the list.", + "operationId": "replace-global-pinned-conversations", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "pinnedConversations" + ], + "properties": { + "pinnedConversations": { + "description": "The conversations to pin at the top for every end user, in the order they should appear. Each entry names either a user (uid) or a group (guid). Entries left out of the array are unpinned. Send an empty array to clear the list. Repeated entries are kept once, at their first position.", + "type": "array", + "items": { + "properties": { + "uid": { + "description": "UID of the user, for a one-to-one conversation.", + "type": "string" + }, + "guid": { + "description": "GUID of the group, for a group conversation.", + "type": "string" + } + }, + "type": "object" + }, + "example": [ + { + "guid": "supergroup" + }, + { + "uid": "superhero2" + } + ] + } + }, + "type": "object" + } + } + } + }, "responses": { "200": { - "description": "Deleted Conversations", + "description": "The new global pinned conversation list, in display order", "content": { "application/json": { "schema": { "properties": { "data": { - "type": "object" + "type": "array", + "items": { + "$ref": "#/components/schemas/conversationSchema" + } } }, "type": "object" }, "example": { - "data": { - "success": true, - "message": "The conversation group_project-group has been deleted successfully for all the users." + "data": [ + { + "conversationId": "supergroup", + "conversationType": "group", + "pinnedBy": "app_system", + "pinnedAt": 1700210300 + }, + { + "conversationId": "superhero1_user_superhero2", + "conversationType": "user", + "pinnedBy": "app_system", + "pinnedAt": 1700210299 + } + ] + } + } + } + }, + "400": { + "description": "The global list exceeds its cap, or an entry names neither a uid nor a guid", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_SYSTEM_PINNED_CONVERSATIONS_LIMIT_EXCEEDED", + "message": "The number of pinned conversations exceeds the allowed limit of 5." } } } } } }, - "deprecated": true, "security": [ { "apiKey": [] @@ -3801,14 +4197,14 @@ ] } }, - "/users/{uid}/conversation": { + "/conversations/{conversationId}": { "get": { "tags": [ "Conversations" ], - "summary": "Get User Conversation", - "description": "Getting user conversation", - "operationId": "get-user-conversations", + "summary": "Get conversation", + "description": "This API is deprecated please use Get User/Group ConversationAPI", + "operationId": "get-conversation", "parameters": [ { "name": "onBehalfOf", @@ -3820,12 +4216,12 @@ } }, { - "$ref": "#/components/parameters/uid--conversation" + "$ref": "#/components/parameters/conversationId" } ], "responses": { "200": { - "description": "Get user Conversations", + "description": "Get Conversations", "content": { "application/json": { "schema": { @@ -3899,7 +4295,12 @@ } }, "sentAt": 1630305562, - "updatedAt": 1630305562 + "updatedAt": 1630305562, + "receipts": { + "data": [ + [] + ] + } }, "conversationWith": { "guid": "project-group", @@ -3924,23 +4325,21 @@ } } }, + "deprecated": true, "security": [ { "apiKey": [] } ] }, - "put": { + "delete": { "tags": [ "Conversations" ], - "summary": "Update User Conversation", - "description": "Updating User Conversation", - "operationId": "updates-user-conversation", + "summary": "Delete Conversation", + "description": "This API is deprecated please use Reset User/GroupConversation API", + "operationId": "deletes-conversation", "parameters": [ - { - "$ref": "#/components/parameters/uid--conversation" - }, { "name": "onBehalfOf", "in": "header", @@ -3949,29 +4348,67 @@ "schema": { "type": "string" } + }, + { + "$ref": "#/components/parameters/conversationId" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "properties": { - "tags": { - "description": "List of tags to identify specific conversation.", - "type": "array", - "items": { - "type": "string" + "responses": { + "200": { + "description": "Deleted Conversations", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "object" } - } + }, + "type": "object" }, - "type": "object" + "example": { + "data": { + "success": true, + "message": "The conversation group_project-group has been deleted successfully for all the users." + } + } } } } }, + "deprecated": true, + "security": [ + { + "apiKey": [] + } + ] + } + }, + "/users/{uid}/conversation": { + "get": { + "tags": [ + "Conversations" + ], + "summary": "Get User Conversation", + "description": "Getting user conversation", + "operationId": "get-user-conversations", + "parameters": [ + { + "name": "onBehalfOf", + "in": "header", + "description": "UID of the user on whose behalf the action is performed.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "$ref": "#/components/parameters/uid--conversation" + } + ], "responses": { "200": { - "description": "Updated user Conversations", + "description": "Get user Conversations", "content": { "application/json": { "schema": { @@ -4045,12 +4482,7 @@ } }, "sentAt": 1630305562, - "updatedAt": 1630305562, - "receipts": { - "data": [ - [] - ] - } + "updatedAt": 1630305562 }, "conversationWith": { "guid": "project-group", @@ -4081,14 +4513,17 @@ } ] }, - "delete": { + "put": { "tags": [ "Conversations" ], - "summary": "Reset User Conversation", - "description": "Resetting User Conversation", - "operationId": "resets-user-conversation", + "summary": "Update User Conversation", + "description": "Updating User Conversation", + "operationId": "updates-user-conversation", "parameters": [ + { + "$ref": "#/components/parameters/uid--conversation" + }, { "name": "onBehalfOf", "in": "header", @@ -4097,9 +4532,6 @@ "schema": { "type": "string" } - }, - { - "$ref": "#/components/parameters/uid--conversation" } ], "requestBody": { @@ -4107,18 +4539,12 @@ "application/json": { "schema": { "properties": { - "conversationWith": { - "description": "UID of a user", - "type": "string" - }, - "deleteMessagesPermanently": { - "description": "Permanently deletes messages in that particular conversation", - "type": "boolean" - }, - "preserveOrder": { - "description": "When set to true, maintains the conversation's position in the user's conversation list after reset.", - "type": "boolean", - "default": false + "tags": { + "description": "List of tags to identify specific conversation.", + "type": "array", + "items": { + "type": "string" + } } }, "type": "object" @@ -4128,7 +4554,7 @@ }, "responses": { "200": { - "description": "Resetted user Conversations", + "description": "Updated user Conversations", "content": { "application/json": { "schema": { @@ -4140,35 +4566,116 @@ "type": "object" }, "example": { - "data": { - "success": true, - "message": "The conversation superhero1_user_superhero2 has been deleted successfully for UID superhero1." - } - } - } - } - } - }, - "security": [ - { - "apiKey": [] - } - ] - } - }, - "/users/{uid}/conversation/delivered": { - "post": { - "tags": [ - "Conversations" - ], - "summary": "Mark User Conversation As Delivered", - "description": "This API will mark the user conversation as delivered.", - "operationId": "mark-conversation-as-delivered", + "data": [ + { + "conversationId": "group_project-group", + "conversationType": "group", + "unreadMessageCount": "0", + "createdAt": 1630071782, + "updatedAt": 1630481413, + "lastMessage": { + "id": "50", + "conversationId": "group_project-group", + "sender": "superhero4", + "receiverType": "group", + "receiver": "project-group", + "category": "action", + "type": "groupMember", + "data": { + "action": "unbanned", + "entities": { + "by": { + "entity": { + "uid": "superhero4", + "name": "Wolverine", + "role": "default", + "avatar": "https://data-us.cometchat.io/assets/images/avatars/wolverine.png", + "status": "offline", + "createdAt": 1629869270 + }, + "entityType": "user" + }, + "on": { + "entity": { + "uid": "superhero3", + "link": "https://data-us.cometchat.io/assets", + "name": "Captain America", + "role": "default", + "avatar": "https://data-us.cometchat.io/assets/images/avatars/captainamerica.png", + "status": "offline", + "createdAt": 1629869270, + "updatedAt": 1629964825, + "conversationId": "superhero3_user_superhero4" + }, + "entityType": "user" + }, + "for": { + "entity": { + "guid": "project-group", + "icon": "http://placehold.it/120x120&text=image1", + "name": "Project Group1", + "type": "private", + "owner": "superhero4", + "createdAt": 1630071341, + "updatedAt": 1630305525, + "updatedBy": "superhero4", + "description": "project related discussions between members", + "membersCount": 4, + "conversationId": "group_project-group" + }, + "entityType": "group" + } + } + }, + "sentAt": 1630305562, + "updatedAt": 1630305562, + "receipts": { + "data": [ + [] + ] + } + }, + "conversationWith": { + "guid": "project-group", + "name": "Project Group1", + "description": "project related discussions between members", + "icon": "http://placehold.it/120x120&text=image1", + "type": "private", + "scope": "participant", + "membersCount": 4, + "joinedAt": 1630071782, + "conversationId": "group_project-group", + "hasJoined": true, + "createdAt": 1630071341, + "owner": "superhero4", + "updatedAt": 1630308875, + "updatedBy": "superhero4" + } + } + ] + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + }, + "delete": { + "tags": [ + "Conversations" + ], + "summary": "Reset User Conversation", + "description": "Resetting User Conversation", + "operationId": "resets-user-conversation", "parameters": [ { "name": "onBehalfOf", "in": "header", - "description": "UID of the receiver of the message", + "description": "UID of the user on whose behalf the action is performed.", "required": true, "schema": { "type": "string" @@ -4183,9 +4690,18 @@ "application/json": { "schema": { "properties": { - "messageId": { - "description": "The id of the message upto which the conversation needs to be marked as delivered.", - "type": "integer" + "conversationWith": { + "description": "UID of a user", + "type": "string" + }, + "deleteMessagesPermanently": { + "description": "Permanently deletes messages in that particular conversation", + "type": "boolean" + }, + "preserveOrder": { + "description": "When set to true, maintains the conversation's position in the user's conversation list after reset.", + "type": "boolean", + "default": false } }, "type": "object" @@ -4195,7 +4711,7 @@ }, "responses": { "200": { - "description": "Marking Conversation as delivered", + "description": "Resetted user Conversations", "content": { "application/json": { "schema": { @@ -4209,7 +4725,7 @@ "example": { "data": { "success": true, - "Message": "All the messages from the user {{UID}} are marked as delivered for the user {{onBehalfOf}}." + "message": "The conversation superhero1_user_superhero2 has been deleted successfully for UID superhero1." } } } @@ -4223,60 +4739,133 @@ ] } }, - "/users/{uid}/conversation/read": { + "/users/{uid}/conversation/pin": { "post": { "tags": [ "Conversations" ], - "summary": "Mark User Conversation As Read", - "description": "This API will mark the user conversation as read.", - "operationId": "mark-conversation-as-read", + "summary": "Pin User Conversation", + "description": "Pins a one-to-one conversation for a user, so it appears at the top of their conversation list. Pins are per user, so the onBehalfOf header is required. Idempotent - re-pinning keeps the original pinnedAt.", + "operationId": "pin-user-conversation", "parameters": [ { - "name": "onBehalfOf", - "in": "header", - "description": "UID of the receiver of the message", - "required": true, - "schema": { - "type": "string" - } + "$ref": "#/components/parameters/requiredonBehalfOf" }, { "$ref": "#/components/parameters/uid--conversation" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "properties": { - "messageId": { - "description": "The id of the message upto which the conversation needs to be marked as read.", - "type": "integer" + "responses": { + "200": { + "description": "Pinning a one-to-one conversation", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/conversationSchema" + } + }, + "type": "object" + }, + "example": { + "data": { + "conversationId": "superhero1_user_superhero2", + "conversationType": "user", + "pinnedBy": "superhero1", + "pinnedAt": 1700210300 } + } + } + } + }, + "400": { + "description": "The user has reached their pinned conversation limit", + "content": { + "application/json": { + "schema": { + "type": "object" }, - "type": "object" + "example": { + "error": { + "code": "ERR_PINNED_CONVERSATIONS_LIMIT_EXCEEDED", + "message": "The number of pinned conversations for the user with uid superhero1 exceeds the allowed limit of 5." + } + } + } + } + }, + "403": { + "description": "The conversation carries a global pin, so a user cannot pin it themselves", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_SYSTEM_PINNED_CONVERSATION", + "message": "The conversation is pinned for all users by the app and can not be pinned by a user." + } + } } } } }, + "security": [ + { + "apiKey": [] + } + ] + }, + "delete": { + "tags": [ + "Conversations" + ], + "summary": "Unpin User Conversation", + "description": "Removes a user's own pin from a one-to-one conversation. A conversation carrying a global pin cannot be unpinned this way. Idempotent.", + "operationId": "unpin-user-conversation", + "parameters": [ + { + "$ref": "#/components/parameters/requiredonBehalfOf" + }, + { + "$ref": "#/components/parameters/uid--conversation" + } + ], "responses": { "200": { - "description": "Marking Conversation as read", + "description": "Unpinning a one-to-one conversation. pinnedBy and pinnedAt are left out of the response once the conversation is no longer pinned.", "content": { "application/json": { "schema": { "properties": { "data": { - "type": "object" + "$ref": "#/components/schemas/conversationSchema" } }, "type": "object" }, "example": { "data": { - "success": true, - "Message": "All the messages from the user {{UID}} are marked as read for the user {{onBehalfOf}}." + "conversationId": "superhero1_user_superhero2", + "conversationType": "user" + } + } + } + } + }, + "403": { + "description": "The conversation carries a global pin, so a user cannot unpin it themselves", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_SYSTEM_PINNED_CONVERSATION", + "message": "The conversation is pinned for all users by the app and can not be unpinned by a user." } } } @@ -4288,14 +4877,16 @@ "apiKey": [] } ] - }, - "delete": { + } + }, + "/users/{uid}/conversation/delivered": { + "post": { "tags": [ "Conversations" ], - "summary": "Mark Conversation Messages As Unread", - "description": "Allows you to mark messages within a conversation as unread", - "operationId": "mark-conversation-as-unread", + "summary": "Mark User Conversation As Delivered", + "description": "This API will mark the user conversation as delivered.", + "operationId": "mark-conversation-as-delivered", "parameters": [ { "name": "onBehalfOf", @@ -4316,7 +4907,7 @@ "schema": { "properties": { "messageId": { - "description": "The id of the message upto which the conversation needs to be marked as unread.", + "description": "The id of the message upto which the conversation needs to be marked as delivered.", "type": "integer" } }, @@ -4327,7 +4918,7 @@ }, "responses": { "200": { - "description": "Marking Conversation as unread", + "description": "Marking Conversation as delivered", "content": { "application/json": { "schema": { @@ -4341,7 +4932,7 @@ "example": { "data": { "success": true, - "message": "The messages after the message id 340 from the user demo1 are marked as unread for the user demo3." + "Message": "All the messages from the user {{UID}} are marked as delivered for the user {{onBehalfOf}}." } } } @@ -4355,34 +4946,166 @@ ] } }, - "/groups/{guid}/conversation": { - "get": { + "/users/{uid}/conversation/read": { + "post": { "tags": [ "Conversations" ], - "summary": "Get Group Conversation", - "description": "Getting group conversation", - "operationId": "get-group-conversations", + "summary": "Mark User Conversation As Read", + "description": "This API will mark the user conversation as read.", + "operationId": "mark-conversation-as-read", "parameters": [ { "name": "onBehalfOf", "in": "header", - "description": "UID of the user on whose behalf the action is performed.", + "description": "UID of the receiver of the message", "required": true, "schema": { "type": "string" } }, { - "$ref": "#/components/parameters/guid--conversation" + "$ref": "#/components/parameters/uid--conversation" } ], - "responses": { - "200": { - "description": "Get user Conversations", - "content": { - "application/json": { - "schema": { + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "messageId": { + "description": "The id of the message upto which the conversation needs to be marked as read.", + "type": "integer" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Marking Conversation as read", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "object" + } + }, + "type": "object" + }, + "example": { + "data": { + "success": true, + "Message": "All the messages from the user {{UID}} are marked as read for the user {{onBehalfOf}}." + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + }, + "delete": { + "tags": [ + "Conversations" + ], + "summary": "Mark Conversation Messages As Unread", + "description": "Allows you to mark messages within a conversation as unread", + "operationId": "mark-conversation-as-unread", + "parameters": [ + { + "name": "onBehalfOf", + "in": "header", + "description": "UID of the receiver of the message", + "required": true, + "schema": { + "type": "string" + } + }, + { + "$ref": "#/components/parameters/uid--conversation" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "properties": { + "messageId": { + "description": "The id of the message upto which the conversation needs to be marked as unread.", + "type": "integer" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Marking Conversation as unread", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "object" + } + }, + "type": "object" + }, + "example": { + "data": { + "success": true, + "message": "The messages after the message id 340 from the user demo1 are marked as unread for the user demo3." + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, + "/groups/{guid}/conversation": { + "get": { + "tags": [ + "Conversations" + ], + "summary": "Get Group Conversation", + "description": "Getting group conversation", + "operationId": "get-group-conversations", + "parameters": [ + { + "name": "onBehalfOf", + "in": "header", + "description": "UID of the user on whose behalf the action is performed.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "$ref": "#/components/parameters/guid--conversation" + } + ], + "responses": { + "200": { + "description": "Get user Conversations", + "content": { + "application/json": { + "schema": { "properties": { "data": { "type": "object" @@ -4702,6 +5425,146 @@ ] } }, + "/groups/{guid}/conversation/pin": { + "post": { + "tags": [ + "Conversations" + ], + "summary": "Pin Group Conversation", + "description": "Pins a group conversation for a user, so it appears at the top of their conversation list. Pins are per user, so the onBehalfOf header is required. Idempotent - re-pinning keeps the original pinnedAt.", + "operationId": "pin-group-conversation", + "parameters": [ + { + "$ref": "#/components/parameters/requiredonBehalfOf" + }, + { + "$ref": "#/components/parameters/guid--conversation" + } + ], + "responses": { + "200": { + "description": "Pinning a group conversation", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/conversationSchema" + } + }, + "type": "object" + }, + "example": { + "data": { + "conversationId": "supergroup", + "conversationType": "group", + "pinnedBy": "superhero1", + "pinnedAt": 1700210300 + } + } + } + } + }, + "400": { + "description": "The user has reached their pinned conversation limit", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_PINNED_CONVERSATIONS_LIMIT_EXCEEDED", + "message": "The number of pinned conversations for the user with uid superhero1 exceeds the allowed limit of 5." + } + } + } + } + }, + "403": { + "description": "The conversation carries a global pin, so a user cannot pin it themselves", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_SYSTEM_PINNED_CONVERSATION", + "message": "The conversation is pinned for all users by the app and can not be pinned by a user." + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + }, + "delete": { + "tags": [ + "Conversations" + ], + "summary": "Unpin Group Conversation", + "description": "Removes a user's own pin from a group conversation. A conversation carrying a global pin cannot be unpinned this way. Idempotent.", + "operationId": "unpin-group-conversation", + "parameters": [ + { + "$ref": "#/components/parameters/requiredonBehalfOf" + }, + { + "$ref": "#/components/parameters/guid--conversation" + } + ], + "responses": { + "200": { + "description": "Unpinning a group conversation. pinnedBy and pinnedAt are left out of the response once the conversation is no longer pinned.", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "$ref": "#/components/schemas/conversationSchema" + } + }, + "type": "object" + }, + "example": { + "data": { + "conversationId": "supergroup", + "conversationType": "group" + } + } + } + } + }, + "403": { + "description": "The conversation carries a global pin, so a user cannot unpin it themselves", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "error": { + "code": "ERR_SYSTEM_PINNED_CONVERSATION", + "message": "The conversation is pinned for all users by the app and can not be unpinned by a user." + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, "/groups/{guid}/conversation/delivered": { "post": { "tags": [ @@ -14528,128 +15391,615 @@ } } } - }, - "security": [ - { - "apiKey": [] - } - ] - } - }, - "/moderation/blocked-messages": { - "get": { - "tags": [ - "Moderation" + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, + "/moderation/blocked-messages": { + "get": { + "tags": [ + "Moderation" + ], + "summary": "List Blocked Messages", + "description": "Lists the messages blocked by the moderation service.", + "operationId": "chat-api-list-moderation-blocked-messages", + "responses": { + "200": { + "description": "List Blocked Messages", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "properties": { + "": { + "$ref": "#/components/schemas/webhookSchema" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "example": { + "data": [ + { + "ruleId": "image-moderation", + "ruleName": "AI Image Moderation", + "revisionId": "253156be20433c97_image-moderation_4", + "condition": { + "id": 1, + "isKeywordsReferencePresent": false, + "isMediaPresent": true, + "entity": "message", + "operand": "image", + "category": "word", + "operator": "contains", + "value": [ + "Any unsafe content_greaterThan_70" + ], + "message": [ + "Image contains Any unsafe content with confidence greater than 70" + ], + "weight": 1 + }, + "message": { + "id": "65", + "muid": "_5zytzmceo", + "conversationId": "superhero1_user_superhero2", + "sender": "superhero1", + "receiverType": "user", + "receiver": "superhero2", + "category": "message", + "type": "image", + "data": { + "metadata": { + "file": [] + }, + "resource": "WEB-4_0_3-ffa565b2-476e-493d-aeb5-4c750aae3ab1-1719925738505", + "url": "https://data-eu.cometchat.io/2601293c931567f7/media/1719993037_336554568_9e044ea0ed5817381b189680f392bafe.jpeg", + "attachments": [ + { + "name": "download.jpeg", + "extension": "jpeg", + "size": 4761, + "mimeType": "image/jpeg", + "url": "https://data-eu.cometchat.io/2601293c931567f7/media/1719993037_336554568_9e044ea0ed5817381b189680f392bafe.jpeg" + } + ], + "entities": { + "sender": { + "entity": { + "uid": "superhero1", + "name": "Iron Man", + "avatar": "https://data-eu.cometchat.io/assets/images/avatars/ironman.png", + "status": "offline", + "role": "default" + }, + "entityType": "user" + }, + "receiver": { + "entity": { + "uid": "superhero2", + "name": "Captain America", + "avatar": "https://data-eu.cometchat.io/assets/images/avatars/captainamerica.png", + "status": "offline", + "role": "default", + "conversationId": "superhero1_user_superhero2" + }, + "entityType": "user" + } + }, + "moderation": { + "status": "pending" + } + }, + "sentAt": 1719993037, + "updatedAt": 1719993037 + }, + "action": [ + "blockMessage" + ], + "createdAt": 1719993038, + "updatedAt": 1719993038 + } + ], + "meta": { + "current": { + "limit": 50, + "count": 20 + } + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, + "/moderation/blocked-messages/{messageId}": { + "patch": { + "tags": [ + "Moderation" + ], + "summary": "Approve Blocked Messages", + "description": "Approves the messages blocked by the moderation service.", + "operationId": "chat-api-approve-moderation-blocked-messages", + "parameters": [ + { + "$ref": "#/components/parameters/messageId" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "required": [ + "status" + ], + "properties": { + "status": { + "description": "Moderation status of the message.", + "type": "string", + "example": "approved" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Approve Blocked Messages", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "properties": { + "": { + "$ref": "#/components/schemas/webhookSchema" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "example": { + "data": { + "success": true, + "message": "Message with ID 268 has been approved." + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, + "/moderation/messages": { + "post": { + "tags": [ + "Moderation" + ], + "summary": "Send message", + "description": "This endpoint is used to submit a message for moderation before it is delivered to the recipient. The message is scanned against the moderation rules configured for the app.", + "operationId": "chat-api-send-message-moderation", + "requestBody": { + "content": { + "application/json": { + "schema": { + "required": [ + "sender", + "receiver", + "receiverType" + ], + "properties": { + "muid": { + "description": "The unique identifier for the message", + "type": "string" + }, + "category": { + "description": "Category of the message. The available category is message", + "type": "string", + "enum": [ + "message" + ] + }, + "type": { + "description": "Defines the type of the message based on the selected category.\nWhen `category` is `message`, the allowed values for `type` are:\n\n`text` — Plain text message\n\n`image` — Image message\n\n`audio` — Audio message\n\n`video` — Video message\n\n`file` — File message\n\nWhen `category` is `custom`, any custom string can be used as the `type`. This allows developers to define and handle custom message types as needed in their UI implementation.", + "type": "string", + "enum": [ + "text", + "image", + "file", + "audio", + "video" + ] + }, + "sender": { + "description": "UID of the sender.", + "type": "string" + }, + "receiver": { + "description": "If the receiverType == “user” the UID of a user receiving the message. else GUID of the group.", + "type": "string" + }, + "receiverType": { + "description": "The receiverType of the message. either user or group", + "type": "string", + "enum": [ + "user", + "group" + ] + }, + "data": { + "$ref": "#/components/schemas/moderationMessageData" + }, + "senderUserDetails": { + "description": "This property contains information about the sender user. It is required only if the sender does not already exist in CometChat. If provided, the sender user will be created before the message is processed.", + "allOf": [ + { + "$ref": "#/components/schemas/userSenderDetails" + } + ] + }, + "receiverUserDetails": { + "description": "This property contains information about the receiver user (in case of one-to-one messages). It is required only if the receiver user does not already exist in CometChat. If provided, the user will be created before the message is sent.", + "allOf": [ + { + "$ref": "#/components/schemas/userSenderDetails" + } + ] + }, + "receiverGroupDetails": { + "description": "This property contains information about the group receiving the message.\nIt is required only if the group does not already exist in CometChat. If provided, the group will be created before the message is sent.", + "allOf": [ + { + "$ref": "#/components/schemas/groupReceiverDetails" + } + ] + }, + "tags": { + "description": "String array containing developer defined tags.", + "type": "array", + "items": { + "type": "string" + } + }, + "sentAt": { + "description": "10 digit unix timestamp at which the message would be sent. If left blank, the current timestamp would be used.", + "type": "integer" + } + }, + "type": "object" + }, + "examples": { + "Send Moderation Message": { + "summary": "Send Moderation Message", + "value": { + "category": "message", + "type": "text", + "data": { + "text": "Hey there! Welcome aboard." + }, + "sender": "cometchat-test-user-1", + "receiver": "cometchat-test-user-2", + "senderUserDetails": { + "uid": "cometchat-test-user-1", + "name": "Test User 1" + }, + "receiverUserDetails": { + "uid": "cometchat-test-user-2", + "name": "Test User 2" + }, + "receiverType": "user" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Import Message(s)", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "data": { + "id": "1", + "conversationId": "cometchat-uid-1_user_cometchat-uid-2", + "sender": "cometchat-uid-2", + "receiverType": "user", + "receiver": "cometchat-uid-1", + "category": "message", + "type": "text", + "data": { + "text": "Hi new user", + "entities": { + "sender": { + "entity": { + "uid": "cometchat-uid-2", + "name": "George Alan", + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-2.webp", + "status": "offline", + "role": "default", + "lastActiveAt": 1751644824, + "createdAt": 1751644824, + "conversationId": "cometchat-uid-1_user_cometchat-uid-2" + }, + "entityType": "user" + }, + "receiver": { + "entity": { + "uid": "cometchat-uid-1", + "name": "Andrew Joseph", + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-1.webp", + "status": "offline", + "role": "default", + "lastActiveAt": 1751644824, + "createdAt": 1751644824 + }, + "entityType": "user" + } + }, + "moderation": { + "status": "pending" + } + }, + "sentAt": 1750335220, + "updatedAt": 1751644906 + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + }, + "get": { + "tags": [ + "Moderation" + ], + "summary": "List messages", + "description": "This endpoint is used to retrieve a list of messages that were submitted for moderation. Each message includes its current moderation status based on the rules configured for the app.", + "operationId": "chat-api-list-message-moderation", + "parameters": [ + { + "name": "sender", + "in": "query", + "description": "Filters messages by the sender’s uid.", + "schema": { + "type": "string" + } + }, + { + "name": "receiverUID", + "in": "query", + "description": "Filters messages by the receiver's uid.", + "schema": { + "type": "string" + } + }, + { + "name": "receiverGUID", + "in": "query", + "description": "Filters messages by the receiver's guid in case of group", + "schema": { + "type": "string" + } + }, + { + "name": "category", + "in": "query", + "description": "Filters messages by category. Possible values: message and custom.", + "schema": { + "type": "string", + "enum": [ + "message", + "custom" + ] + } + }, + { + "name": "type", + "in": "query", + "description": "Filters messages by type.", + "schema": { + "type": "string" + } + }, + { + "name": "moderationStatus", + "in": "query", + "description": "Filters messages by moderation status.", + "schema": { + "type": "string", + "enum": [ + "disapproved", + "pending" + ] + } + } + ], + "responses": { + "200": { + "description": "Get Message(s)", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "example": { + "data": [ + { + "id": "1", + "conversationId": "cometchat-uid-1_user_cometchat-uid-2", + "sender": "cometchat-uid-2", + "receiverType": "user", + "receiver": "cometchat-uid-1", + "category": "message", + "type": "text", + "data": { + "entities": { + "receiver": { + "entity": { + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-1.webp", + "createdAt": 1751644824, + "lastActiveAt": 1751644824, + "name": "Andrew Joseph", + "role": "default", + "status": "offline", + "uid": "cometchat-uid-1" + }, + "entityType": "user" + }, + "sender": { + "entity": { + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-2.webp", + "conversationId": "cometchat-uid-1_user_cometchat-uid-2", + "createdAt": 1751644824, + "lastActiveAt": 1751644824, + "name": "George Alan", + "role": "default", + "status": "offline", + "uid": "cometchat-uid-2" + }, + "entityType": "user" + } + }, + "moderation": { + "status": "approved" + }, + "text": "Hi new user" + }, + "sentAt": 1750335220, + "updatedAt": 1751644906 + } + ], + "meta": { + "current": { + "limit": 100, + "count": 1 + }, + "next": { + "affix": "append", + "sentAt": 1750335220, + "id": "1" + } + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + } + }, + "/moderation/messages/{id}": { + "get": { + "tags": [ + "Moderation" + ], + "summary": "Get message", + "description": "This endpoint is used to retrieve the details of a message that was submitted for moderation. The message is fetched along with its current moderation status based on the app's configured rules.", + "operationId": "chat-api-get-message-moderation", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Id of the message whose details are to be fetched.", + "required": true, + "schema": { + "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" + } + } + } ], - "summary": "List Blocked Messages", - "description": "Lists the messages blocked by the moderation service.", - "operationId": "chat-api-list-moderation-blocked-messages", "responses": { "200": { - "description": "List Blocked Messages", + "description": "Get Message(s)", "content": { "application/json": { "schema": { - "properties": { - "data": { - "properties": { - "": { - "$ref": "#/components/schemas/webhookSchema" - } - }, - "type": "object" - } - }, "type": "object" }, "example": { - "data": [ - { - "ruleId": "image-moderation", - "ruleName": "AI Image Moderation", - "revisionId": "253156be20433c97_image-moderation_4", - "condition": { - "id": 1, - "isKeywordsReferencePresent": false, - "isMediaPresent": true, - "entity": "message", - "operand": "image", - "category": "word", - "operator": "contains", - "value": [ - "Any unsafe content_greaterThan_70" - ], - "message": [ - "Image contains Any unsafe content with confidence greater than 70" - ], - "weight": 1 - }, - "message": { - "id": "65", - "muid": "_5zytzmceo", - "conversationId": "superhero1_user_superhero2", - "sender": "superhero1", - "receiverType": "user", - "receiver": "superhero2", - "category": "message", - "type": "image", - "data": { - "metadata": { - "file": [] - }, - "resource": "WEB-4_0_3-ffa565b2-476e-493d-aeb5-4c750aae3ab1-1719925738505", - "url": "https://data-eu.cometchat.io/2601293c931567f7/media/1719993037_336554568_9e044ea0ed5817381b189680f392bafe.jpeg", - "attachments": [ - { - "name": "download.jpeg", - "extension": "jpeg", - "size": 4761, - "mimeType": "image/jpeg", - "url": "https://data-eu.cometchat.io/2601293c931567f7/media/1719993037_336554568_9e044ea0ed5817381b189680f392bafe.jpeg" - } - ], - "entities": { - "sender": { - "entity": { - "uid": "superhero1", - "name": "Iron Man", - "avatar": "https://data-eu.cometchat.io/assets/images/avatars/ironman.png", - "status": "offline", - "role": "default" - }, - "entityType": "user" - }, - "receiver": { - "entity": { - "uid": "superhero2", - "name": "Captain America", - "avatar": "https://data-eu.cometchat.io/assets/images/avatars/captainamerica.png", - "status": "offline", - "role": "default", - "conversationId": "superhero1_user_superhero2" - }, - "entityType": "user" - } + "data": { + "id": "1", + "conversationId": "cometchat-uid-1_user_cometchat-uid-2", + "sender": "cometchat-uid-2", + "receiverType": "user", + "receiver": "cometchat-uid-1", + "category": "message", + "type": "text", + "data": { + "entities": { + "receiver": { + "entity": { + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-1.webp", + "createdAt": 1751644824, + "lastActiveAt": 1751644824, + "name": "Andrew Joseph", + "role": "default", + "status": "offline", + "uid": "cometchat-uid-1" }, - "moderation": { - "status": "pending" - } + "entityType": "user" }, - "sentAt": 1719993037, - "updatedAt": 1719993037 + "sender": { + "entity": { + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-2.webp", + "conversationId": "cometchat-uid-1_user_cometchat-uid-2", + "createdAt": 1751644824, + "lastActiveAt": 1751644824, + "name": "George Alan", + "role": "default", + "status": "offline", + "uid": "cometchat-uid-2" + }, + "entityType": "user" + } }, - "action": [ - "blockMessage" - ], - "createdAt": 1719993038, - "updatedAt": 1719993038 - } - ], - "meta": { - "current": { - "limit": 50, - "count": 20 - } + "moderation": { + "status": "approved" + }, + "text": "Hi new user" + }, + "sentAt": 1750335220, + "updatedAt": 1751644906 } } } @@ -14661,62 +16011,157 @@ "apiKey": [] } ] - } - }, - "/moderation/blocked-messages/{messageId}": { - "patch": { + }, + "put": { "tags": [ "Moderation" ], - "summary": "Approve Blocked Messages", - "description": "Approves the messages blocked by the moderation service.", - "operationId": "chat-api-approve-moderation-blocked-messages", + "summary": "Update message", + "description": "This endpoint is responsible for editing the message, The moderation status is recalculated based on the app's configured rules for the edited message.", + "operationId": "chat-api-update-message-moderation", "parameters": [ { - "$ref": "#/components/parameters/messageId" + "name": "id", + "in": "path", + "description": "Id of the message whose details are to be fetched.", + "required": true, + "schema": { + "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" + } + } } ], "requestBody": { "content": { "application/json": { "schema": { - "required": [ - "status" - ], "properties": { - "status": { - "description": "Moderation status of the message.", - "type": "string", - "example": "approved" + "data": { + "$ref": "#/components/schemas/moderationMessageData" } }, "type": "object" + }, + "examples": { + "Update Moderation Message": { + "summary": "Update Moderation Message", + "value": { + "data": { + "text": "This message has been updated." + } + } + } } } } }, "responses": { "200": { - "description": "Approve Blocked Messages", + "description": "Update Message(s)", "content": { "application/json": { "schema": { - "properties": { + "type": "object" + }, + "example": { + "data": { + "id": "1", + "conversationId": "cometchat-uid-1_user_cometchat-uid-2", + "sender": "cometchat-uid-2", + "receiverType": "user", + "receiver": "cometchat-uid-1", + "category": "message", + "type": "text", "data": { - "properties": { - "": { - "$ref": "#/components/schemas/webhookSchema" + "text": "heyaya, I'm updated", + "entities": { + "receiver": { + "entity": { + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-1.webp", + "createdAt": 1751644824, + "lastActiveAt": 1751644824, + "name": "Andrew Joseph", + "role": "default", + "status": "offline", + "uid": "cometchat-uid-1" + }, + "entityType": "user" + }, + "sender": { + "entity": { + "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-2.webp", + "conversationId": "cometchat-uid-1_user_cometchat-uid-2", + "createdAt": 1751644824, + "lastActiveAt": 1751644824, + "name": "George Alan", + "role": "default", + "status": "offline", + "uid": "cometchat-uid-2" + }, + "entityType": "user" } }, - "type": "object" - } - }, + "moderation": { + "status": "approved" + } + }, + "sentAt": 1750335220, + "editedAt": 1751645607, + "editedBy": "cometchat-uid-1", + "updatedAt": 1751644906 + } + } + } + } + } + }, + "security": [ + { + "apiKey": [] + } + ] + }, + "delete": { + "tags": [ + "Moderation" + ], + "summary": "Delete message", + "description": "This endpoint deletes a previously submitted message. The message is removed along with its associated moderation data, as per the app's configured rules.", + "operationId": "chat-api-delete-message-moderation", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "Id of the message whose details are to be fetched.", + "required": true, + "schema": { + "type": "string" + }, + "examples": { + "string": { + "summary": "Message ID", + "value": "" + } + } + } + ], + "responses": { + "200": { + "description": "Delete Message(s)", + "content": { + "application/json": { + "schema": { "type": "object" }, "example": { "data": { "success": true, - "message": "Message with ID 268 has been approved." + "message": "Message with id 20011 has been deleted successfully." } } } @@ -17346,6 +18791,14 @@ }, "conversationWith": { "type": "object" + }, + "pinnedBy": { + "description": "UID of the user who pinned the conversation, or app_system for a global pin. Left out of the response when the conversation is not pinned.", + "type": "string" + }, + "pinnedAt": { + "description": "When the conversation was pinned, in seconds. Left out of the response when the conversation is not pinned.", + "type": "integer" } }, "type": "object" @@ -17431,6 +18884,7 @@ "type": "object" }, "customCategorySchema": { + "title": "Custom", "properties": { "receiver": { "description": "The receiver of the message.", @@ -17458,11 +18912,7 @@ }, "quotedMessageId": { "description": "ID of the message being quoted.\nIf provided, the send message response will include a `quotedMessage` node\nin the response containing the referenced message object.", - "type": "string", - "default": "message", - "enum": [ - "message" - ] + "type": "string" }, "type": { "description": "Type of the message.", @@ -18458,6 +19908,7 @@ "type": "object" }, "messageCategorySchema": { + "title": "Message", "properties": { "receiver": { "description": "The receiver of the message.", @@ -18845,6 +20296,18 @@ }, "updatedAt": { "type": "integer" + }, + "pinnedBy": { + "description": "UID of the user who pinned the message, or app_system when the app pinned it. Left out of the response when the message is not pinned.", + "type": "string" + }, + "pinnedAt": { + "description": "When the message was pinned, in seconds. Left out of the response when the message is not pinned.", + "type": "integer" + }, + "savedAt": { + "description": "When the message was saved, in seconds. Only present for the user who saved it, and left out of the response when they have not saved it.", + "type": "integer" } }, "type": "object" diff --git a/data-import-apis.json b/data-import-apis.json index 2678590ca..cd7e55dc0 100644 --- a/data-import-apis.json +++ b/data-import-apis.json @@ -2928,6 +2928,14 @@ }, "conversationWith": { "type": "object" + }, + "pinnedBy": { + "description": "UID of the user who pinned the conversation, or app_system for a global pin. Left out of the response when the conversation is not pinned.", + "type": "string" + }, + "pinnedAt": { + "description": "When the conversation was pinned, in seconds. Left out of the response when the conversation is not pinned.", + "type": "integer" } }, "type": "object" @@ -3013,6 +3021,7 @@ "type": "object" }, "customCategorySchema": { + "title": "Custom", "properties": { "receiver": { "description": "The receiver of the message.", @@ -3040,11 +3049,7 @@ }, "quotedMessageId": { "description": "ID of the message being quoted.\nIf provided, the send message response will include a `quotedMessage` node\nin the response containing the referenced message object.", - "type": "string", - "default": "message", - "enum": [ - "message" - ] + "type": "string" }, "type": { "description": "Type of the message.", @@ -4040,6 +4045,7 @@ "type": "object" }, "messageCategorySchema": { + "title": "Message", "properties": { "receiver": { "description": "The receiver of the message.", @@ -4427,6 +4433,18 @@ }, "updatedAt": { "type": "integer" + }, + "pinnedBy": { + "description": "UID of the user who pinned the message, or app_system when the app pinned it. Left out of the response when the message is not pinned.", + "type": "string" + }, + "pinnedAt": { + "description": "When the message was pinned, in seconds. Left out of the response when the message is not pinned.", + "type": "integer" + }, + "savedAt": { + "description": "When the message was saved, in seconds. Only present for the user who saved it, and left out of the response when they have not saved it.", + "type": "integer" } }, "type": "object" diff --git a/docs.json b/docs.json index 86152f233..d16c37cd3 100644 --- a/docs.json +++ b/docs.json @@ -5048,6 +5048,11 @@ "rest-api/messages/get-message", "rest-api/messages/update-message", "rest-api/messages/delete-message", + "rest-api/messages/pin-message", + "rest-api/messages/unpin-message", + "rest-api/messages/save-message", + "rest-api/messages/unsave-message", + "rest-api/messages/mark-message-as-interacted", "rest-api/messages/list-all-reactions", "rest-api/messages/list-reactions-with-a-specific-emoji-unicode", "rest-api/messages/add-reaction", @@ -5069,18 +5074,24 @@ "rest-api/conversations/list-conversations", "rest-api/conversations/get-conversation", "rest-api/conversations/delete-conversation", + "rest-api/conversations/list-global-pinned-conversations", + "rest-api/conversations/replace-global-pinned-conversations", "rest-api/conversations/get-user-conversation", "rest-api/conversations/update-user-conversation", "rest-api/conversations/reset-user-conversation", "rest-api/conversations/mark-user-conversation-as-delivered", "rest-api/conversations/mark-user-conversation-as-read", "rest-api/conversations/mark-conversation-messages-as-unread", + "rest-api/conversations/pin-user-conversation", + "rest-api/conversations/unpin-user-conversation", "rest-api/conversations/get-group-conversation", "rest-api/conversations/update-group-conversation", "rest-api/conversations/reset-group-conversation", "rest-api/conversations/mark-group-conversation-as-delivered", "rest-api/conversations/mark-group-conversation-as-read", - "rest-api/conversations/mark-group-conversation-as-unread" + "rest-api/conversations/mark-group-conversation-as-unread", + "rest-api/conversations/pin-group-conversation", + "rest-api/conversations/unpin-group-conversation" ] } ] diff --git a/rest-api/conversations/list-global-pinned-conversations.mdx b/rest-api/conversations/list-global-pinned-conversations.mdx new file mode 100644 index 000000000..1d7b4b876 --- /dev/null +++ b/rest-api/conversations/list-global-pinned-conversations.mdx @@ -0,0 +1,6 @@ +--- +openapi: get /conversations/pinned +description: "List the CometChat global pinned conversations with REST API - the conversations pinned at the top for every end user, in display order." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/conversations/pin-group-conversation.mdx b/rest-api/conversations/pin-group-conversation.mdx new file mode 100644 index 000000000..d26caa2ad --- /dev/null +++ b/rest-api/conversations/pin-group-conversation.mdx @@ -0,0 +1,6 @@ +--- +openapi: post /groups/{guid}/conversation/pin +description: "Pin a CometChat group conversation for a user with REST API so it appears at the top of their conversation list." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/conversations/pin-user-conversation.mdx b/rest-api/conversations/pin-user-conversation.mdx new file mode 100644 index 000000000..7313fd14a --- /dev/null +++ b/rest-api/conversations/pin-user-conversation.mdx @@ -0,0 +1,6 @@ +--- +openapi: post /users/{uid}/conversation/pin +description: "Pin a CometChat one-on-one conversation for a user with REST API so it appears at the top of their conversation list." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/conversations/replace-global-pinned-conversations.mdx b/rest-api/conversations/replace-global-pinned-conversations.mdx new file mode 100644 index 000000000..a92aaf94d --- /dev/null +++ b/rest-api/conversations/replace-global-pinned-conversations.mdx @@ -0,0 +1,6 @@ +--- +openapi: put /conversations/pinned +description: "Replace the full CometChat global pinned conversation list with REST API - the conversations pinned at the top for every end user." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/conversations/unpin-group-conversation.mdx b/rest-api/conversations/unpin-group-conversation.mdx new file mode 100644 index 000000000..0f17fd6d3 --- /dev/null +++ b/rest-api/conversations/unpin-group-conversation.mdx @@ -0,0 +1,6 @@ +--- +openapi: delete /groups/{guid}/conversation/pin +description: "Unpin a CometChat group conversation for a user with REST API, removing that user's own pin." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/conversations/unpin-user-conversation.mdx b/rest-api/conversations/unpin-user-conversation.mdx new file mode 100644 index 000000000..1347b1b52 --- /dev/null +++ b/rest-api/conversations/unpin-user-conversation.mdx @@ -0,0 +1,6 @@ +--- +openapi: delete /users/{uid}/conversation/pin +description: "Unpin a CometChat one-on-one conversation for a user with REST API, removing that user's own pin." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/messages/mark-message-as-interacted.mdx b/rest-api/messages/mark-message-as-interacted.mdx new file mode 100644 index 000000000..1702a12a0 --- /dev/null +++ b/rest-api/messages/mark-message-as-interacted.mdx @@ -0,0 +1,6 @@ +--- +openapi: patch /messages/{id}/interacted +description: "Mark a CometChat message as interacted with REST API on behalf of a user." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/messages/pin-message.mdx b/rest-api/messages/pin-message.mdx new file mode 100644 index 000000000..07ac55da3 --- /dev/null +++ b/rest-api/messages/pin-message.mdx @@ -0,0 +1,6 @@ +--- +openapi: post /messages/{id}/pin +description: "Pin a CometChat message in a one-on-one or group conversation with REST API, as the app or on behalf of a user." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/messages/save-message.mdx b/rest-api/messages/save-message.mdx new file mode 100644 index 000000000..ead01b419 --- /dev/null +++ b/rest-api/messages/save-message.mdx @@ -0,0 +1,6 @@ +--- +openapi: post /messages/{id}/save +description: "Save a CometChat message to a user's private saved list with REST API on behalf of that user." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/messages/unpin-message.mdx b/rest-api/messages/unpin-message.mdx new file mode 100644 index 000000000..dec2fe974 --- /dev/null +++ b/rest-api/messages/unpin-message.mdx @@ -0,0 +1,6 @@ +--- +openapi: delete /messages/{id}/pin +description: "Unpin a pinned CometChat message with REST API. Any user with unpin permission can unpin, not only the user who pinned it." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide). diff --git a/rest-api/messages/unsave-message.mdx b/rest-api/messages/unsave-message.mdx new file mode 100644 index 000000000..7e407d6e1 --- /dev/null +++ b/rest-api/messages/unsave-message.mdx @@ -0,0 +1,6 @@ +--- +openapi: delete /messages/{id}/save +description: "Remove a CometChat message from a user's saved list with REST API on behalf of that user." +--- + +For the complete error reference, see [Error Guide](/articles/error-guide).