# wecloud-im 客户端对接文档


[TOC]


## 生产环境

ws.im199.com

websocket连接示例

```
wss://ws.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
```

_______



## 核心概念说明

### clientId、用户和登录

即时通讯服务中的每一个终端称为一个「Client」。Client 拥有一个在应用内唯一标识自己的 ID（`clientId`）。这个 ID 由应用自己定义，必须是 **由任意英文字母、数字、半角下划线与半角短横线组成，可以纯数字，不超过 64个字符的字符串组成**。在大部分场合，Client 都可以对应到应用中的某个「用户」，但是并不是只有真的用户才能作为「Client」，你完全可以把一个探测器当成一个「Client」，把它收集到的数据通过即时通讯服务广播给更多「人」。

要使用即时通讯服务，每一个终端设备需要首先建立与即时通讯云端的 WebSocket 长连接，并使用唯一的 `clientId` 来加入即时通讯服务，我们把这一过程称为「登录」。请注意这里的登录仅仅指客户端登录即时通讯服务，与应用层面的用户账户注册登录是不一样的。



### 对话（Conversation）

用户登录之后，与其他人进行消息沟通，即为开启了一个「对话（Conversation）」。在即时通讯服务中，「对话」包含了沟通的用户群体（成员），也是所有消息依托的媒介：消息都是由某一个 Client 发往一个「对话」。终端用户在开始聊天之前，需要先创建或者加入一个对话，然后再邀请其他人进来（可选），之后所有参与者在这个对话内进行交流。

### 已读/已接收

**已接收**为客户端接收到该消息,已经保存到本地缓存中,用户还未打开会话查看该条消息的情况. 服务器将不会再次下发已接收状态的离线消息,未接收的消息会在拉取离线消息时返回

**已读**为客户端已经查看该消息

## 客户端登陆api

<img src="https://tva1.sinaimg.cn/large/008i3skNly1gqlielspokj30s80xe0vv.jpg" alt="image-20210517140904878" style="zoom:67%;" />

1. appKey, appSecret为im云下发给客户方安全保护密钥,不建议保存在前端客户端, 
2. 客户前端需提供获取sign的接口, sign 由MD5{timestamp + clientId + appKey + appSecret},其中clientId由后端生成
3. 前端拿到sign后,调用验证sign接口进行获取token
4. websocket连接初始化需要带上token即可连接成功

### 生成sign示例

 java示例代码 ,供客户应用后端参考

```java
private void getSign(String timestemp, String clientId, String appKey, String appSecret) {
  String sign = new MD5().digestHex(timestemp + clientId + appKey + appSecret);
}

public static void main(String[] args)   {
  String clientId = "client_123123";
  String appKey = "elLwpel1gWCHDqZy";
  String appSecret = "68809bb5a9077a83631aeb0b17b5965d6b2302faf2ab3737";
  String timestemp = String.valueOf(new Date().getTime());
  getSign(timestemp, clientId, appKey, appSecret);
}
```

后端需要响应参数示例:

```
{
	"timestamp": "1628838135066",
	"clientId": "client_3334444",
	"appKey": "D13ug9jsWbJbeVx1",
	"sign": "c15a886fe4114dba2c8f078369e6bec9"
}
```

### sign

### 连接websocket

ws://localhost:8899/ws?token=xxxxxx

示例:

```
ws://localhost:8899/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImhhaGFoXzMwIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6ImVsTHdwZWwxZ1dDSERxWnkiLCJleHAiOjE2MjkwOTY0MzksImlhdCI6MTYyMDQ1NjQzOSwianRpIjoiNDA1YzE3MWM2Njc5NGJmMDllNGRjZDdhNzA0ZjY3YTgifQ.7g2J_0q9UnuWszpuapSJUXJEwVevvI8Rm2Srg3594Lk
```



## 请求CMD指令说明

- 1: 发送消息

- 2: RTC

## 响应CMD指令说明

1响应用户请求

2下发在线用户消息

3下发在线事件类型消息

401:无权限 token失效

## 消息type说明

- 文本消息	-1

- 图像消息	-2

- 音频消息	-3

- 视频消息	-4

- 位置消息	-5

- 文件消息	-6

- ### 事件类型type (xx表示为某客户端)

  - xx邀请xx加入会话 -1007
  - xx被xx移出会话 -1008
  - xx已接收某消息 -1009
  - xx已读某条消息 -1010
  - 你被xx拉入新会话 -1011

以上类型均使用负数，所有正数留给自定义扩展类型使用，0 作为「没有类型」被保留起来。

## code错误码

- 401 用户token无效

## websocket客户端请求参数说明

**reqId** 为每次客户端通过websocket通道发送请求的唯一request Id, 用来标识每次请求,方便定位问题,以及用于绑定服务端响应对此请求request id的数据.

websocket像服务端发送数据不同于http请求接口.
 http发送请求 会一个请求对应一个响应,客户端接收也知道该响应数据是针对哪个请求的.

websocket是异步的 有可能你很快速的发送了几条消息,服务器响应的数据不一定是按你发送的消息顺序响应,  所以你每个请求要自己定一个id, 服务器就算乱序响应数据,客户端也能知道响应的数据对应哪个请求

**cmd** 为请求指令

**data** 为数据,所有需要发送的数据都在此参数下

**data内**的参数: **toConversation**(会话id)与**type**(消息类型)为固定的,其它参数名与参数值皆可由使用方自定义




## websocket服务器响应参数说明

**reqId** 一个请求唯一的id,服务端响应时,会将对应的id与数据一同返回

**cmd**  为响应指令

![image-20210521104503728](https://tva1.sinaimg.cn/large/008i3skNly1gqpurt4tgnj30py0dc3zd.jpg)

## 消息收发流程

### 1. 客户端发送文本消息

```json
{
"reqId":"123123123",
"cmd":1,
"data":{
  "push":{
    "title":"收到一条新消息",
    "subTitle":"发给12312123213这是一123个纯文本消息,发给12312123213这是一123个纯文本消息发给12312123213这是一123个纯文本消息"
   },
  "diyAbcd":"aaaa自已定义字段的值",
  "toConversation":1402147846261706752,
  "type":-1,
  "text":"发给12312123213这是一123个纯文本消息,发给12312123213这是一123个纯文本消息发给12312123213这是一123个纯文本消息",
  "attrs":{
    "a":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对",
    "b":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对"
   }
	}
}
```

data里面的参数  除toConversation与type为固定的,其它参数皆可由使用方自定义

push为客户端自定义系统推送内容

### 2. 发送成功服务端响应给发送者

```json
{
    "cmd":2,
    "code":200,
    "msg":"成功",
    "data":{
        "msgId":"1394207796915998720"
    },
    "reqId":"123123123"
}
```

### 3. 接收方收到在线消息

```json
{
    "cmd":1,
    "code":200,
    "msg":"成功",
    "data":{
        "msgId":"1394207796915998720",
        "createTime":1621240016587,
        "withdrawTime":null,
        "sender":"hahah_30",
        "content":{
            "text":"发给12312123213这是一123个纯文本消息,发给12312123213这是一123个纯文本消息发给12312123213这是一123个纯文本消息",
            "type":-1,
            "attrs":{
                "a":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对",
                "b":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对"
            }
        },
        "withdraw":false,
        "event":false,
        "system":false,
        "at":null,
        "conversationId":"1394188055950266368"
    },
    "reqId":null
}
```

### 4.接收方收到,需要回执

已接收回执需参考API对接文档

## 发送图片

```json
{
"reqId":"123123123",
"cmd":1,
"data":{
  "toConversation":1394188055950266368,
  "type":-2,
  "file": {
    "url":      "http://ac-p2bpmgci.clouddn.com/246b8acc-2e12-4a9d-a255-8d17a3059d25", // 必要参数
    "objId":    "54699d87e4b0a56c64f470a4", // 文件对应的AVFile.objectId
    "metaData": {
      "name":   "IMG_20141223.jpeg",   // 图像的名称
      "format": "png",                 // 图像的格式
      "height": 768,                   // 单位：像素
      "width":  1024,                  // 单位：像素
      "size":   18                     // 单位：b
    }
  },
  "attrs":{
    "a":"attrs 存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对",
    "b":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对"
   }
	}
}
```

上面是完整的例子，如果只想简单的发送图像 URL：

```json
{
"reqId":"123123123",
"cmd":1,
"data":{
  "toConversation":1394188055950266368,
  "type":-2,
  "file": {
    "url":      "http://ac-p2bpmgci.clouddn.com/246b8acc-2e12-4a9d-a255-8d17a3059d25", // 必要参数
    "objId":    "54699d87e4b0a56c64f470a4", // 文件对应的AVFile.objectId
    "metaData": {
      "name":   "IMG_20141223.jpeg",   // 图像的名称
      "format": "png",                 // 图像的格式
      "height": 768,                   // 单位：像素
      "width":  1024,                  // 单位：像素
      "size":   18                     // 单位：b
    }
	}
}
```

## 其他富媒体消息 

如视频 位置 音频 发送红包  好友验证等等

可参考:https://leancloud.cn/docs/realtime_v2.html#hash939050100

```json
{
"reqId":"123123123",
"cmd":1,
"data":{
  "toConversation":1394188055950266368,
  "type":由应用自定义,
  "应用自定义参数": 应用自定义值
	}
}
```



## 客户端在线接收事件类型消息

### 事件类型type (xx表示为某客户端)

- xx邀请xx加入会话 -1007
- xx被xx移出会话 -1008
- xx已接收某消息 -1009
- xx已读某条消息 -1010
- 你被xx拉入新会话 -1011

### 服务端在线下发 某消息*已接收*状态

receiverId:接收方客户端id 

conversationId:会话id

type为-1009 : 某消息已接收状态

msgId: 消息id;

该event事件消息类型不需要回执,不会保存进离线,仅下发给当前在线会话客户端. 


```json
{
    "cmd":3,
    "code":200,
    "msg":"成功",
    "data":{
        "msgId":1427109835333308416,
        "createTime":1629086007054,
        "withdrawTime":null,
        "sender":"aaaaa1",
        "content":{
            "receiverId":"aaaaa1",
            "type":"-1009"
        },
        "withdraw":false,
        "event":true,
        "system":false,
        "at":null,
        "conversationId":1427109730563788800
    },
    "reqId":null
}
```

### 服务端在线下发 某消息*已读*状态

receiverId:接收方客户端id 

conversationId:会话id

type为-1010 : 某消息已读状态

msgId: 消息id;

该event事件消息类型不需要回执,不会保存进离线,仅下发给当前在线会话客户端. 


```json
{
    "cmd":3,
    "code":200,
    "msg":"成功",
    "data":{
        "msgId":1427109835333308416,
        "createTime":1629086007084,
        "withdrawTime":null,
        "sender":"aaaaa1",
        "content":{
            "receiverId":"aaaaa1",
            "type":"-1010"
        },
        "withdraw":false,
        "event":true,
        "system":false,
        "at":null,
        "conversationId":1427109730563788800
    },
    "reqId":null
}
```


#  API 文档


**简介**:wecloud_im API Documents

**HOST**:https://ws.im199.com/


[TOC]




# token相关


## 验证sign,并返回token


**接口地址**:`/api/token/verify`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:根据客户方生成签名字符串 验证通过则下发token


**请求示例**:


```javascript
{
	"timestamp": "",
	"clientId": "",
	"appKey": "",
	"sign": ""
}
```


**请求参数**:


| 参数名称              | 参数说明             | in     | 是否必须 | 数据类型      | schema        |
| --------------------- | -------------------- | ------ | -------- | ------------- | ------------- |
| imTokenVerify         | imTokenVerify        | body   | true     | ImTokenVerify | ImTokenVerify |
| &emsp;&emsp;timestamp | 时间戳               |        | false    | string        |               |
| &emsp;&emsp;clientId  | client客户端id       |        | false    | string        |               |
| &emsp;&emsp;appKey    | appkey               |        | false    | string        |               |
| &emsp;&emsp;sign      | 签名sign             |        | false    | string        |               |
| token                 | Token Request Header | header | false    | string        |               |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«TokenVo» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称               | 参数说明                               | 类型           | schema         |
| ---------------------- | -------------------------------------- | -------------- | -------------- |
| code                   |                                        | integer(int32) | integer(int32) |
| message                |                                        | string         |                |
| data                   |                                        | TokenVo        | TokenVo        |
| &emsp;&emsp;token      |                                        | string         |                |
| &emsp;&emsp;id         | 客户端id                               | integer(int64) |                |
| &emsp;&emsp;attributes | 可选	自定义属性，供开发者扩展使用。 | string         |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": {
		"token": "",
		"id": 0,
		"attributes": ""
	}
}
```


# 会话表


## 创建会话


**接口地址**:`/api/conversation/create`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:后台可配置:两个客户端如果已经创建过会话,是否重复创建会话


**请求示例**:


```javascript
{
	"name": "",
	"attributes": {},
	"clientIds": []
}
```


**请求参数**:


| 参数名称               | 参数说明                                                  | in     | 是否必须 | 数据类型             | schema               |
| ---------------------- | --------------------------------------------------------- | ------ | -------- | -------------------- | -------------------- |
| imConversationCreate   | imConversationCreate                                      | body   | true     | ImConversationCreate | ImConversationCreate |
| &emsp;&emsp;name       | 可选	 对话的名字，可为群组命名。                       |        | false    | string               |                      |
| &emsp;&emsp;attributes | json格式,可选	自定义属性，供开发者扩展使用。           |        | false    | object               |                      |
| &emsp;&emsp;clientIds  | 可选 邀请加入会话的客户端,如创建单聊,则填入对方的clientId |        | false    | array                | string               |
| token                  | Token Request Header                                      | header | false    | string               |                      |


**响应状态**:


| 状态码 | 说明         | schema                            |
| ------ | ------------ | --------------------------------- |
| 200    | OK           | ApiResult«ImConversationCreateVo» |
| 201    | Created      |                                   |
| 401    | Unauthorized |                                   |
| 403    | Forbidden    |                                   |
| 404    | Not Found    |                                   |


**响应参数**:


| 参数名称       | 参数说明 | 类型                   | schema                 |
| -------------- | -------- | ---------------------- | ---------------------- |
| code           |          | integer(int32)         | integer(int32)         |
| message        |          | string                 |                        |
| data           |          | ImConversationCreateVo | ImConversationCreateVo |
| &emsp;&emsp;id | 会话id   | integer(int64)         |                        |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": {
		"id": 0
	}
}
```


## 批量修改单向隐藏或显示会话


**接口地址**:`/api/conversation/displayUpdate`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:拉取会话列表不展示已隐藏状态的会话,云端聊天记录不删除;假设有A和B两个用户,A删会话,B还能发; 如果B发了消息,A这边要重新把会话显示出来,并能显示之前的聊天记录


**请求示例**:


```javascript
{
	"conversationIds": [],
	"displayStatus": 0
}
```


**请求参数**:


| 参数名称                    | 参数说明                    | in     | 是否必须 | 数据类型             | schema               |
| --------------------------- | --------------------------- | ------ | -------- | -------------------- | -------------------- |
| imConversationDisplayUpdate | imConversationDisplayUpdate | body   | true     | 修改是否单向隐藏会话 | 修改是否单向隐藏会话 |
| &emsp;&emsp;conversationIds | 会话id                      |        | false    | array                | integer              |
| &emsp;&emsp;displayStatus   | 显示状态 1显示 0不显示      |        | false    | integer(int32)       |                      |
| token                       | Token Request Header        | header | false    | string               |                      |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```


## 查询加入的会话列表


**接口地址**:`/api/conversation/getList`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:查询用户加入的非隐藏状态的会话列表 与每个会话的未读条数 成员


**请求参数**:


| 参数名称 | 参数说明             | in     | 是否必须 | 数据类型 | schema |
| -------- | -------------------- | ------ | -------- | -------- | ------ |
| token    | Token Request Header | header | false    | string   |        |


**响应状态**:


| 状态码 | 说明         | schema                                |
| ------ | ------------ | ------------------------------------- |
| 200    | OK           | ApiResult«List«MyConversationListVo»» |
| 201    | Created      |                                       |
| 401    | Unauthorized |                                       |
| 403    | Forbidden    |                                       |
| 404    | Not Found    |                                       |


**响应参数**:


| 参数名称                                 | 参数说明                                           | 类型              | schema               |
| ---------------------------------------- | -------------------------------------------------- | ----------------- | -------------------- |
| code                                     |                                                    | integer(int32)    | integer(int32)       |
| message                                  |                                                    | string            |                      |
| data                                     |                                                    | array             | MyConversationListVo |
| &emsp;&emsp;id                           | 会话id                                             | integer(int64)    |                      |
| &emsp;&emsp;createTime                   | 创建时间                                           | string(date-time) |                      |
| &emsp;&emsp;creator                      | 创建者客户端id                                     | string            |                      |
| &emsp;&emsp;name                         | 可选	 对话的名字，可为群组命名。                | string            |                      |
| &emsp;&emsp;attributes                   | 可选	自定义属性，供开发者扩展使用。             | object            |                      |
| &emsp;&emsp;system                       | 可选	对话类型标志，是否是系统对话，后面会说明。 | boolean           |                      |
| &emsp;&emsp;msgNotReadCount              | 未读消息条数                                       | integer(int64)    |                      |
| &emsp;&emsp;members                      | 成员                                               | string            |                      |
| &emsp;&emsp;lastMsg                      | 会话最后一条消息                                   | OfflineMsgDto     | OfflineMsgDto        |
| &emsp;&emsp;&emsp;&emsp;msgId            | 消息id                                             |                   | false                |
| &emsp;&emsp;&emsp;&emsp;createTime       | 创建时间                                           |                   | false                |
| &emsp;&emsp;&emsp;&emsp;withdrawTime     | 撤回时间                                           |                   | false                |
| &emsp;&emsp;&emsp;&emsp;sender           | 发送者客户端id                                     |                   | false                |
| &emsp;&emsp;&emsp;&emsp;content          | 内容                                               |                   | false                |
| &emsp;&emsp;&emsp;&emsp;withdraw         | 0未撤回; 1已撤回                                   |                   | false                |
| &emsp;&emsp;&emsp;&emsp;event            | 0非事件; 1为事件                                   |                   | false                |
| &emsp;&emsp;&emsp;&emsp;system           | 0非系统通知; 1为系统通知                           |                   | false                |
| &emsp;&emsp;&emsp;&emsp;at               | at他人,传入客户端id数组                            |                   | false                |
| &emsp;&emsp;&emsp;&emsp;notReadCount     | 未读人数统计,全部人已读为0                         |                   | false                |
| &emsp;&emsp;&emsp;&emsp;notReceiverCount | 未接收人数统计,全部人已接收为0                     |                   | false                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": [
		{
			"id": 0,
			"createTime": "",
			"creator": "",
			"name": "",
			"attributes": {},
			"system": true,
			"msgNotReadCount": 0,
			"members": "",
			"lastMsg": {
				"msgId": 0,
				"createTime": "",
				"withdrawTime": "",
				"sender": "",
				"content": "",
				"withdraw": true,
				"event": true,
				"system": true,
				"at": "",
				"notReadCount": 0,
				"notReceiverCount": 0
			}
		}
	]
}
```


# 消息存储表


## 查询某个会话历史消息分页列表


**接口地址**:`/api/imMessage/getHistoryMsg`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"conversationId": 0,
	"pageIndex": 1,
	"pageSorts": [
		{
			"column": "",
			"asc": true
		}
	],
	"pageSize": 10,
	"keyword": ""
}
```


**请求参数**:


| 参数名称                       | 参数说明                  | in     | 是否必须 | 数据类型                  | schema                    |
| ------------------------------ | ------------------------- | ------ | -------- | ------------------------- | ------------------------- |
| imHistoryMessagePageParam      | imHistoryMessagePageParam | body   | true     | ImHistoryMessagePageParam | ImHistoryMessagePageParam |
| &emsp;&emsp;conversationId     | 会话id                    |        | false    | integer(int64)            |                           |
| &emsp;&emsp;pageIndex          | 页码,默认为1              |        | false    | integer(int64)            |                           |
| &emsp;&emsp;pageSorts          | 排序                      |        | false    | array                     | OrderItem                 |
| &emsp;&emsp;&emsp;&emsp;column |                           |        | false    | string                    |                           |
| &emsp;&emsp;&emsp;&emsp;asc    |                           |        | false    | boolean                   |                           |
| &emsp;&emsp;pageSize           | 页大小,默认为10           |        | false    | integer(int64)            |                           |
| &emsp;&emsp;keyword            | 搜索字符串                |        | false    | string                    |                           |
| token                          | Token Request Header      | header | false    | string                    |                           |


**响应状态**:


| 状态码 | 说明         | schema                                 |
| ------ | ------------ | -------------------------------------- |
| 200    | OK           | ApiResult«分页结果对象«OfflineMsgDto»» |
| 201    | Created      |                                        |
| 401    | Unauthorized |                                        |
| 403    | Forbidden    |                                        |
| 404    | Not Found    |                                        |


**响应参数**:


| 参数名称                                 | 参数说明                       | 类型                        | schema                      |
| ---------------------------------------- | ------------------------------ | --------------------------- | --------------------------- |
| code                                     |                                | integer(int32)              | integer(int32)              |
| message                                  |                                | string                      |                             |
| data                                     |                                | 分页结果对象«OfflineMsgDto» | 分页结果对象«OfflineMsgDto» |
| &emsp;&emsp;total                        | 总行数                         | integer(int64)              |                             |
| &emsp;&emsp;records                      | 数据列表                       | array                       | OfflineMsgDto               |
| &emsp;&emsp;&emsp;&emsp;msgId            | 消息id                         |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;createTime       | 创建时间                       |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;withdrawTime     | 撤回时间                       |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;sender           | 发送者客户端id                 |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;content          | 内容                           |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;withdraw         | 0未撤回; 1已撤回               |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;event            | 0非事件; 1为事件               |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;system           | 0非系统通知; 1为系统通知       |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;at               | at他人,传入客户端id数组        |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;notReadCount     | 未读人数统计,全部人已读为0     |                             | false                       |
| &emsp;&emsp;&emsp;&emsp;notReceiverCount | 未接收人数统计,全部人已接收为0 |                             | false                       |
| &emsp;&emsp;pageIndex                    | 页码                           | integer(int64)              |                             |
| &emsp;&emsp;pageSize                     | 页大小                         | integer(int64)              |                             |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": {
		"total": 0,
		"records": [
			{
				"msgId": 0,
				"createTime": "",
				"withdrawTime": "",
				"sender": "",
				"content": "",
				"withdraw": true,
				"event": true,
				"system": true,
				"at": "",
				"notReadCount": 0,
				"notReceiverCount": 0
			}
		],
		"pageIndex": 0,
		"pageSize": 0
	}
}
```


## 离线消息列表


**接口地址**:`/api/imMessage/offlineList`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求参数**:


| 参数名称 | 参数说明             | in     | 是否必须 | 数据类型 | schema |
| -------- | -------------------- | ------ | -------- | -------- | ------ |
| token    | Token Request Header | header | false    | string   |        |


**响应状态**:


| 状态码 | 说明         | schema                                  |
| ------ | ------------ | --------------------------------------- |
| 200    | OK           | ApiResult«List«ImMessageOfflineListVo»» |
| 201    | Created      |                                         |
| 401    | Unauthorized |                                         |
| 403    | Forbidden    |                                         |
| 404    | Not Found    |                                         |


**响应参数**:


| 参数名称                                 | 参数说明                       | 类型           | schema                 |
| ---------------------------------------- | ------------------------------ | -------------- | ---------------------- |
| code                                     |                                | integer(int32) | integer(int32)         |
| message                                  |                                | string         |                        |
| data                                     |                                | array          | ImMessageOfflineListVo |
| &emsp;&emsp;conversationId               | 会话id                         | integer(int64) |                        |
| &emsp;&emsp;msgList                      | 消息列表                       | array          | OfflineMsgDto          |
| &emsp;&emsp;&emsp;&emsp;msgId            | 消息id                         |                | false                  |
| &emsp;&emsp;&emsp;&emsp;createTime       | 创建时间                       |                | false                  |
| &emsp;&emsp;&emsp;&emsp;withdrawTime     | 撤回时间                       |                | false                  |
| &emsp;&emsp;&emsp;&emsp;sender           | 发送者客户端id                 |                | false                  |
| &emsp;&emsp;&emsp;&emsp;content          | 内容                           |                | false                  |
| &emsp;&emsp;&emsp;&emsp;withdraw         | 0未撤回; 1已撤回               |                | false                  |
| &emsp;&emsp;&emsp;&emsp;event            | 0非事件; 1为事件               |                | false                  |
| &emsp;&emsp;&emsp;&emsp;system           | 0非系统通知; 1为系统通知       |                | false                  |
| &emsp;&emsp;&emsp;&emsp;at               | at他人,传入客户端id数组        |                | false                  |
| &emsp;&emsp;&emsp;&emsp;notReadCount     | 未读人数统计,全部人已读为0     |                | false                  |
| &emsp;&emsp;&emsp;&emsp;notReceiverCount | 未接收人数统计,全部人已接收为0 |                | false                  |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": [
		{
			"conversationId": 0,
			"msgList": [
				{
					"msgId": 0,
					"createTime": "",
					"withdrawTime": "",
					"sender": "",
					"content": "",
					"withdraw": true,
					"event": true,
					"system": true,
					"at": "",
					"notReadCount": 0,
					"notReceiverCount": 0
				}
			]
		}
	]
}
```


## 修改消息体


**接口地址**:`/api/imMessage/updateMsgById`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:只能修改客户端自己发送的消息


**请求示例**:


```javascript
{
	"msgId": 0,
	"content": {}
}
```


**请求参数**:


| 参数名称            | 参数说明             | in     | 是否必须 | 数据类型       | schema      |
| ------------------- | -------------------- | ------ | -------- | -------------- | ----------- |
| imMsgUpdate         | imMsgUpdate          | body   | true     | ImMsgUpdate    | ImMsgUpdate |
| &emsp;&emsp;msgId   | 消息id               |        | false    | integer(int64) |             |
| &emsp;&emsp;content | 内容                 |        | false    | object         |             |
| token               | Token Request Header | header | false    | string         |             |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```


## 消息撤回


**接口地址**:`/api/imMessage/withdraw`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:只能撤回客户端自己发送的消息


**请求参数**:


| 参数名称 | 参数说明             | in     | 是否必须 | 数据类型       | schema |
| -------- | -------------------- | ------ | -------- | -------------- | ------ |
| msgId    | msgId                | query  | true     | integer(int64) |        |
| token    | Token Request Header | header | false    | string         |        |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```


# 消息收件箱表


## 消息修改为已读状态


**接口地址**:`/api/imInbox/msgReadUpdate`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"msgIds": []
}
```


**请求参数**:


| 参数名称              | 参数说明                                                     | in     | 是否必须 | 数据类型              | schema                |
| --------------------- | ------------------------------------------------------------ | ------ | -------- | --------------------- | --------------------- |
| imMsgReadStatusUpdate | imMsgReadStatusUpdate                                        | body   | true     | ImMsgReadStatusUpdate | ImMsgReadStatusUpdate |
| &emsp;&emsp;msgIds    | 消息id数组,可以传入单个或多个, 如接收离线消息列表时可以批量修改 则传入多个 |        | false    | array                 | integer               |
| token                 | Token Request Header                                         | header | false    | string                |                       |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```


## 消息修改为已接收状态


**接口地址**:`/api/imInbox/msgReceivedUpdate`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"msgIds": [],
	"readStatus": true
}
```


**请求参数**:


| 参数名称               | 参数说明                                                     | in     | 是否必须 | 数据类型                  | schema                    |
| ---------------------- | ------------------------------------------------------------ | ------ | -------- | ------------------------- | ------------------------- |
| imMsgReceivedUpdate    | imMsgReceivedUpdate                                          | body   | true     | ImMsgReceivedStatusUpdate | ImMsgReceivedStatusUpdate |
| &emsp;&emsp;msgIds     | 消息id数组,可以传入单个或多个, 如接收离线消息列表时可以批量修改 则传入多个 |        | false    | array                     | integer                   |
| &emsp;&emsp;readStatus | 是否同时修改为已读状态                                       |        | false    | boolean                   |                           |
| token                  | Token Request Header                                         | header | false    | string                    |                           |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```



# 终端


## 添加或修改推送设备信息(每次请求都会覆盖之前的数据)


**接口地址**:`/api/imClient/addDeviceInfo`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"valid": 0,
	"deviceType": 0,
	"deviceToken": ""
}
```


**请求参数**:


| 参数名称                | 参数说明                         | in     | 是否必须 | 数据类型               | schema                 |
| ----------------------- | -------------------------------- | ------ | -------- | ---------------------- | ---------------------- |
| imClientDevice          | imClientDevice                   | body   | true     | 添加或修改推送设备信息 | 添加或修改推送设备信息 |
| &emsp;&emsp;valid       | 设备不想收到推送提醒, 1想, 0不想 |        | false    | integer(int32)         |                        |
| &emsp;&emsp;deviceType  | 设备类型1:ios; 2:android         |        | false    | integer(int32)         |                        |
| &emsp;&emsp;deviceToken | 设备推送token                    |        | false    | string                 |                        |
| token                   | Token Request Header             | header | false    | string                 |                        |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |

**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```


## 获取用户在线状态(批量)


**接口地址**:`/api/imClient/onlineStatus`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"clientIds": []
}
```


**请求参数**:


| 参数名称              | 参数说明             | in     | 是否必须 | 数据类型             | schema               |
| --------------------- | -------------------- | ------ | -------- | -------------------- | -------------------- |
| getOnlineStatusParam  | getOnlineStatusParam | body   | true     | GetOnlineStatusParam | GetOnlineStatusParam |
| &emsp;&emsp;clientIds | 客户端ID             |        | false    | array                | string               |
| token                 | Token Request Header | header | false    | string               |                      |


**响应状态**:


| 状态码 | 说明         | schema                            |
| ------ | ------------ | --------------------------------- |
| 200    | OK           | ApiResult«List«ImOnlineStatusVo»» |
| 201    | Created      |                                   |
| 401    | Unauthorized |                                   |
| 403    | Forbidden    |                                   |
| 404    | Not Found    |                                   |


**响应参数**:


| 参数名称             | 参数说明                | 类型           | schema           |
| -------------------- | ----------------------- | -------------- | ---------------- |
| code                 |                         | integer(int32) | integer(int32)   |
| message              |                         | string         |                  |
| data                 |                         | array          | ImOnlineStatusVo |
| &emsp;&emsp;status   | true:在线, false 不在线 | boolean        |                  |
| &emsp;&emsp;clientId |                         | string         |                  |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": [
		{
			"status": true,
			"clientId": ""
		}
	]
}
```


# 获取sign(Demo)


## 获取sign(仅测试使用)


**接口地址**:`/api/signDemo/get`


**请求方式**:`GET`


**请求数据类型**:`*`


**响应数据类型**:`*/*`


**接口描述**:生成签名


**请求示例**:


```javascript
{
	"timestamp": "",
	"clientId": "",
	"appKey": "",
	"appSecret": ""
}
```


**请求参数**:


| 参数名称              | 参数说明             | in     | 是否必须 | 数据类型     | schema       |
| --------------------- | -------------------- | ------ | -------- | ------------ | ------------ |
| getSignParam          | getSignParam         | body   | true     | GetSignParam | GetSignParam |
| &emsp;&emsp;timestamp | 时间戳               |        | false    | string       |              |
| &emsp;&emsp;clientId  | client客户端id       |        | false    | string       |              |
| &emsp;&emsp;appKey    | appKey               |        | false    | string       |              |
| &emsp;&emsp;appSecret | 密钥                 |        | false    | string       |              |
| token                 | Token Request Header | header | false    | string       |              |


**响应状态**:


| 状态码 | 说明         | schema |
| ------ | ------------ | ------ |
| 200    | OK           |        |
| 401    | Unauthorized |        |
| 403    | Forbidden    |        |
| 404    | Not Found    |        |


**响应参数**:


暂无


**响应示例**:

```javascript

```


# 黑名单


## 拉入黑名单


**接口地址**:`/api/ClientBlacklist/add`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"clientIdBePrevent": ""
}
```


**请求参数**:


| 参数名称                      | 参数说明                | in     | 是否必须 | 数据类型                | schema                  |
| ----------------------------- | ----------------------- | ------ | -------- | ----------------------- | ----------------------- |
| imClientBlacklistUpdate       | imClientBlacklistUpdate | body   | true     | ImClientBlacklistUpdate | ImClientBlacklistUpdate |
| &emsp;&emsp;clientIdBePrevent | 被拉黑者id              |        | false    | string                  |                         |
| token                         | Token Request Header    | header | false    | string                  |                         |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```


## 移出黑名单


**接口地址**:`/api/ClientBlacklist/delete`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"clientIdBePrevent": ""
}
```


**请求参数**:


| 参数名称                      | 参数说明                | in     | 是否必须 | 数据类型                | schema                  |
| ----------------------------- | ----------------------- | ------ | -------- | ----------------------- | ----------------------- |
| imClientBlacklistUpdate       | imClientBlacklistUpdate | body   | true     | ImClientBlacklistUpdate | ImClientBlacklistUpdate |
| &emsp;&emsp;clientIdBePrevent | 被拉黑者id              |        | false    | string                  |                         |
| token                         | Token Request Header    | header | false    | string                  |                         |


**响应状态**:


| 状态码 | 说明         | schema             |
| ------ | ------------ | ------------------ |
| 200    | OK           | ApiResult«boolean» |
| 201    | Created      |                    |
| 401    | Unauthorized |                    |
| 403    | Forbidden    |                    |
| 404    | Not Found    |                    |


**响应参数**:


| 参数名称 | 参数说明 | 类型           | schema         |
| -------- | -------- | -------------- | -------------- |
| code     |          | integer(int32) | integer(int32) |
| message  |          | string         |                |
| data     |          | boolean        |                |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": true
}
```


## 黑名单分页列表


**接口地址**:`/api/ClientBlacklist/getPageList`


**请求方式**:`POST`


**请求数据类型**:`application/json`


**响应数据类型**:`*/*`


**接口描述**:


**请求示例**:


```javascript
{
	"pageIndex": 1,
	"pageSorts": [
		{
			"column": "",
			"asc": true
		}
	],
	"pageSize": 10,
	"keyword": ""
}
```


**请求参数**:


| 参数名称                       | 参数说明                   | in     | 是否必须 | 数据类型       | schema         |
| ------------------------------ | -------------------------- | ------ | -------- | -------------- | -------------- |
| imClientBlacklistPageParam     | imClientBlacklistPageParam | body   | true     | 黑名单分页参数 | 黑名单分页参数 |
| &emsp;&emsp;pageIndex          | 页码,默认为1               |        | false    | integer(int64) |                |
| &emsp;&emsp;pageSorts          | 排序                       |        | false    | array          | OrderItem      |
| &emsp;&emsp;&emsp;&emsp;column |                            |        | false    | string         |                |
| &emsp;&emsp;&emsp;&emsp;asc    |                            |        | false    | boolean        |                |
| &emsp;&emsp;pageSize           | 页大小,默认为10            |        | false    | integer(int64) |                |
| &emsp;&emsp;keyword            | 搜索字符串                 |        | false    | string         |                |
| token                          | Token Request Header       | header | false    | string         |                |


**响应状态**:


| 状态码 | 说明         | schema                                                |
| ------ | ------------ | ----------------------------------------------------- |
| 200    | OK           | ApiResult«分页结果对象«ImClientBlacklistQueryVo对象»» |
| 201    | Created      |                                                       |
| 401    | Unauthorized |                                                       |
| 403    | Forbidden    |                                                       |
| 404    | Not Found    |                                                       |


**响应参数**:


| 参数名称                                  | 参数说明   | 类型                                       | schema                                     |
| ----------------------------------------- | ---------- | ------------------------------------------ | ------------------------------------------ |
| code                                      |            | integer(int32)                             | integer(int32)                             |
| message                                   |            | string                                     |                                            |
| data                                      |            | 分页结果对象«ImClientBlacklistQueryVo对象» | 分页结果对象«ImClientBlacklistQueryVo对象» |
| &emsp;&emsp;total                         | 总行数     | integer(int64)                             |                                            |
| &emsp;&emsp;records                       | 数据列表   | array                                      | ImClientBlacklistQueryVo对象               |
| &emsp;&emsp;&emsp;&emsp;clientIdBePrevent | 被拉黑者id |                                            | false                                      |
| &emsp;&emsp;pageIndex                     | 页码       | integer(int64)                             |                                            |
| &emsp;&emsp;pageSize                      | 页大小     | integer(int64)                             |                                            |


**响应示例**:

```javascript
{
	"code": 0,
	"message": "",
	"data": {
		"total": 0,
		"records": [
			{
				"clientIdBePrevent": ""
			}
		],
		"pageIndex": 0,
		"pageSize": 0
	}
}
```