====== 消息管理 ======
更新时间:2022-08-12
本文展示如何调用环信 IM REST API 在服务端实现全类型消息的发送与接收、消息附件上传和下载、获取历史消息、服务端消息撤回、服务端单向删除会话等。支持消息类型包括文本消息、图片消息、语音消息、视频消息、透传消息和自定义消息。
===== 前提条件 =====
要调用环信即时通讯 REST API,请确保满足以下要求:
* 已在环信即时通讯控制台 [[https://docs-im.easemob.com/ccim/config|开通配置环信即时通讯 IM 服务]]。
* 了解环信 IM REST API 的调用频率限制,详见[[https://docs-im.easemob.com/ccim/limitationapi|接口频率限制]]。
===== 公共参数 =====
==== 请求参数 ====
^参数 ^类型 ^是否必需 ^描述 ^
|''%%host%%'' |String |是 |你在环信即时通讯 IM 管理后台注册项目时所在的集群服务器地址。 |
|''%%org_name%%'' |String |是 |即时通讯服务分配给每个企业(组织)的唯一标识。 |
|''%%app_name%%'' |String |是 |你在环信即时通讯 IM 管理后台注册项目时填入的应用名称。 |
|''%%username%%'' |String |是 |用户 ID。 |
==== 响应参数 ====
^参数 ^类型 ^描述 ^
|''%%action%%'' |String |请求方式,即接口方法名。 |
|''%%organization%%'' |String |即 ''%%org_name%%'',即时通讯服务分配给每个企业(组织)的唯一标识。 |
|''%%application%%'' |String |应用在系统内的唯一标识。该标识由系统生成,开发者无需关心。 |
|''%%applicationName%%'' |String |即 ''%%app_name%%'',你在环信即时通讯 IM 管理后台注册项目时填入的应用名称。 |
|''%%uri%%'' |String |请求 URL。 |
|''%%path%%'' |String |请求路径,属于请求 URL 的一部分,开发者无需关注。 |
|''%%entities%%'' |JSON |详细信息。 |
|''%%host%%'' |String |你在环信即时通讯 IM 管理后台注册项目时所在的集群服务器地址。 |
|''%%data%%'' |JSON |实际获取的数据详情。 |
|''%%uuid%%'' |String |消息附件的唯一标识。该标识由系统生成,开发者无需关心。 |
|''%%username%%'' |String |用户 ID。 |
|''%%timestamp%%'' |Long |HTTP 响应的 Unix 时间戳,单位为毫秒。 |
|''%%duration%%'' |Int |从发送 HTTP 请求到响应的时长,单位为毫秒。 |
===== 认证方式 =====
环信即时通讯 REST API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 Authorization 字段:
Authorization:''%%Bearer ${YourAppToken}%%''
为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。本篇涉及的所有消息管理 REST API 都需要使用 App Token 的鉴权方式,详见 [[https://docs-im.easemob.com/ccim/authentication|使用 app token 鉴权]]。
===== 发送消息 =====
在服务端实现用户到用户,用户到群组或用户到聊天室的消息发送与接收。消息类型包括文本、图片、语音、视频、透传以及自定义消息。
^消息类型 ^描述 ^
|文本/透传消息 |调用发送消息方法,在请求 body 中传入消息内容。 |
|图片/语音/视频/文件消息 |1. 调用[[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传方法]]上传图片、语音、视频或其他类型文件,并从响应 body 中获取文件 uuid。
2. 调用发送消息方法,在请求 body 中传入该 uuid。 |
调用服务端接口发送消息时,可选的 ''%%from%%'' 字段用于指定发送方。
此外,消息支持扩展属性 ''%%ext%%'',可添加自定义信息。同时,推送通知也支持自定义扩展字段,详见 [[https://docs-im.easemob.com/ccim/ios/push#自定义显示|APNs 自定义显示]] 和 [[https://docs-im.easemob.com/ccim/android/push#自定义显示|Android 推送字段说明]]。
**注意**
在调用程序中,请求体若超过 5 KB 会导致 413 错误,需要拆成几个更小的请求体重试。同时,请求体和扩展字段的总长度不能超过 3 KB。
==== 发送单聊消息 ====
=== HTTP 请求 ===
POST https://{host}/{org_name}/{app_name}/messages/users
== 路径参数 ==
参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
== 请求 header ==
^ 参数 ^类型 ^ 是否必需 ^ 描述 ^
| ''%%Content-Type%%'' |String | 是 | 内容类型。请填 ''%%application/json%%''。 |
| ''%%Accept%%'' |String | 是 | 内容类型。请填 ''%%application/json%%''。 |
| ''%%Authorization%%'' |String | 是 | ''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
=== 通用请求体 ===
通用请求体为 JSON 对象,是所有消息的外层结构。不同类型的消息只是 ''%%body%%'' 字段内容存在差异。
^参数 ^类型 ^是否必需 ^描述 ^
|''%%from%%'' |String |否 |消息发送方的用户 ID。若不传入该字段,服务器默认设置为管理员,即 “admin”;若传入字段但值为空字符串 (“”),请求失败。 |
|''%%to%%'' |List |是 |消息接收方的用户 ID 数组。每次可发送的接收方用户上限为 600 人,即 600 条消息。每分钟最多可向 6000 个用户发送信息。 |
|''%%type%%'' |String |是 |消息类型:
- ''%%txt%%'':文本消息;
- ''%%img%%'':图片消息;
- ''%%audio%%'':语音消息;
- ''%%video%%'':视频消息;
- ''%%file%%'':文件消息;
- ''%%loc%%'':位置消息;
- ''%%cmd%%'':透传消息;
- ''%%custom%%'':自定义消息。 |
|''%%body%%'' |JSON |是 |消息内容。对于不同消息类型 ,body 包含的字段不同,详情见下表。 |
|''%%sync_device%%'' |Bool |否 |消息发送成功后,是否将消息同步到发送方。
- ''%%true%%'':是;
- (默认)''%%false%%'':否。 |
|''%%routetype%%'' |String |否 |若传入该参数,其值为 “ROUTE_ONLINE”,表示只有接收方在线时,消息才能成功发送;若接收方离线,消息发送失败。若不传入该字段,接收方离线时,消息也能成功发送。 |
|''%%ext%%'' |JSON |否 |消息支持扩展字段,可添加自定义信息。同时,推送通知也支持自定义扩展字段,详见 [[https://docs-im.easemob.com/ccim/ios/push#自定义显示|APNs 自定义显示]] 和 [[https://docs-im.easemob.com/ccim/android/push#自定义显示|Android 推送字段说明]]。 |
=== body 字段说明 ===
== 文本消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%msg%%'' |String |是 |消息内容。 |
== 图片消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%filename%%'' |String |是 |图片名称。 |
|''%%secret%%'' |String |否 |图片的访问密钥。成功上传图片后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取的 share-secret。如果图片文件上传时设置了文件访问限制(restrict-access),则该字段为必填。 |
|''%%size%%'' |JSON |是 |图片尺寸,单位为像素,包含以下字段:
- height:图片高度;
- width:图片宽度。 |
|''%%url%%'' |String |是 |图片 URL 地址:''%%https://{host}/{org_name}/{app_name}/chatfiles/{uuid}%%''。其中 ''%%uuid%%'' 为文件 ID,成功上传图片文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取。 |
== 语音消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%filename%%'' |String |是 |语音文件的名称。 |
|''%%secret%%'' |String |否 |语音文件访问密钥,成功上传语音文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取的 share-secret。 如果语音文件上传时设置了文件访问限制(restrict-access),则该字段为必填。 |
|''%%Length%%'' |Int |是 |语音时长,单位为秒。 |
|''%%url%%'' |String |是 |语音文件 URL 地址:''%%https://{host}/{org_name}/{app_name}/chatfiles/{uuid}%%''。uuid 为文件 ID,成功上传语音文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取。 |
== 视频消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%thumb%%'' |String |是 |视频缩略图 URL 地址:''%%https://{host}/{org_name}/{app_name}/chatfiles/{uuid}%%''。uuid 为视频缩略图唯一标识,成功上传缩略图文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取。 |
|''%%length%%'' |Int |是 |视频时长,单位为秒。 |
|''%%secret%%'' |String |否 |视频文件访问密钥,成功上传视频文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取的 share-secret。如果视频文件上传时设置了文件访问限制(restrict-access),则该字段为必填。 |
|''%%file_length%%'' |Long |是 |视频文件大小,单位为字节。 |
|''%%thumb_secret%%'' |String |否 |视频缩略图访问密钥,成功上传视频文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取的 share-secret。如果缩略图文件上传时设置了文件访问限制(restrict-access),则该字段为必填。 |
|''%%url%%'' |String |是 |视频文件 URL 地址:''%%https://{host}/{org_name}/{app_name}/chatfiles/{uuid}%%''。其中 ''%%uuid%%'' 为文件 ID,成功上传视频文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取。 |
== 文件消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%filename%%'' |String |是 |文件名称。 |
|''%%secret%%'' |String |否 |文件访问密钥,成功上传文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取的 share-secret。如果文件上传时设置了文件访问限制(restrict-access),则该字段为必填。 |
|''%%url%%'' |String |是 |文件 URL 地址:''%%https://{host}/{org_name}/{app_name}/chatfiles/{uuid}%%''。其中 ''%%uuid%%'' 为文件 ID,成功上传视频文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取。 |
== 位置消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%lat%%'' |String |是 |位置的纬度,单位为度。 |
|''%%lng%%'' |String |是 |位置的经度,单位为度。 |
|''%%addr%%'' |String |是 |位置的文字描述。 |
== 透传消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%action%%'' |String |是 |命令内容。 |
== 自定义消息 ==
^参数 ^类型 ^是否必需 ^描述 ^
|''%%customEvent%%'' |String |否 |用户自定义的事件类型。该参数的值必须满足正则表达式 ''%%[a-zA-Z0-9-_/\.]{1,32}%%'',长度为 1-32 个字符。 |
|''%%customExts%%'' |JSON |否 |用户自定义的事件属性,类型必须是 ''%%Map%%'',最多可以包含 16 个元素。''%%customExts%%'' 是可选的,不需要可以不传。 |
=== HTTP 响应 ===
== 响应 body ==
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应 body 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%data%%'' |JSON |返回数据详情。该字段的值为包含接收方用户 ID 和 发送的消息的 ID 的键值对。
例如 “user2”: “1029457500870543736”,表示向 user2 发送了消息 ID 为1029457500870543736 的消息。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
=== 示例 ===
== 请求示例 ==
= 文本消息 =
发送给目标用户,消息无需同步给发送方:
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'http://XXXX/XXXX/XXXX/messages/users' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["user2"],"type": "txt","body": {"msg": "testmessages"}}'
仅发送给在线用户,消息同步给发送方:
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'http://XXXX/XXXX/XXXX/messages/users' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["user2"],"type": "txt","body": {"msg": "testmessages"},"routetype":"ROUTE_ONLINE", "sync_device":true}'
= 图片消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/users' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["user2"],"type": "img","body": {"filename":"testimg.jpg","secret":"VfXXXXNb_","url":"https://XXXX/XXXX/XXXX/chatfiles/55f12940-XXXX-XXXX-8a5b-ff2336f03252","size":{"width":480,"height":720}}}'
= 语音消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/users' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["user2"],"type": "audio","body": {"url": "https://XXXX/XXXX/XXXX/chatfiles/1dfc7f50-XXXX-XXXX-8a07-7d75b8fb3d42","filename": "testaudio.amr","length": 10,"secret": "HfXXXXCjM"}}'
= 视频消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/users' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["user2"],"type": "video","body": {"thumb" : "https://XXXX/XXXX/XXXX/chatfiles/67279b20-7f69-11e4-8eee-21d3334b3a97","length" : 0,"secret":"VfXXXXNb_","file_length" : 58103,"thumb_secret" : "ZyXXXX2I","url" : "https://XXXX/XXXX/XXXX/chatfiles/671dfe30-XXXX-XXXX-ba67-8fef0d502f46"}}'
= 文件消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/users' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["user2"],"type": "file","body": {"filename":"test.txt","secret":"1-g0XXXXua","url":"https://XXXX/XXXX/XXXX/chatfiles/d7eXXXX7444"}}'
= 位置消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/users" -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["user2"],"type": "loc","body":{"lat": "39.966","lng":"116.322","addr":"中国北京市海淀区中关村"}}'
= 透传消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/users" -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization:Bearer " -d '{"from": "user1","to": ["user2"],"type": "cmd","body":{"action":"action1"}}'
= 自定义消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/users" -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization:Bearer " -d '{"from": "user1","to": ["user2"],"type": "custom","body": {"customEvent": "custom_event"}}'
== 响应示例 ==
= 文本消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
= 图片消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
= 语音消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
= 视频消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
= 文件消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
= 位置消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
= 透传消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
= 自定义消息 =
{
"path": "/messages/users",
"uri": "https://XXXX/XXXX/XXXX/messages/users",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"user2": "1029457500870543736"
},
"duration": 0,
"applicationName": "XXXX"
}
==== 发送群聊消息 ====
=== HTTP 请求 ===
POST https://{host}/{org_name}/{app_name}/messages/chatgroups
=== 路径参数 ===
参数及说明详见 [[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Content-Type%%'' |String |是 |内容类型。请填 ''%%application/json%%''。 |
|''%%Accept%%'' |String |是 |内容类型。请填 ''%%application/json%%''。 |
|''%%Authorization%%'' |String |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
=== 通用请求体 ===
通用请求体为 JSON 对象,是所有消息的外层结构。
^参数 ^类型 ^是否必需 ^描述 ^
|''%%to%%'' |Array |是 |消息接收方群组 ID 数组,每秒最多可向群组发送 20 条信息,每次最多可向 3 个群组发送消息。例如,一次向 3 个群组发消息,表示发送了 3 条消息。 |
群聊消息的通用请求体中的其他参数与单聊消息类似,详见 [[https://docs-im.easemob.com/ccim/rest/message#通用请求体|通用请求体]]。
与单聊消息类似,不同类型的消息只是 ''%%body%%'' 字段内容存在差异。详见 [[https://docs-im.easemob.com/ccim/rest/message#body_字段说明|body 字段说明]]。
=== HTTP 响应 ===
== 响应 body ==
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应 body 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%data%%'' |JSON |返回数据详情。该字段的值为包含群组 ID 和 发送的消息的 ID 的键值对。
例如 “184524748161025”: “1029544257947437432”,表示在 ID 为 184524748161025 的群组中发送了消息 ID 为 1029544257947437432 的消息。 |
其他参数及说明详见 [[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考 [[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]] 了解可能的原因。
=== 示例 ===
== 请求示例 ==
= 文本消息 =
发送给目标用户,消息无需同步给发送方:
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'http://XXXX/XXXX/XXXX/messages/chatgroups' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["184524748161025"],"type": "txt","body": {"msg": "testmessages"}}'
仅发送给在线用户,消息同步给发送方:
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'http://XXXX/XXXX/XXXX/messages/chatgroups' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["184524748161025"],"type": "txt","body": {"msg": "testmessages"},"routetype":"ROUTE_ONLINE", "sync_device":true}'
= 图片消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatgroups' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["184524748161025"],"type": "img","body": {"filename":"testimg.jpg","secret":"VfXXXXNb_","url":"https://XXXX/XXXX/XXXX/chatfiles/55f12940-XXXX-XXXX-8a5b-ff2336f03252","size":{"width":480,"height":720}}}'
= 语音消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatgroups' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["184524748161025"],"type": "audio","body": {"url": "https://XXXX/XXXX/XXXX/chatfiles/1dfc7f50-XXXX-XXXX-8a07-7d75b8fb3d42","filename": "testaudio.amr","length": 10,"secret": "HfXXXXCjM"}}'
= 视频消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatgroups' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["184524748161025"],"type": "video","body": {"thumb" : "https://XXXX/XXXX/XXXX/chatfiles/67279b20-7f69-11e4-8eee-21d3334b3a97","length" : 0,"secret":"VfXXXXNb_","file_length" : 58103,"thumb_secret" : "ZyXXXX2I","url" : "https://XXXX/XXXX/XXXX/chatfiles/671dfe30-XXXX-XXXX-ba67-8fef0d502f46"}}'
= 文件消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatgroups' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["184524748161025"],"type": "file","body": {"filename":"test.txt","secret":"1-g0XXXXua","url":"https://XXXX/XXXX/XXXX/chatfiles/d7eXXXX7444"}}'
= 位置消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/chatgroups" -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["184524748161025"],"type": "loc","body":{"lat": "39.966","lng":"116.322","addr":"中国北京市海淀区中关村"}}'
= 透传消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/chatgroups" -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization:Bearer " -d '{"from": "user1","to": ["184524748161025"],"type": "cmd","body":{"action":"action1"}}'
= 自定义消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/chatgroups" -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization:Bearer " -d '{"from": "user1","to": ["184524748161025"],"type": "custom","body": {"customEvent": "custom_event"}}'
== 响应示例 ==
= 文本消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
= 图片消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
= 语音消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
= 视频消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
= 文件消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
= 位置消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
= 透传消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
= 自定义消息 =
{
"path": "/messages/chatgroups",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"184524748161025": "1029544257947437432"
},
"duration": 0,
"applicationName": "XXXX"
}
==== 发送聊天室消息 ====
=== HTTP 请求 ===
POST https://{host}/{org_name}/{app_name}/messages/chatrooms
=== 路径参数 ===
参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
=== 请求 header ===
^ 参数 ^类型 ^ 是否必需 ^ 描述 ^
| ''%%Content-Type%%'' |String | 是 | 内容类型。请填 ''%%application/json%%''。 |
| ''%%Accept%%'' |String | 是 | 内容类型。请填 ''%%application/json%%''。 |
| ''%%Authorization%%'' |String | 是 | ''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
=== 通用请求体 ===
通用请求体为 JSON 对象,是所有消息的外层结构。不同类型的消息只是 ''%%body%%'' 字段内容存在差异。
^参数 ^类型 ^是否必需 ^描述 ^
|''%%to%%'' |Array |是 |消息接收方聊天室 ID 数组,每秒钟最多可向 100 个聊天室发送信息,每次可发送的接收方聊天室上限为 10 个,如:一次发送给 10 个聊天室时,表示为 10 条消息。 |
聊天室消息的通用请求体中的其他参数与单聊消息类似,详见 [[https://docs-im.easemob.com/ccim/rest/message#通用请求体|通用请求体]]。
与单聊消息类似,不同类型的消息只是 ''%%body%%'' 字段内容存在差异。详见 [[https://docs-im.easemob.com/ccim/rest/message#body_字段说明|body 字段说明]]。
=== HTTP 响应 ===
== 响应 body ==
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应 body 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%data%%'' |JSON |返回数据详情。该字段的值为包含聊天室 ID 和 发送的消息的 ID 的键值对。
例如 “185145305923585”: “1029545553039460728”,表示在 ID 为 184524748161025 的聊天室中发送了消息 ID 为 1029545553039460728 的消息。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
=== 示例 ===
== 请求示例 ==
= 文本消息 =
发送给目标用户,消息无需同步给发送方:
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'http://XXXX/XXXX/XXXX/messages/chatrooms' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["185145305923585"],"type": "txt","body": {"msg": "testmessages"}}'
仅发送给在线用户,消息同步给发送方:
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'http://XXXX/XXXX/XXXX/messages/chatrooms' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["185145305923585"],"type": "txt","body": {"msg": "testmessages"},"routetype":"ROUTE_ONLINE", "sync_device":true}'
= 图片消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatrooms' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["185145305923585"],"type": "img","body": {"filename":"testimg.jpg","secret":"VfXXXXNb_","url":"https://XXXX/XXXX/XXXX/chatfiles/55f12940-XXXX-XXXX-8a5b-ff2336f03252","size":{"width":480,"height":720}}}'
= 语音消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatrooms' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["185145305923585"],"type": "audio","body": {"url": "https://XXXX/XXXX/XXXX/chatfiles/1dfc7f50-XXXX-XXXX-8a07-7d75b8fb3d42","filename": "testaudio.amr","length": 10,"secret": "HfXXXXCjM"}}'
= 视频消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatrooms' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["185145305923585"],"type": "video","body": {"thumb" : "https://XXXX/XXXX/XXXX/chatfiles/67279b20-7f69-11e4-8eee-21d3334b3a97","length" : 0,"secret":"VfXXXXNb_","file_length" : 58103,"thumb_secret" : "ZyXXXX2I","url" : "https://XXXX/XXXX/XXXX/chatfiles/671dfe30-XXXX-XXXX-ba67-8fef0d502f46"}}'
= 文件消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i 'https://XXXX/XXXX/XXXX/messages/chatrooms' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["185145305923585"],"type": "file","body": {"filename":"test.txt","secret":"1-g0XXXXua","url":"https://XXXX/XXXX/XXXX/chatfiles/d7eXXXX7444"}}'
= 位置消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/chatrooms" -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{"from": "user1","to": ["185145305923585"],"type": "loc","body":{"lat": "39.966","lng":"116.322","addr":"中国北京市海淀区中关村"}}'
= 透传消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/chatrooms" -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization:Bearer " -d '{"from": "user1","to": ["185145305923585"],"type": "cmd","body":{"action":"action1"}}'
= 自定义消息 =
# 将 替换为你在服务端生成的 App Token
curl -X POST -i "https://XXXX/XXXX/XXXX/messages/chatrooms" -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization:Bearer " -d '{"from": "user1","to": ["185145305923585"],"type": "custom","body": {"customEvent": "custom_event"}}'
== 响应示例 ==
= 文本消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
= 图片消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
= 语音消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
= 视频消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
= 文件消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
= 位置消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
= 透传消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
= 自定义消息 =
{
"path": "/messages/chatrooms",
"uri": "https://XXXX/XXXX/XXXX/messages/chatrooms",
"timestamp": 1657254052191,
"organization": "XXXX",
"application": "e82bcc5f-XXXX-XXXX-a7c1-92de917ea2b0",
"action": "post",
"data": {
"185145305923585": "1029545553039460728"
},
"duration": 0,
"applicationName": "XXXX"
}
===== 文件上传 =====
上传图片、语音、视频或其他类型文件。同时,为了保证聊天文件的安全,我们的 API 保证了以下几点:
* 上传文件的大小不能超过 10 MB,超过会上传失败。
* 支持对上传的文件限制访问。该功能开启后,你需要通过密钥才能下载被限制访问的文件。消息回调(包含发送前回调和发送后回调)、历史消息中涉及下载文件时,都需要在下载 URL 中拼接密钥,才能正常下载文件,拼接规则为:''%%{{url}}?share-secret={{secret}}%%''。
==== HTTP 请求 ====
POST https://{host}/{org_name}/{app_name}/chatfiles
=== 路径参数 ===
参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Content-Type%%'' |String |否 |内容类型。请填 ''%%multipart/form-data%%''。上传文件会自动填充这个头。 |
|''%%Authorization%%'' |String |是 |''%%Bearer ${YourAppToken}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
|''%%restrict-access%%'' |Bool |否 |是否限制访问该文件:
- ''%%true%%'' :是。用户需要通过响应 body 中获取的文件访问密钥(share-secret)才能下载该文件。
- ''%%false%%'' :否。表示不限制访问。用户可以直接下载该文件。 |
=== 请求 body ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%file%%'' |String |是 |文件本地路径。 |
==== HTTP 响应 ====
=== 响应 body ===
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应包体中包含以下字段:
^参数 ^类型 ^描述 ^
|''%%entities.uuid%%'' |String |文件 ID,即时通讯服务分配给该文件的唯一标识符。该参数在发送消息时需用到。 |
|''%%entities.type%%'' |String |消息类型。文件类型为 ''%%file%%''。 |
|''%%entities.share-secret%%'' |String |文件访问密钥。你需要自行保存 share-secret,以便[[https://docs-im.easemob.com/ccim/rest/message#下载语音/图片文件/缩略图|下载文件]]时使用。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。 如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
==== 示例 ====
=== 请求示例 ===
# 将 替换为你在服务端生成的 App Token,将 file 的路径替换为待上传文件所在的本地完整路径
curl -X POST https://XXXX/XXXX/XXXX/chatfiles -H 'Authorization: Bearer ' -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' -H 'restrict-access: true' -F file=@/Users/test/9.2/easemob/image/IMG_2953.JPG
=== 响应示例 ===
{
"action": "post",
"application": "8be024f0-XXXX-XXXX-b697-5d598d5f8402",
"path": "/chatfiles",
"uri": "https://XXXX/XXXX/XXXX/chatfiles",
"entities": [
{
"uuid": "5fd74830-XXXX-XXXX-822a-81ea50bb049d",
"type": "chatfile",
"share-secret": "X9dXXXX7Yc"
}
],
"timestamp": 1554371126338,
"duration": 0,
"organization": "XXXX",
"applicationName": "XXXX"
}
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
===== 下载语音/图片文件/缩略图 =====
需要注意是,如果上传文件时选择了文件不共享,需要在请求头中包含上述响应返回的 ''%%share-secret%%'' 和当前登录用户的 token 才能下载。
==== HTTP 请求 ====
GET https://{host}/{org_name}/{app_name}/chatfiles/{uuid}
=== 路径参数 ===
参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Accept%%'' |string |是 |内容类型。请填 ''%%application/octet-stream%%'',表示下载二进制数据流格式的文件。 |
|''%%Authorization%%'' |string |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
|''%%share-secret%%'' |string |否 |文件访问密钥。若上传文件时限制了访问,则需要该访问密钥。成功上传文件后,从 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 的响应 body 中获取该密钥。 |
==== HTTP 响应 ====
=== 响应 body ===
参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
==== 示例 ====
=== 请求示例 ===
以下载图片为例:
# 将 替换为你在服务端生成的 App Token
curl -X GET -H 'Accept: application/octet-stream' -H 'Authorization: Bearer ' -H 'share-secret: f0Vr-uyyEeiHpHmsu53XXXXXXXXZYgyLkdfsZ4xo2Z0cSBnB' 'http://XXXX/XXXX/XXXX/chatfiles/7f456bf0-XXXX-XXXX-b630-777db304f26c'-o /Users/test/easemob/image/image.JPG
**注意**
上述请求示例中,''%%/Users/test/easemob/image/image.JPG%%'' 为环信即时通讯 IM 的本地文件路径,使用时请替换为自己的文件路径,否则会请求失败。
=== 响应示例 ===
{
//语音/图片文件内容
}
如果返回的 HTTP 状态码为 200,表示请求成功,返回文件二进制数据流。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
===== 下载缩略图 =====
环信即时通讯 IM 支持在服务器端自动创建图片的缩略图。用户可先下载缩略图,需要时再下载原图。下载缩略图与下载原图的唯一区别是前者在请求 header 中多了 “thumbnail: true”。当服务器收到包含该字段的请求 header 时,返回缩略图,否则返回原图。
==== HTTP 请求 ====
GET https://{host}/{org_name}/{app_name}/chatfiles/{file_uuid}
需要在请求时对应填写 ''%%{file_uuid}%%'',即服务器为文件生成的 UUID。
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Accept%%'' |String |是 |内容类型。请填 ''%%application/octet-stream%%'',表示下载二进制数据流格式的文件。 |
|''%%Authorization%%'' |String |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
|''%%thumbnail%%'' |Bool |否 |上传图片或视频时,服务器是否自动生成缩略图,用户可选择下载缩略图或原文件。
- ''%%true%%'':是。
- ''%%false%%'':否。 |
==== HTTP 响应 ====
=== 响应 body ===
参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
==== 示例 ====
=== 请求示例 ===
# 将 替换为你在服务端生成的 App Token
curl -X GET -H 'Accept: application/octet-stream' -H 'Authorization: Bearer ' -H 'share-secret: f0Vr-uyyEeiHpHmsu53XXXXXXXXZYgyLkdfsZ4xo2Z0cSBnB' -H 'thumbnail: true' 'http://XXXX/XXXX/XXXX/chatfiles/7f456bf0-ecb2-11e8-b630-777db304f26c'
=== 响应示例 ===
**返回值 200,表示下载缩略图成功**
{
//缩略图信息
}
**返回值 401,未授权 [无 token、token 错误、token 过期]**
{
"error": "auth_bad_access_token",
"timestamp": 1542350943210,
"duration": 0,
"exception": "org.apache.usergrid.rest.exceptions.SecurityException",
"error_description": "Unable to authenticate due to corrupt access token"
}
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
===== 获取历史消息文件 =====
获取用户发送和接收的历史消息。
* 一次请求获取从指定起始时间开始一小时内的全部历史消息。
* 查询历史消息时存在一定延时,无法实时获取。
* 过期的历史消息无法获取。对于不同的套餐版本,历史消息默认存储时间不同。详见[[https://www.easemob.com/pricing/im|套餐包详情]]。
==== HTTP 请求 ====
GET https://{host}/{org_name}/{app_name}/chatmessages/${time}
=== 路径参数 ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%time%%'' |String |是 |历史消息查询的起始时间。UTC 时间,使用 ISO8601 标准,格式为 yyyyMMddHH。例如 time 为 2018112717,则表示查询 2018 年 11 月 27 日 17 时至 2018 年 11 月 27 日 18 时期间的历史消息。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Accept%%'' |String |是 |内容类型,请填 ''%%application/json%%''。 |
|''%%Authorization%%'' |String |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
==== HTTP 响应 ====
=== 响应 body ===
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应包体中包含以下字段:
^参数 ^类型 ^描述 ^
|''%%url%%'' |String |历史消息文件下载地址。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
==== 示例 ====
=== 请求示例 ===
# 将 替换为你在服务端生成的 App Token
curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXXX/XXXX/XXXX/chatmessages/2018112717'
=== 响应示例 ===
{
"action": "get",
"application": "8be024f0-XXXX-XXXX-b697-5d598d5f8402",
"uri": "'http://XXXX/XXXX/XXXX/chatmessages/2018112717",
"data": [
{
"url": "http://XXXX?Expires=1543316122&OSSAccessKeyId=XXXX&Signature=XXXX"
} ],
"timestamp": 1543314322601,
"duration": 0,
"organization": "XXXX",
"applicationName": "testapp"
}
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
**注意**
URL 仅在一定时间内有效,URL 中的 Expires 对应的时间戳为过期时间,单位为秒。请及时通过 URL 下载聊天记录文件,URL 过期后会下载失败,需要重新调用”获取历史消息文件”接口获取新的 URL。
==== 历史消息内容 ====
查询历史消息成功后,你可以访问 URL 下载历史消息文件,查看历史消息具体内容。
历史消息包含以下字段:
^参数 ^类型 ^描述 ^
|''%%msg_id%%'' |String |消息 ID。 |
|''%%timestamp%%'' |Long |消息发送完成的 Unix 时间戳,单位未毫秒,UTC 时间。 |
|''%%from%%'' |String |消息发送方的用户 ID。 |
|''%%to%%'' |String |消息接收方。
- 单聊为接收方用户 ID;
- 群聊为群组ID。 |
|''%%chat_type%%'' |String |会话类型:
- ''%%chat%%'': 单聊;
- ''%%groupchat%%'': 群聊;
- ''%%chatroom%%'': 聊天室。 |
|''%%payload%%'' |JSON |包含消息的具体内容。例如消息扩展信息、自定义扩展属性等。 |
历史消息为 JSON 类型,示例如下:
{
"msg_id": "5I02W-XX-8278a",
"timestamp": 1403099033211,
"direction":"outgoing",
"to": "XXXX",
"from": "XXXX",
"chat_type": "chat",
"payload":
{
"bodies": [ {
//下面会将不同的消息类型进行说明
}
],
"ext":
{
"key1": "value1", ... },
"from":"XXXX",
"to":"XXXX"
}
}
=== 文本消息 ===
文本消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%msg%%'' |JSON |消息内容。 |
|''%%type%%'' |String |消息类型,文本消息类型为 ''%%txt%%''。 |
示例
"bodies": [{"msg":"welcome to easemob!", "type":"txt"}]
=== 图片消息 ===
图片消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%file_length%%'' |Long |图片附件大小,单位为字节。 |
|''%%secret%%'' |String |图片文件访问密钥。如果 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 时设置了文件访问限制,则该字段存在。 |
|''%%size%%'' |JSON |图片的尺寸。单位为像素。
- ''%%height%%'':图片高度。
- ''%%width%%'':图片宽度。 |
|''%%type%%'' |String |消息类型。图片消息为 ''%%img%%''。 |
|''%%url%%'' |String |图片 URL 地址。 |
示例
"bodies": [ { "file_length":128827, "filename":"test1.jpg", "secret":"DRGM8OZrEeO1vaXXXXXXXXHBeKlIhDp0GCnFu54xOF3M6KLr", "size":{"height":1325,"width":746}, "type":"img", "url":"https://XXXX/XXXX/chatdemoui/chatfiles/65e54a4a-XXXX-XXXX-b821-ebde7b50cc4b", }]
=== 位置消息 ===
位置消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%addr%%'' |String |所在位置地址描述。 |
|''%%lat%%'' |Long |所在位置的纬度。 |
|''%%lng%%'' |Long |所在位置的经度。 |
|''%%type%%'' |String |消息类型。位置消息为 ''%%loc%%''。 |
示例
"bodies": [
{
"addr":"西城区西便门桥 ",
"lat":39.9053,
"lng":116.36302,
"type":"loc"
}]
=== 语音消息 ===
语音消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%file_length%%'' |Long |语音附件大小。单位为字节。 |
|''%%filename%%'' |String |带文件格式后缀的语音文件名称。 |
|''%%secret%%'' |String |语音文件访问密钥。如果 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 时设置了文件访问限制,则该字段存在。 |
|''%%length%%'' |Int |语音时长。单位为秒。 |
|''%%type%%'' |String |消息类型。语音消息为 ''%%audio%%''。 |
|''%%url%%'' |String |语音文件 URL 地址。 |
示例
"bodies":
[
{
"file_length":6630,
"filename":"test1.amr",
"length":10,
"secret":"DRGM8OZrEeO1vafuJSo2IjHBeKlIhDp0GCnFu54xOF3M6KLr",
"type":"audio",
"url":"https://XXXX/XXXX/chatdemoui/chatfiles/0637e55a-f606-XXXX-XXXX-51f25fd1215b"
}
]
=== 视频消息 ===
视频消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%file_length%%'' |Long |视频附件大小。单位为字节。 |
|''%%filename%%'' |String |带文件格式后缀的视频文件名称。 |
|''%%secret%%'' |String |视频文件访问密钥。如果 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 时设置了文件访问限制,则该字段存在。 |
|''%%length%%'' |Int |视频时长。单位为秒。 |
|''%%size%%'' |JSON |视频缩略图尺寸。单位为像素。
- ''%%width%%'':视频缩略图宽度;
- ''%%height%%'':视频缩略图高度。 |
|''%%thumb%%'' |String |上传视频缩略图远程地址,在上传视频缩略图后会返回 UUID。 |
|''%%thumb_secret%%'' |String |缩略图文件访问密钥。
- 如果文件上传时设置了文件访问限制,则该字段存在。 |
|''%%type%%'' |String |消息类型。视频消息为 ''%%video%%''。 |
|''%%url%%'' |String |视频缩略图 URL 地址。 |
示例如下:
"bodies": [ {
"file_length": 58103,
"filename": "14XXXX.mp4",
"length": 10,
"secret": "VfEpSmSvEeS7yU8dwa9rAQc-DIL2HhmpujTNfSTsrDt6eNb_",
"size":{"height":480,"width":360},
"thumb": "https://XXXX/XXXX/chatdemoui/chatfiles/67279b20-XXXX-XXXX-8eee-21d3334b3a97",
"thumb_secret": "ZyebKn9pEeSSfY03ROk7ND24zUf74s7HpPN1oMV-1JxN2O2I",
"type": "video",
"url": "https://XXXX/XXXX/chatdemoui/chatfiles/671dfe30-XXXX-XXXX-ba67-8fef0d502f46" }]
=== 文件消息 ===
文件消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%file_length%%'' |Long |文件大小。单位为字节。 |
|''%%filename%%'' |String |带文件格式后缀的文件名称。 |
|''%%secret%%'' |String |文件访问密钥。
- 如果 [[https://docs-im.easemob.com/ccim/rest/message#文件上传|文件上传]] 时设置了文件访问限制,则该字段存在。 |
|''%%type%%'' |String |消息类型。文件消息为 ''%%file%%''。 |
|''%%url%%'' |String |文件的 URL 地址。你可以访问该 URL 下载历史消息文件。 |
示例如下:
"bodies":
[
{
"file_length":3279,
"filename":"record.md",
"secret":"2RNXCgeeEeeXXXX-XXXXbtZXJH4cgr2admVXn560He2PD3RX",
"type":"file",
"url":"https://XXXX/XXXX/XXXX/chatfiles/d9135700-XXXX-XXXX-b000-a7039876610f"
}
]
=== 透传消息 ===
透传消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%action%%'' |String |命令内容。 |
|''%%type%%'' |String |消息类型。透传消息为 ''%%cmd%%''。 |
示例如下:
"bodies":
[
{
"action":"run",
"type":"cmd"
}
]
=== 自定义消息 ===
自定义消息的 bodies 包含如下字段:
^参数 ^类型 ^描述 ^
|''%%customExts%%'' |JSON |自定义扩展属性。你可以自行设置扩展属性中的字段。 |
|''%%customEvent%%'' |String |自定义事件类型。 |
|''%%type%%'' |String |消息类型。自定义消息为 ''%%custom%%''。 |
示例如下:
"bodies":
[
{
"customExts":
{
"name":"flower",
"size":"16",
"price":"100"
},
"customEvent":"gift_1",
"type":"custom"
}
]
===== 服务端消息撤回 =====
应用管理员可撤回发送的消息。默认可撤回发出 2 分钟内的消息,如需调整请联系环信商务经理。
==== HTTP 请求 ====
POST https://{host}/{org_name}/{app_name}/messages/msg_recall
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Authorization%%'' |String |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
=== 请求 body ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%msg_id%%'' |String |是 |要撤回消息的消息 ID。 |
|''%%to%%'' |String |是 |撤回消息的接收方。
- 单聊为接收方用户 ID;
- 群聊为群组 ID;
- 聊天室聊天为聊天室 ID。
若不传入该参数,请求失败。 |
|''%%chat_type%%'' |String |是 |撤回消息的会话类型:
- ''%%chat%%'':单聊;
- ''%%groupchat%%'':群聊 ;
- ''%%chatroom%%'':聊天室 。 |
|''%%from%%'' |String |否 |消息撤回方的用户 ID。若不传该参数,默认为 ''%%admin%%''。 |
|''%%force%%'' |Bool |是 |是否为强制撤回:
- ''%%true%%'':是,支持撤回超过服务器存储时间的消息。具体见[[https://docs-im.easemob.com/ccim/limitation#消息存储时长限制|服务器消息保存时长]];
- ''%%false%%'':否,不支持撤回超过服务器存储时间的消息。 |
==== HTTP 响应 ====
=== 响应 body ===
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应包体中包含以下字段:
^参数 ^类型 ^描述 ^
|''%%msg_id%%'' |String |需要撤回的消息 ID。 |
|''%%recalled%%'' |String |消息撤回结果,成功是 ''%%yes%%''。 |
|''%%from%%'' |String |消息撤回方。 |
|''%%to%%'' |String |撤回消息的送达方。
- 单聊为送达方用户 ID;
- 群聊为群组 ID。 |
|''%%chattype%%'' |String |撤回消息的会话类型:
- ''%%chat%%'':单聊;
- ''%%groupchat%%'':群聊;
- ''%%chatroom%%'':聊天室。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。 如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
==== 示例 ====
=== 请求示例 ===
# 将 替换为你在服务端生成的 App Token
curl -i -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization: Bearer "
"http://XXXX/XXXX/XXXX/messages/msg_recall"
-d '{
"msg_id": "1028442084794698104",
"to": "user2",
"from": "user1",
"chat_type": "chat",
"force": true
}'
=== 响应示例 ===
撤销成功:
{
"path": "/messages/msg_recall",
"uri": "https://XXXX/XXXX/XXXX/messages/msg_recall",
"timestamp": 1657529588473,
"organization": "XXXX",
"application": "09ebbf8b-XXXX-XXXX-XXXX-d47c3b38e434",
"action": "post",
"data": {
"recalled": "yes",
"chattype": "chat",
"from": "XXXX",
"to": "XXXX",
"msg_id": "1028442084794698104"
},
"duration": 8,
"applicationName": "XXXX"
}
撤销失败:
''%%recalled%%'':消息撤销失败包含以下几种情况:
* ”can’t find msg to”:未找到撤回消息的接收⽅;
* ”exceed recall time limit”:消息撤回超时;
* ”not_found msg”:消息过期或已被撤回;
* ”internal error”:后端服务出现异常。
{
"msgs":
[
{ "msg_id":"673296835082717140",
"recalled":"not_found msg"
}
]
}
撤回消息服务未在环信即时通讯云管理后台开通,返回示例如下:
{
"error":"forbidden_op",
"exception":"EasemobForbiddenOpException",
"timestamp":1644402553845,
"duration":0,
"error_description":"message recall service is unopened"
}
===== 服务端单向删除会话 =====
==== HTTP 请求 ====
DELETE https://{host}/{orgName}/{appName}/users/{userName}/user_channel
=== 路径参数 ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%userName%%'' |String |是 |要删除会话的用户的唯一标识符,即用户 ID。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Authorization%%'' |String |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
=== 请求 body ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%channel%%'' |String |是 |要删除的会话 ID。 |
|''%%type%%'' |String |是 |会话类型。
- ''%%chat%%'':单聊会话;
-''%%groupchat%%'':群聊会话。 |
|''%%delete_roam%%'' |Bool |是 |是否删除服务端消息。
- ''%%true%%'':是;
- ''%%false%%'':否。 |
==== HTTP 响应 ====
=== 响应 body ===
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应包体中包含以下字段:
^字段 ^类型 ^描述 ^
|''%%result%%'' |String |删除结果,''%%ok%%'' 表示成功,失败则直接返回错误码和原因。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
==== 示例 ====
=== 请求示例 ===
# 将 替换为你在服务端生成的 App Token
curl -X DELETE -H "Authorization: Bearer " "https://XXXX/XXXX/XXXX/users/u1/user_channel" -d '{"channel":"u2", "type":"chat","delete_roam": true}'
=== 响应示例 ===
{
"path": "/users/user_channel",
"uri": "https://XXXX/XXXX/XXXX/users/u1/user_channel",
"timestamp": 1638440544078,
"organization": "XXXX",
"application": "c3624975-XXXX-XXXX-9da2-ee91ed4c5a76",
"entities": [],
"action": "delete",
"data": {
"result": "ok"
},
"duration": 3,
"applicationName": "XXXX"
}
===== 导入单聊消息 =====
该接口用于数据迁移时单聊消息的批量导入。
==== HTTP 请求 ====
POST https://{host}/{orgName}/{appName}/messages/users/import
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Authorization%%'' |String |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
=== 请求 body ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%from%%'' |String |是 |消息发送方的用户 ID。 |
|''%%target%%'' |String |是 |消息接受方的用户 ID。 |
|''%%type%%'' |String |是 |消息类型:
- ''%%txt%%'':文本消息;
- ''%%img%%'':图片消息;
- ''%%audio%%'':语音消息;
- ''%%video%%'':视频消息;
- ''%%file%%'':文件消息;
- ''%%loc%%'':位置消息;
- ''%%cmd%%'':透传消息;
- ''%%custom%%'':自定义消息。 |
|''%%body%%'' |JSON |是 |消息内容。 |
|''%%is_ack_read%%'' |Bool |否 |是否设置消息为已读。
- ''%%true%%'':是;
- ''%%false%%'':否。 |
|''%%msg_timestamp%%'' |Long |否 |导入的消息需要设置的时间戳。单位为毫秒。 |
|''%%need_download%%'' |Bool |否 |是否需要下载附件并上传到服务器。
- ''%%true%%'':是;
- ''%%false%%'':否。
- ''%%默认%%'': false。 |
与发送消息类似,不同类型的消息只是 ''%%body%%'' 字段内容存在差异。详见 [[https://docs-im.easemob.com/ccim/rest/message#body_字段说明|body 字段说明]]。
==== HTTP 响应 ====
=== 响应 body ===
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应包体中包含以下字段:
^字段 ^类型 ^描述 ^
|''%%msg_id%%'' |String |导入消息返回的消息 ID。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
==== 示例 ====
=== 请求示例 ===
# 导入文本消息
# 将 替换为你在服务端生成的 App Token
curl -X POST -H "Authorization: Bearer " "https://XXXX/XXXX/XXXX/messages/users/import" -d '{
"target": "username2",
"type": "txt",
"body": {
"msg": "import message."
},
"from": "username1",
"is_ack_read": true,
"msg_timestamp": 1656906628428
}'
# 导入图片消息
# 将 替换为你在服务端生成的 App Token
curl -X POST -H "Authorization: Bearer " "https://XXXX/XXXX/XXXX/messages/users/import" -d '{
"target": "username2",
"type": "img",
"body": {
"url": "",
"filename": "",
"size": {
"width": 1080,
"height": 1920
}
},
"from": "username1",
"is_ack_read": true,
"msg_timestamp": 1656906628428,
"need_download": true
}'
=== 响应示例 ===
{
"path": "/messages/users/import",
"uri": "https://XXXX/XXXX/XXXX/messages/users/import",
"timestamp": 1638440544078,
"organization": "XXXX",
"application": "c3624975-XXXX-XXXX-9da2-ee91ed4c5a76",
"entities": [],
"action": "post",
"data": {
"msg_id": "10212123848595"
},
"duration": 3,
"applicationName": "XXXX"
}
===== 导入群聊消息 =====
==== HTTP 请求 ====
POST https://{host}/{orgName}/{appName}/messages/chatgroups/import
=== 请求 header ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%Authorization%%'' |String |是 |''%%Bearer ${App Token}%%'' Bearer 是固定字符,后面加英文空格,再加上获取到的 App Token 的值。 |
=== 请求 body ===
^参数 ^类型 ^是否必需 ^描述 ^
|''%%from%%'' |String |是 |消息发送方的用户 ID。 |
|''%%target%%'' |String |是 |群 ID。 |
|''%%type%%'' |String |是 |消息类型:
- ''%%txt%%'':文本消息;
- ''%%img%%'':图片消息;
- ''%%audio%%'':语音消息;
- ''%%video%%'':视频消息;
- ''%%file%%'':文件消息;
- ''%%loc%%'':位置消息;
- ''%%cmd%%'':透传消息;
- ''%%custom%%'':自定义消息。 |
|''%%body%%'' |JSON |是 |消息内容。 |
|''%%is_ack_read%%'' |Bool |否 |是否设置消息为已读。
- ''%%true%%'':是;
- ''%%false%%'':否。 |
|''%%msg_timestamp%%'' |Long |否 |导入的消息需要设置的时间戳。单位为毫秒。 |
|''%%need_download%%'' |Bool |否 |是否需要下载附件并上传到服务器。
- ''%%true%%'':是;
- (默认)''%%false%%'':否。 |
与发送消息类似,不同类型的消息只是 ''%%body%%'' 字段内容存在差异。详见 [[https://docs-im.easemob.com/ccim/rest/message#body_字段说明|body 字段说明]]。
==== HTTP 响应 ====
=== 响应 body ===
如果返回的 HTTP 状态码为 ''%%200%%'',表示请求成功,响应包体中包含以下字段:
^字段 ^类型 ^描述 ^
|''%%msg_id%%'' |String |导入消息返回的消息 ID。 |
其他参数及说明详见[[https://docs-im.easemob.com/ccim/rest/message#公共参数|公共参数]]。
如果返回的 HTTP 状态码非 ''%%200%%'',表示请求失败。你可以参考[[https://docs-im.easemob.com/ccim/rest/errorcode|响应状态码]]了解可能的原因。
==== 示例 ====
=== 请求示例 ===
# 导入文本消息
# 将 替换为你在服务端生成的 App Token
curl -X POST -H "Authorization: Bearer " "https://XXXX/XXXX/XXXX/messages/chatgroups/import" -d '{
"target": "username2",
"type": "txt",
"body": {
"msg": "import message."
},
"from": "username1",
"is_ack_read": true,
"msg_timestamp": 1656906628428
}'
# 导入图片消息
# 将 替换为你在服务端生成的 App Token
curl -X POST -H "Authorization: Bearer " "https://XXXX/XXXX/XXXX/messages/chatgroups/import" -d '{
"target": "username2",
"type": "img",
"body": {
"url": "",
"filename": "",
"size": {
"width": 1080,
"height": 1920
}
},
"from": "username1",
"is_ack_read": true,
"msg_timestamp": 1656906628428,
"need_download": true
}'
=== 响应示例 ===
{
"path": "/messages/users/import",
"uri": "https://XXXX/XXXX/XXXX/messages/chatgroups/import",
"timestamp": 1638440544078,
"organization": "XXXX",
"application": "c3624975-XXXX-XXXX-9da2-ee91ed4c5a76",
"entities": [],
"action": "post",
"data": {
"msg_id": "10212123848595"
},
"duration": 3,
"applicationName": "XXXX"
}