帮助文档
  1. 开发者手册
帮助文档
  • 产品介绍
    • 产品价值及介绍
    • 产品应用场景
    • 产品重点特性
    • 系统架构
    • 部署架构
    • 资质背书
  • 管理员手册
    • 入门必读
    • 第三方服务同步配置
      • 钉钉
      • 飞书
      • 企业微信
      • 腾讯会议
      • ExchangeWebService国际版
      • Outlook国际版
      • Outlook国内版
  • 功能详解
    • 我的企业
      • 概要
      • 首页
      • 通讯录
      • 空间资源
      • 权限管理
      • 安全
      • 第三方对接
      • 操作日志
      • 增值服务
    • 设备资产
      • 概要
      • 设备关联
      • 分配空间
      • 设备标签
      • 设备巡检
      • 解绑设备
    • 设备管控
      • 设备监控
      • 巡检报告
      • 设备控制
      • 设备详情
      • 定时任务
      • 告警策略
      • 远程桌面
      • 应用管理
      • 文件推送
      • 壁纸推送
      • 消息推送
      • 命令行推送
      • 弹窗拦截
      • 设备看板
      • 权限管理
      • 操作记录
    • 会议管理
      • 会议室管理
      • 会议管理
      • 预约配置
      • 通知配置
      • 门牌配置
      • 门禁配置
      • 会议数据
      • 权限管理
      • 操作记录
    • 内容宣发
      • 概要
      • 内容制作
      • 信息发布
      • 设备主页
      • 设备屏保
      • 展厅播控
      • 智能迎宾
      • 操作记录
      • 组件
    • 其他功能
      • 消息通知
      • 个人中心
      • 专属服务
  • 方案产品
    • 会议预约小程序
    • 会议预约web端
    • 腾讯会议对接
    • 设备助手
    • 门牌&门禁
    • 展厅控制屏
    • 会控屏
  • 开发者手册
    • API调用指南(必看)
      • 调用流程概述
      • 公共参数
      • 最佳实践 - 三方系统约会显示在在门牌上
      • 最佳实践 - 代码实现参考(JAVA)
    • 接口授权
      • 生成客户端令牌
    • 单点登录
      • 手机号免密登录授权
    • 通讯录管理
      • 分页查询成员
      • 查询成员
      • 根据外部id查询成员
      • 创建成员
      • 更新成员
      • 删除成员
      • 分页查询团队列表
      • 查询团队
      • 根据外部ID查询团队
      • 创建团队
      • 更新团队
      • 删除团队
      • 根据手机号查询成员id
      • 根据邮箱查询成员id
    • 空间管理
      • 更新空间
      • 分页查询空间
      • 创建空间(楼层)
      • 创建空间
      • 查询空间分类
      • 通过空间ID获取空间
      • 删除空间
      • 查询空间日程
    • 设备管理
      • 设备控制
        • 设备指令下发
      • 设备信息
        • 获取设备详情
        • 获取设备属性
        • 修改设备属性
        • 获取设备品类支持的指令集
    • 事件回调
      • 注册回调
      • 会议事件回调
      • 参会人事件回调
      • 用户签到事件回调
      • 失败记录
      • 清除失败记录
      • 查询失败记录
      • 取消回调
      • 注册回调
    • 日程管理
      • 日程
        • 创建会议日程
        • 更新会议日程
        • 取消会议日程
        • 结束会议日程
        • 会议日程签到
        • 查询会议日程详情
        • 创建周期日程
        • 取消周期日程
        • 查询周期日程
        • 更新周期日程
      • 参会人
        • 查询成员日程列表
        • 确认参加会议日程
        • 查询参会人闲忙
        • 批量删除参会人
        • 批量添加参会人
        • 拒绝参加会议日程
        • 会议日程请假
      • 签到
        • 查询会议日程的人员签到记录
      • 会议室
        • 查询会议室闲忙
        • 释放会议室
        • 预定会议室
  • 更新日志
    • 1.7.1 版本
    • 1.8.1版本
    • 1.8.6版本
  1. 开发者手册

事件回调

注册回调#

通过注册回调,可以订阅会议、会议室、通讯录的数据变更事件,服务器在服务数据发生变更的时候通过回调方式通知业务方。一个企业只能注册一个接收回调的url。
注册流程如下:
An image
请求方式: POST(HTTPS)
请求地址: https://apis.maxhub.com/hook/api/v1/client/hooks/actions/register
请求body:
{
    "company_code": "000111333",
    "url": "https://www.example.com/callback",
    "token": "wrdolYCN8nM0",
    "encrypt_key": "RUt5eZGDz3tM28qmeHSVsRwoUCa4NuviP2VknMmE0kJ",
    "event_tags": [
        "meeting_create",
        "meeting_update",
        "meeting_delete"
    ]
}
参数说明:
参数必须说明
company_code是企业编码,即企业管理后台显示的企业ID(登录企业管理后台,在首页可以看到)
url是事件回调的接口路径,必须是合法的url
token是3-32位长度的由字母或数字组成的字符串,用于校验消息合法性
encrypt_key是43位长度的由字母或数字组成的字符串,用于加解密消息
event_tags是需要订阅的事件,可以是事件类型,也可以是事件分组,填了事件分组,即订阅该分组下的全部事件
返回结果:
{
  "message": "ok"
}
参数说明:
参数说明
message固定值ok

校验回调路径#

注册回调时,MAXHUB服务器会向回调路径发起POST请求,只有回调路径在5秒内返回正确结果才能注册成功,否则注册失败。业务方可以通过校验signature合法性,以及data解密后的内容是否正确,来验证回调数据是否正确。如果校验正确,业务方需要在response的body中返回新生成的signature。
回调注册成功后,事件回调的返回参数、加解密方式、签名校验方式跟这里描述的一样,后面不在赘述。唯一不同的是,data解密出来的内容不同,在具体的【事件回调】章节中会详细说明。
POST请求的body参数:
{
    "nonce": "8iyBhg4q",
    "timestamp": 1602317904000,
    "data": "QKw5S2xCLQ276c95HhJNvPkY+8IecD3bKwfFmi/DLk/292+90/H0O1bi12/0dGWM",
    "signature": "613817568cc8aa6a1ea6c1e6945296f5a95e1473"
}
参数说明:
参数说明
nonce随机字符串
timestamp时间戳
data经过AES加密,并转成base64字符串的回调数据
signature消息签名
data解密后的消息内容:
{
	"event_type": "check_url",
	"message": {
        "_id": "8b2edc1f-a869-4d87-ae9f-1beec7a0c513",
		"_timestamp": 1602742001287
    }
}
参数说明:
参数说明
event_type事件类型,对于回调路径的校验,此为固定值check_url
message事件内容,对于回调路径的校验,此为固定值{}
— _id事件ID
— _timestamp事件发生时的时间戳
业务方需要返回新生成的signature:
signature=sha1("nonce=xxx&token=xxx")
signature的生成方式参考:生成signature,但此处生成signature只需要nonce和token两个字段。业务方务必返回正确的signature,才能注册成功。
{
    "signature": "5c01a87d5832f1fd7d176dfc2c0abbdc899ab0f8"
}

data的加解密#

data=base64_encode(aes(消息内容, base64_decode(encrypt_key+"=")))
1.
消息内容为json格式的字符串;
2.
aes_key会从encrypt_key通过base64解码得来,长度为32字节aes_key=base64_decode(encrypt_key+"=");
3.
aes_key为AES加解密的密钥,AES采用CBC模式,数据采用PKCS#7填充,IV初始向量大小为16字节,取aes_key的前16字节;
加密示例:
String dataJson = "{\"event_type\":\"check_url\",\"message\":{}}";
String encryptKey = "RUt5eZGDz3tM28qmeHSVsRwoUCa4NuviP2VknMmE0kJ";
byte[] aesKey = java.util.Base64.getDecoder().decode(encryptKey + "=");
byte[] iv = new byte[16];
System.arraycopy(aesKey, 0, iv, 0, 16);

java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS7Padding");
javax.crypto.spec.SecretKeySpec keySpec = new javax.crypto.spec.SecretKeySpec(aesKey, "AES");
javax.crypto.spec.IvParameterSpec ivSpec = new javax.crypto.spec.IvParameterSpec(iv);
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] cipherText = cipher.doFinal(dataJson.getBytes(java.nio.charset.Charset.forName("UTF-8")));
String data = java.util.Base64.getEncoder().encodeToString(cipherText);
AES加密如果抛出异常:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding
需要添加如下jar:
<!-- 不同jdk对应的版本可能会不一样,具体版本可以在该网址中找到:https://www.bouncycastle.org/latest_releases.html -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15to18</artifactId>
    <version>1.66</version>
</dependency>
并在代码中添加以下一行:
解密示例:
String data = "QKw5S2xCLQ276c95HhJNvPkY+8IecD3bKwfFmi/DLk/292+90/H0O1bi12/0dGWM";
byte[] cipherText = java.util.Base64.getDecoder().decode(data);
String encryptKey = "RUt5eZGDz3tM28qmeHSVsRwoUCa4NuviP2VknMmE0kJ";
byte[] aesKey = java.util.Base64.getDecoder().decode(encryptKey + "=");
byte[] iv = new byte[16];
System.arraycopy(aesKey, 0, iv, 0, 16);

java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS7Padding");
javax.crypto.spec.SecretKeySpec keySpec = new javax.crypto.spec.SecretKeySpec(aesKey, "AES");
javax.crypto.spec.IvParameterSpec ivSpec = new javax.crypto.spec.IvParameterSpec(iv);
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] plainText = cipher.doFinal(cipherText);
String dataJson = new String(plainText, java.nio.charset.Charset.forName("UTF-8"));

生成signature#

signature=sha1("data=xxx&nonce=xxx&timestamp=xxx&token=xxx")
将token(注册回调时提交的token)、nonce、timestamp、data几个字段根据字典顺序排序,再将各字段的key和value使用“=”拼接在一起,再使用“&”将各字段拼接在一起,得到待签名字符串,然后进行sha1签名,得到signature。
签名示例:

取消回调#

请求方式: POST(HTTPS)
请求地址: https://apis.maxhub.com/hook/api/v1/client/hooks/actions/unregister
请求body:
{
    "company_code": "000111333"
}
参数说明:
参数必须说明
company_code是企业编码,即企业管理后台显示的企业ID(登录企业管理后台,在首页可以看到)
返回结果:
{
  "message": "ok"
}
参数说明:
参数说明
message固定值ok
修改于 2024-05-29 01:10:58
上一页
获取设备品类支持的指令集
下一页
注册回调