回调功能

更新时间:2022-03-17

回调功能,即环信 IM 服务器会在事件发生之前或之后,向你的应用服务器发送请求,你可以根据业务需求来干预事件的后续处理流程(发送前回调),或据此进行必要的数据同步(发送后回调)。

一般发送前回调是对用户发送的消息内容的处理,发送后回调还包括送达回执和已读回执、群组或聊天室操作、好友关系操作和用户状态变化等事件,具体见 用户在线状态回调和发送后回调过滤规则设置。

设置消息内容回调的规则可以在环信即时通讯云控制台实现,如需单独设置特定类型不回调,请联系环信商务经理。

从处理角度看,回调分为以下两类:

  • 发送前回调:回调的主要目的在于让 app 后台可以干预该事件的处理逻辑,环信 IM 服务器会根据回调返回码和返回值确定后续处理流程;
  • 发送后回调:回调的主要目的在于让 app 后台实现必要的数据同步,环信 IM 服务器忽略回调返回码。

技术原理

应用服务器可以通过发送前回调实时监控用户的聊天消息,包括:

  • 对聊天消息进行实时同步;
  • 拦截用户的消息请求。可拦截所有类型的消息,包含文本、图片、自定义消息等;

im_e6_96_87_e6_a1_a3.jpg

回调发生时间

环信 IM 服务器收到用户发送的上行单聊和群聊消息之后、将该消息下发给目标用户之前。

前提条件

以下是使用发送前回调功能需要了解的前提条件,包括在高并发可用性的基础上的使用限制说明,请按照此限制正确使用回调。

  • 回调的方向是环信 IM 服务器向应用服务器发起 HTTP/HTTPS POST 请求。
  • 若同时设置了消息发送前和发送后两种回调,且消息发送前回调返回拒绝,则消息发送后回调将不会被触发。
  • 发送前回调只对客户端发送的消息有效,不包含 REST API 发送的消息。对同一个 app,可以针对不同类型的消息(“TEXT”,“IMAGE”,“VIDEO”,“LOCATION”,“VOICE”和”FILE”)做配置;规则支持选择两种以上消息类型同时回调至一个指定服务器地址,接收到消息后,你可以区分消息的类型以便进行分类处理(详见 消息管理 REST API
  • 环信 IM 服务器执行发送前回调后,如果你的应用服务器没有返回 valid 状态或者返回其他错误码,该条消息会根据默认设置(console 后台发送前回调中”调用失败时默认策略”)处理,不会再重试;后续消息依然正常执行回调。
  • 消息发送到你的应用服务器后,应用服务器需返回 HTTP 响应码 200 和 valid 属性,根据 valid 状态决定是否进行下发。

实现步骤

  1. 在管理后台开通消息回调服务。
  2. 请在环信即时通讯云控制台配置开通规则配置。
配置说明 是否必填 内容
规则名称 必填 填写文字,支持中英文,长度限制为 32 字符。
会话类型 必填 * 单聊;
* 群组;
* 聊天室。
消息类型 必填 多选:
文本;图片;视频;位置;语音;文件;自定义消息。
等待响应时间 必填 后台判断超时时间,默认 200,单位为毫秒。
调用失败时默认策略 必填 当您的服务器返回结果异常或等待时间内未返回结果时,消息放行或不放行。
消息拦截报错时显示 必填 当消息被拦截时,是否通知发送者 SDK 消息发送失败:
* 报错:通知发送者 SDK 消息发送失败,发送者会感知到消息发送失败;
* 不报错:不通知发送者 SDK 消息发送失败,发送者无感知。
启用状态 必填 回调规则是否马上生效:
* 启用:马上生效;
* 不启用:暂不生效。
(建议首次创建配置为“不启用”,等您的服务器配置好验证信息后再修改为“启用”)
回调地址 必填 回调 URL,环信 IM 对 HTTP 和 HTTPS 的回调地址均支持。

规则说明:

  • 规则可以有多条,每个规则的名称必须是唯一的。
  • 环信 IM 服务器发送前回调应用服务器的超时时间默认为 200 ms,支持自定义“超时时间”。如果回调超时无应答,消息默认会正常下发,支持修改消息处理逻辑。
  • 目前支持发送前回调的消息类型包括:文本,图片,视频,位置,语音,文件,自定义消息。
  1. 从环信服务器向你的应用服务器发送请求。

请求采用 POST 方式,支持 HTTP/HTTPS,正文部分为 JSON 格式的字符串,字符集为 UTF-8。

请求 header 中包括以下字段:

字段名
Content-Typeapplication/json

请求体

参数 类型
callId callId{appkey}_{uuid},其中 uuid 为随机生成,作为每条回调的唯一标识。
eventType 有两种,chat_offline 离线消息,chat 上行消息。
timestamp 环信 IM 服务器接收到此消息的时间戳。
chat_type chat 单聊回调、groupchat 群聊回调包含了群组和聊天室的消息回调,默认全选。
group_id 回调消息所在的群组。群聊消息回调才有此参数。
from 消息的发送方。
to 消息的接收方。
msg_id 消息的 ID。
payload 消息内容,与通过 REST API 发送过来的一致,查看消息格式文档
securityVersion安全校验版本,目前为 1.0.0。忽略此参数,以后会改成 Console 后台做设置。
security 签名,格式如下: MD5(callId+Secret+timestamp)。Secret 见 环信即时通讯云控制台回调规则。

响应体

参数 类型 是否必需 描述
valid bool 根据开发者自己服务器设定的规则判断消息是否合法。
code String 自定义信息,字符串类型。
payload Object 如果需要更改消息内容可以回传修改后的内容,不修改则无需传该内容。格式同传入的消息内容,目前仅支持文本的形式,并且消息大小不能超过 1K。

请求示例

{
    "callId":"easemob-demo#test_0990a64f-dp01-6c50-8696-cf3b48b20e7e",
    "eventType":"chat_offline",
    "timestamp":1600060847294,
    "chat_type":"groupchat", 
    "group_id":"16934809238921545",
    "from":"user1",
    "to":"user2",
    "msg_id":"8924312242322",
    "payload":{
    // 具体的消息内容
    },
    "securityVersion":"1.0.0",
    "security":"2ca02c394bef9e7abc83958bcc3156d3"
}

响应示例

{
     "valid": true,
    "code": "HX:10000",
     "payload":{
    // 具体的消息内容。
    // 仅支持文本类型消息。
    },
}

技术原理

发送后回调经常用在 app 后台需要实现必要的数据同步的场景。比如:

  • 针对客户消息的内容进行自动回复;
  • 在你的应用服务器端及时保存聊天历史记录或者离线消息。

注:如果您对聊天消息没有时效性需求,可以直接通过免费的聊天记录拉取 REST API 获取聊天记录,无需使用发送后回调。

前提条件

以下是需要了解的发送后回调功能说明,包括在高并发可用性的基础上的使用限制说明,请按照此限制正确使用回调。

  • 消息回调属于增值服务,需要开通相应版本后才能使用,具体见 环信即时通讯 IM 价格
  • 消息回调规则设置成功即可正常使用。最多支持 4 个回调规则(包含发送前回调和发送后回调),如果需要再增加回调规则,需要联系商务经理开通。
  • 发送后回调范围,所有上行消息有效(包含 REST 发送的消息),包含单聊/群聊;如果 app 开通了反垃圾/敏感词过滤,被识别的消息会在服务器被拦截并禁止发送,将不会回调。
  • 发送后回调接收延时,是指消息服务器接收到客户端上行消息、再将消息成功回调至客户指定服务器地址的时间间隔。消息接收延时保障是 99.95% 的消息在 30s 内
  • 发送后回调对同一个 app 可以针对不同类型的消息(chat 和 chat_offline)做配置,如果 app 同时需要 chat 和 chat_offline 两种消息,建议区分回调地址。当然,规则也可以把这两种消息同时回调至一个指定服务器地址,在接收到消息后,可以对 eventType 做判断,区分消息的类型。
  • 发送后回调重试,当环信服务器执行发出回调后,响应状态码非 200,认为是指定服务器无网络、超过 60 秒或者其他因素导致失败,记录一次失败,然后立即重试,若再次失败,再记录一次失败直至无法重试。30 秒内累计 90 次失败,会对应封禁该 app 回调规则,5 分钟后自动解封。重试失败以及封禁期间的回调不会自动补录,可以下载历史消息文件自行补充。
  • 指定服务器收到回调消息后,向消息服务器发出响应内容不能超过 1,000 字符长度,如果连续发送超长的响应内容,会导致回调规则封禁,只能手动解除,需要用户手动重新设置。
  • 客户有特殊需求不能丢失回调消息的情况下,请联系环信商务经理开通回调异常缓存功能,并使用 查询回调异常缓存补发回调储存信息接口。

实现步骤

  1. 发送后回调规则配置;
  2. 从环信服务器向你的应用服务器发送请求;
  3. 在不能丢失回调消息的情况下,请联系环信商务经理开通回调异常缓存功能后,进行回调异常缓存的查询和重新发送。

具体如下:

  1. App Key 可以配置回调规则的数据格式,可以配置多个回调规则(默认最多开通 4 个规则),开通服务后才允许用户配置,前往 环信即时通讯云控制台 配置:
参数 说明
规则名称 填写唯一的规则名称(不能用中文)。
消息类型 需要回调的类型,目前有两种消息类型可以回调(chat 为上行消息;chat_offline 为离线消息,可以同时选择)
回调地址 环信 IM 服务器会把消息推送到指定的 URL 地址,支持针对不同类型的消息配置不同的 HTTP 和 HTTPS 回调地址。
Secret (可选)默认情况下,环信 IM 服务器发给 URL(也就是您自己服务器的)的数据,签名时使用的密钥由环信 IM 服务器生成,可通过环信即时通讯 IM Console 管理后台查看。若要使用自定义密钥,可以联系环信商务经理。

chat 上行消息

这个消息跟通过 REST 导出聊天记录查询到的消息一致。比如:一个用户(u1)给另一个用户(u2)发送消息,那么就会产生一条 Chat 消息,与接收方是否在线无关。接收到的消息里面 from 为 u1,to 为 u2。一个用户(u1)给一个群(g1)发送消息,那么会产生一条 Chat 消息,接收到的消息里面 from 为 u1,to 为 g1,且返回值包含 group_id 字段。

chat_offline 离线消息

App 可以根据这个消息做 APNS 推送等个性化的推广。例如:给一个用户发送消息,如果用户不在线,那么会产生一条离线消息。如果给一个群发送消息,那么群里有几个用户不在线,就会产生几条离线消息,那么这几条离线消息的 to 为接收消息用户的 ID,并不是群组 ID。

chat_type 的选择

  • 如果 app 只需要用户的聊天记录,则配置 Chat 类型消息的回调即可。
  • 如果 app 只需要针对离线消息做 APNS 等推送,则配置 chat_offline 类型的消息回调即可。
  • 如果 app 需同时对用户的聊天记录和离线消息进行处理,则需要配置 chat 和 chat_offline 两种类型的消息回调。
  1. 从环信服务器向你的应用服务器发送请求

请求采用 POST 方式,支持 HTTP/HTTPS,正文部分为 JSON 格式的字符串,字符集为 UTF-8。

回调时,会对发送的正文做 MD5 签名。 环信 IM 使用的 MD5 为 org.apache.commons.codec.digest.DigestUtils#md5Hex

app 的响应内容不能超过 1,000 个字符,否则环信服务器会认为是攻击,导致回调失败。

回调消息的参数说明

参数 类型
callId callId 为 {appkey}_{uuid} 其中 UUID 为随机生成,作为每条回调的唯一标识。
eventType “chat” 上行消息、“chat_offline” 离线消息。
timestamp 环信 IM 服务器接收到此消息的 Unix 时间戳,单位为毫秒。
chat_type “chat” 单聊回调、“groupchat” 群聊回调包含了群组和聊天室的消息回调,默认全选。
group_id 群聊时才有此参数,回调消息所在的群组。
from 消息的发送方。
to 消息的接收方。
msg_id 消息的 ID。
payload 消息内容,与通过 REST API 发送过来的一致,查看消息格式文档
securityVersion安全校验版本,目前为 1.0.0。忽略此参数,以后会改成控制台做设置。
security 签名,格式如下: MD5(callId+Secret+timestamp)。 Secret 见 Console 后台回调规则。

回调成功返回的示例

{
    "callId":"easemob-demo#test_0990a64f-dp01-6c50-8696-cf3b48b20e7e",
    "eventType":"chat_offline",
    "timestamp":1600060847294,
    "chat_type":"groupchat", 
    "group_id":"16934809238921545",
    "from":"user1",
    "to":"user2",
    "msg_id":"8924312242322",
    "payload":{
    // 具体的消息内容。
    },
    "securityVersion":"1.0.0",
    "security":"2ca02c394bef9e7abc83958bcc3156d3"
}

Payload 数据格式说明

应答包字段说明

环信 IM 服务器不会验证响应的 response 内容,只要你的服务器给我们返回 HTTP 状态码是 200 即认为将消息回调成功。

  1. 查询回调存储详情和补发回调消息

查询回调储存详情接口描述

查询 App Key 下由于异常(比如链接超时,响应超时,回调规则封禁等)回调失败时存储的消息和事件类型集合,按每十分钟一个 date key 存储,然后用户可以根据消息集合按需拉取。

功能限制说明

  • 异常存储过期时间默认 3 天,若有存储需及时补发。
  • 补发重试次数建议控制在 10 次以内。

认证方式

环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 Authorization 字段:

Authorization:Bearer ${YourAppToken}

为提高项目的安全性,使用 token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 仅支持使用 App Token 的鉴权方式,详见使用 Token 鉴权

基本信息

方法:GET

接入点: /{orgName}/{appName}/callbacks/storage/info

路径参数

参数 类型 是否必需描述
orgNameString你在环信 IM 管理后台注册的组织唯一标识。
appNameString你在环信 IM 管理后台注册的 App 唯一标识 。

请求头

参数 类型 是否必需描述
AuthorizationString鉴权 Token,管理员 Token(含)以上权限。

响应参数

参数 类型 描述
path string请求路径。
uri string请求路径的 URI。
timestamp long 环信 IM 服务器接收到此消息的 Unix 时间戳,单位为毫秒。
organization string你在环信 IM 管理后台注册的组织唯一标识。
application string你在环信 IM 管理后台注册的 App 唯一标识。
action string请求方法。
duration long 请求耗时,单位为毫秒。
applicationNamestring你在环信 IM 管理后台注册的 App 名称。
data object响应数据内容。包括以下三个参数:datesizeretry
date String代表本次可以发送的补发的一个十分钟 date key,key 为十分钟的起点。
size Int 本时段消息数量。
retry Int 开发者已经重试补发的次数。考虑到补发也可能失败,服务器会继续存储。最开始是 0。

请求示例

curl -X GET 'http://a1.easemob.com/easemob-demo/easeim/callbacks/storage/info' \
-H 'Authorization: Bearer {{token}}'

响应示例

{
    "path": "/callbacks",
    "uri": "http://a1.easemob.com/easemob-demo/easeim/callbacks",
    "timestamp": 1631193031254,
    "organization": "easemob-demo",
    "application": "8dfb1641-b6d8-450b-bbe9-d8d45a3be39f",
    "action": "post",
    "data": [
        {
            "date": "202109091440",
            "size": 15,
            "retry": 0
        },
        {
            "date": "202109091450",
            "size": 103,
            "retry": 1
        }
    ],
    "duration": 153,
    "applicationName": "easeim"
}

补发回调存储信息接口描述

调用接口根据存储集合进行回调补发。

基本信息

方法:POST

接入点: http://{host}/{orgName}/{appName}/callbacks/storage/retry

路径参数

参数 类型 是否必需描述
orgNameString你在环信 IM 管理后台注册的组织唯一标识。
appNameString你在环信 IM 管理后台注册的 App 唯一标识。

请求头

参数 类型 是否必需描述
Content-Type Stringapplication/json
AuthorizationString鉴权 App Token 的值。详见使用 token 鉴权

请求体

参数 类型 是否必需描述
date String可以补发的一个十分钟 date key,key 为十分钟的起点。
retry Int 开发已重试的次数。考虑到补发也可能失败,服务器会继续存储。最开始是 0。
targetUrlString补发消息的回调地址,如果为空,则使用原回调规则的回调地址。

响应参数

参数 类型 描述
path String 请求路径。
uri String 请求路径的 URI。
timestamp long 环信 IM 服务器接收到此消息的 Unix 时间戳,单位为毫秒。
organizationString 你在环信 IM 管理后台注册的组织唯一标识。
application String 你在环信 IM 管理后台注册的 app 唯一标识。
action String 请求方法。
data Bool- success:成功;
- failure:失败。
duration long 请求耗时,单位为毫秒。
retry Int 开发者已经重试补发的次数。考虑到补发也可能失败,服务器会继续存储。最开始是 0。

请求示例

curl -X POST 'http://a1.easemob.com/easemob-demo/easeim/callback/storage/retry' \
-H 'Authorization: Bearer {{token}}' \
-H 'Content-Type: application/json' \
--data-raw '{
    "date": "202108272230",
    "retry": 0,
    "targetUrl": "http://localhost:8000/test"
}'

响应示例

{
    "path": "/callbacks",
    "uri": "http://a1.easemob.com/easemob-demo/easeim/callbacks",
    "timestamp": 1631194031721,
    "organization": "easemob-demo",
    "application": "8dfb1641-b6d8-450b-bbe9-d8d45a3be39f",
    "action": "post",
    "data": "success",
    "duration": 225,
    "applicationName": "easeim"
}

响应码说明

状态码描述
200请求成功。
400请求参数错误,请根据返回提示检查。
401用户权限错误。
403服务未开通或权限不足。
429单位时间内请求过多。
500服务器内部错误。