飞书 API
  1. 订阅流程
飞书 API
  • 应用权限
    • 简介
    • 权限列表
  • API 调用服务指南
    • API 列表
    • 通用参数
    • 频控策略
    • 通用错误码
    • 调用流程
      • 流程概述
      • 申请权限
      • 获取访问凭证
      • 设置 IP 白名单
      • 调用 API
  • 事件订阅指南
    • 概述
    • 事件列表
    • 订阅流程
      • 配置 Encrypt Key
      • 修改 Verification Token
      • 配置请求地址
      • 添加事件
      • 申请权限
      • 接收并处理事件
  • 服务端 SDK
    • 服务端 SDK
  • 鉴权管理
    • 访问凭证
      • 自建应用获取 tenant_access_token
      • 自建应用获取 app_access_token
      • 商店应用获取 app_access_token
      • 商店应用获取 tenant_access_token
      • 获取 user_access_token
      • 刷新 user_access_token
      • 重新获取 app_ticket
    • 登录态管理
      • 资源介绍
      • 获取登录预授权码
      • 获取登录用户信息
      • 批量获取脱敏的用户登录信息
  • 事件管理
    • 获取事件出口 IP
      GET
  • 通讯录
    • 概述
    • 常见问题
    • 权限范围
      • 资源介绍
      • 权限范围详解
      • 事件
        • 通讯录权限范围变更
      • 获取通讯录授权范围
    • 用户
      • 资源介绍
      • 国家/地区 Code 参照表
      • 事件
        • 员工信息被修改
        • 员工离职
        • 员工入职
      • 创建用户
      • 删除用户
      • 修改用户部分信息
      • 获取单个用户信息
      • 更新用户所有信息
      • 获取单个用户信息
      • 获取部门直属用户列表
      • 通过手机号或邮箱获取用户 ID
    • 用户组
      • 资源介绍
      • 创建用户组
      • 删除用户组
      • 更新用户组
      • 查询指定用户组
      • 查询用户组列表
      • 查询用户所属用户组
    • 自定义用户字段
      • 资源介绍
      • 事件
        • 成员字段变更
      • 获取企业自定义用户字段
    • 人员类型
      • 资源介绍
      • 事件
        • 新建人员类型
        • 启用人员类型
        • 停用人员类型
        • 删除人员类型
        • 修改人员类型名称
      • 新增人员类型
      • 删除人员类型
      • 更新人员类型
      • 查询人员类型
    • 部门
      • 资源介绍
      • 事件
        • 创建部门
        • 删除部门
        • 修改部门信息
      • 创建部门
      • 删除部门
      • 修改部门部分信息
      • 获取单个部门信息
      • 更新部门所有信息
      • 部门群转为普通群
      • 获取单个部门信息
      • 获取子部门列表
      • 获取父部门信息
      • 搜索部门
    • 单位
      • 资源介绍
      • 创建单位
      • 删除单位
      • 修改单位信息
      • 建立部门与单位的绑定关系
      • 解除部门与单位的绑定关系
      • 获取单位绑定的部门列表
      • 获取单位信息
      • 获取单位列表
    • 用户组成员
      • 资源介绍
      • 添加用户组成员
      • 批量添加用户组成员
      • 移除用户组成员
      • 查询用户组成员列表
      • 批量移除用户组成员
  • 消息
    • 概述
    • 常见问题
    • 消息内容介绍
      • 发送消息内容
      • 接收消息内容
    • 消息管理
      • 资源介绍
      • 事件
        • 接收消息
        • 消息已读
        • 撤回消息
      • 发送消息
      • 回复消息
      • 撤回消息
      • 查询消息已读信息
      • 获取会话历史消息
      • 获取消息中的资源文件
      • 获取指定消息的内容
    • 消息加急
      • 发送应用内加急
      • 发送短信加急
      • 发送电话加急
    • 批量消息
      • 批量发送消息
      • 批量撤回消息
      • 查询批量消息推送和阅读人数
      • 查询批量消息整体进度
    • 图片信息
      • 上传图片
      • 下载图片
    • 文件信息
      • 上传文件
      • 下载文件
    • 消息-消息卡片
      • 资源介绍
      • 更新应用发送的消息卡片
      • 延时更新消息卡片
      • 发送仅特定人可见的消息卡片
      • 删除仅特定人可见的消息卡片
    • 表情回复
      • 资源介绍
      • 表情文案说明
      • 事件
        • 新增消息表情回复
        • 删除消息表情回复
      • 添加消息表情回复
      • 删除消息表情回复
      • 获取消息表情回复
    • Pin
      • Pin 消息
      • 移除 Pin 消息
      • 获取群内 Pin 消息
  • 群组
    • 概述
    • 群组管理
      • 资源介绍
      • 群 ID 说明
      • 事件
        • 群解散
        • 群配置修改
      • 创建群
      • 解散群
      • 更新群信息
      • 更新群发言权限
      • 获取群信息
      • 更新群置顶
      • 撤销群置顶
      • 获取用户或机器人所在的群列表
      • 搜索对用户或机器人可见的群列表
      • 获取群成员发言权限
      • 获取群分享链接
    • 群成员
      • 资源介绍
      • 事件
        • 用户进群
        • 用户出群
        • 撤销拉用户进群
        • 机器人进群
        • 机器人被移出群
        • 用户和机器人的会话首次被创建
      • 指定群管理员
      • 删除群管理员
      • 将用户或机器人拉入群聊
      • 用户或机器人主动加入群聊
      • 将用户或机器人移出群聊
      • 获取群成员列表
      • 判断用户或机器人是否在群里
    • 群公告
      • 资源介绍
      • 更新群公告信息
      • 获取群公告信息
    • 会话标签页
      • 添加会话标签页
      • 删除会话标签页
      • 更新会话标签页
      • 会话标签页排序
      • 拉取会话标签页
    • 群菜单
      • 资源介绍
      • 添加群菜单
      • 删除群菜单。
      • 修改群菜单元信息
      • 排序群菜单
      • 获取群菜单
  • 云文档
    • 概述
    • 常见问题
    • 云空间
      • 云空间概述
      • 云空间常见问题
      • 文件夹
        • 获取我的空间(root folder)元信息
        • 获取文件夹下的清单
        • 获取文件夹元信息
        • 新建文件夹
        • 移动文件
        • 删除文件
      • 文件
        • 异步任务状态
          • 查询异步任务状态
        • 获取文档元数据
        • 新建在线文档
        • 复制文件
        • 移动文件
        • 删除文件
        • 获取文件统计信息
      • 素材
        • 素材概述
        • 分片上传素材
          • 概述
          • 分片上传素材(预上传)
          • 分片上传素材(上传分片)
          • 分片上传素材(完成上传)
        • 上传素材
        • 下载素材
        • 获取素材临时下载链接
      • 事件
        • 列表
          • 多维表格字段变更
          • 多维表格记录变更
          • 文件标题变更
          • 文件已读
          • 文件编辑
          • 文件协作者添加
          • 文件协作者移除
          • 文件删除到回收站
          • 文件彻底删除
        • 订阅云文档事件
      • 搜索
        • 文档搜素
      • 上传
        • 分片上传文件
          • 概述
          • 分片上传文件(预上传)
          • 分片上传文件(上传分片)
          • 分片上传文件(完成上传)
        • 上传文件
      • 下载
        • 下载文件
      • 导入
        • 概述
        • 创建导入任务
        • 查询导入结果
      • 导出
        • 导出文件指南
        • 创建导出任务
        • 查询导出任务结果
        • 下载导出文件
      • 文档版本
        • 概述
        • 创建文档版本
        • 删除文档版本
        • 获取文档版本
        • 获取文档版本列表
    • 权限
      • 权限概述
      • 常见问题
      • 成员
        • 转移所有者
        • 判断当前用户是否有某权限
        • 获取协作者列表(新版本)
        • 获取协作者列表
        • 增加协作者权限
        • 更新协作者权限
        • 移除协作者权限
      • 设置
        • 获取云文档权限设置
        • 更新云文档权限设置
    • 评论
      • 分页获取文档评论
      • 添加评论
      • 获取评论
      • 更新回复
      • 删除回复
      • 解决/恢复 评论
    • 文档
      • 新版文档接入指南
      • 新版文档
        • 概述
        • 数据结构
        • 接入指南
        • 文档
          • 获取文档基本信息
          • 获取文档纯文本内容
          • 获取文档所有块
          • 创建文档
        • 块
          • 获取块
          • 创建块
          • 更新块
          • 批量更新块
          • 删除块
          • 获取所有子块
      • 旧版文档
        • 概述
        • 准备接入文档 API
        • 文档数据结构概述
        • 文档数据结构参考
        • 文档
          • 创建文档
        • 内容
          • 获取文档富文本内容
          • 获取文档文本内容
          • 编辑文档内容
    • 权限
      • 权限成员
        • 增加权限
        • 判断协作者是否有某权限
      • 权限设置
        • 获取文档公共设置V2
        • 更新文档公共设置
      • 转移拥有者
    • 电子表格
      • 概述
      • 电子表格常见问题
      • 支持写入的数据类型
      • 支持数字格式类型
      • 表格
        • 修改电子表格属性
        • 获取电子表格信息
        • 创建表格
      • 工作表
        • 查询工作表
        • 获取工作表
        • 操作工作表
        • 更新工作表属性
      • 行列
        • 增加行列
        • 插入行列
        • 更新行列
        • 移动行列
        • 删除行列
      • 单元格
        • 追加数据
        • 插入数据
        • 读取单个范围
        • 读取多个范围
        • 向单个范围写入数据
        • 向多个范围写入数据
        • 设置单元格样式
        • 批量设置单元格样式
        • 写入图片
        • 合并单元格
        • 拆分单元格
        • 查找单元格
        • 替换单元格
      • 筛选
        • 筛选指南
        • 获取筛选
        • 创建筛选
        • 更新筛选
        • 删除筛选
      • 筛选视图
        • 筛选条件
          • 筛选视图的筛选条件指南
          • 创建筛选条件
          • 查询筛选条件
          • 更新筛选条件
          • 删除筛选条件
          • 获取筛选条件
        • 更新筛选视图
        • 获取筛选视图
        • 查询筛选视图
        • 创建筛选视图
        • 删除筛选视图
      • 表格操作
        • 创建表格
        • 获取表格元数据
        • 更新表格属性
        • 操作工作表
        • 更新工作表属性
      • 保护范围
        • 增加保护范围
        • 获取保护范围
        • 修改保护范围
        • 删除保护范围
      • 数据校验
        • 概述
        • 设置下拉列表
        • 删除下拉列表设置
        • 更新下拉列表设置
        • 查询下拉列表设置
      • 条件格式
        • 条件格式指南
        • 创建条件格式
        • 获取条件格式
        • 更新条件格式
        • 删除条件格式
      • 浮动图片
        • 浮动图片指南
        • 创建浮动图片
        • 获取浮动图片
        • 查询浮动图片
        • 更新浮动图片
        • 删除浮动图片
    • API参考
      • 创建文档
      • 编辑文档内容
      • 历史文档(不建议)
        • 获取文档中的电子表格的元数据
      • 获取文档元信息
    • 多维表格
      • 概述
      • 接入指南
      • 数据结构
      • 多维表格
        • 获取多维表格元数据
        • 更新多维表格元数据
      • 数据表
        • 更新数据表
        • 列出数据表
        • 新增数据表
        • 新增多个数据表
        • 删除一个数据表
        • 删除多个数据表
      • 仪表盘
        • 复制仪表盘
        • 列出仪表盘
      • 视图
        • 更新视图
        • 检索视图
        • 列出视图
        • 新增视图
        • 删除视图
      • 表单
        • 更新表单元数据
        • 获取表单元数据
        • 更新表单问题
        • 列出表单问题
      • 记录
        • 记录筛选开发指南
        • 检索记录
        • 列出记录
        • 新增记录
        • 更新记录
        • 删除记录
        • 新增多条记录
        • 更新多条记录
        • 删除多条记录
      • 字段
        • 字段编辑指南
        • 附件字段说明
        • 列出字段
        • 新增字段
        • 更新字段
        • 删除字段
      • 高级权限
        • 概述
        • 自定义角色
          • 列出自定义角色
          • 新增自定义角色
          • 删除自定义角色
          • 更新自定义角色
        • 协作者
          • 批量删除协作者
          • 批量新增协作者
          • 列出协作者
          • 新增协作者
          • 删除协作者
    • 知识库
      • 概述
      • 常见问题
      • 知识空间
        • 创建知识空间
        • 获取知识空间列表
        • 获取知识空间信息
      • 空间成员
        • 删除知识空间成员
        • 添加知识空间成员
      • 空间设置
        • 更新知识空间设置
      • 节点
        • 创建知识空间节点
        • 获取知识空间节点信息
        • 获取知识空间子节点列表
        • 移动知识空间节点
        • 更新知识空间节点标题
        • 创建知识空间节点副本
      • 任务
        • 获取任务结果
      • 云文档
        • 移动云空间文档至知识空间
        • 获取任务结果
      • 搜索 Wiki
        • 搜索 Wiki
    • 云文档助手
      • 订阅
        • 获取订阅状态
        • 创建订阅
        • 更新订阅状态
  • 日历
    • 概述
    • 常见问题
    • 日历管理
      • 资源介绍
      • 事件
        • 日历变更
      • 获取主日历
      • 创建共享日历
      • 删除共享日历
      • 查询主日历信息
      • 查询主日历忙闲信息
      • 查询日历信息
      • 查询日历列表
      • 更新日历
      • 搜索日历
      • 订阅日历
      • 取消订阅日历
      • 订阅日历变更事件
      • 取消订阅日历变更事件
    • 日历访问控制
      • 资源介绍
      • 事件
        • 创建 ACL
        • 删除 ACL
      • 取消订阅日历访问控制变更事件
      • 创建访问控制
      • 删除访问控制
      • 获取访问控制列表
      • 订阅日历访问控制变更事件
    • 日程管理
      • 资源介绍
      • 事件
        • 日程变更
      • 创建日程
      • 删除日程
      • 更新日程
      • 获取日程
      • 获取日程列表
      • 搜索日程
      • 订阅日程变更事件
      • 取消订阅日程变更事件
    • 请假日程管理
      • 资源介绍
      • 创建请假日程
      • 删除请假日程
    • 会议室日程管理
      • 事件
        • 会议室状态信息变更
        • 第三方会议室日程变动
      • 查询会议室日程主题和会议详情
      • 查询会议室忙闲
      • 回复会议室日程实例
    • 日程参与人
      • 资源介绍
      • 获取日程参与群成员列表
      • 添加日程参与人
      • 获取日程参与人列表
      • 删除日程参与人
    • 同步到本地日历
      • 生成 CalDAV 配置
    • 同步 Exchange 日历信息
      • 资源介绍
      • 将 Exchange 账户绑定到飞书账户
      • 解除 Exchange 账户绑定
      • 查询 Exchange 账户的绑定状态
  • 视频会议
    • 视频会议概述
    • 预约
      • 资源介绍
      • 预约会议
      • 删除预约
      • 更新预约
      • 获取预约
      • 获取活跃会议
    • 会议
      • 资源介绍
      • 事件
        • 企业会议开始
        • 企业会议结束
        • 会议开始
        • 会议结束
        • 加入会议
        • 离开会议
        • 开始录制
        • 停止录制
        • 录制完成
        • 屏幕共享开始
        • 屏幕共享结束
      • 邀请参会人
      • 移除参会人
      • 设置主持人
      • 结束会议
      • 获取会议详情
      • 获取与会议号相关联的会议列表
    • 录制
      • 资源介绍
      • 开始录制
      • 停止录制
      • 获取录制文件
      • 授权录制文件
    • 会议报告
      • 资源介绍
      • 获取会议报告
      • 获取top用户列表
    • 导出
      • 资源介绍
      • 导出会议明细
      • 导出参会人明细
      • 导出参会人会议质量数据
      • 导出会议室预定数据
      • 查询导出任务结果
      • 下载导出文件
    • 会议室层级
      • 资源介绍
      • 创建会议室层级
      • 删除会议室层级
      • 更新会议室层级
      • 查询会议室层级详情
      • 批量查询会议室层级详情
      • 查询会议室层级列表
      • 搜索会议室层级
    • 会议室管理
      • 资源介绍
      • 事件
        • 创建会议室
        • 更新会议室
        • 删除会议室
      • 创建会议室
      • 删除会议室
      • 更新会议室
      • 查询会议室详情
      • 批量查询会议室详情
      • 查询会议室列表
      • 搜索会议室
    • 会议室配置
      • 资源介绍
      • 查询会议室配置
      • 设置会议室配置
      • 获取会议室预定范围
      • 更新会议室预定范围
  • 考勤打卡
    • 概述
    • 接入指南
    • 考勤班次
      • 按名称查询班次
      • 删除班次
      • 创建班次
      • 按 ID 查询班次
      • 查询所有班次
    • 考勤组管理
      • 创建或修改考勤组
      • 删除考勤组
      • 按 ID 查询考勤组
      • 按名称查询考勤组
      • 查询所有考勤组
    • 考勤排班
      • 查询班表信息
      • 创建或修改班表
    • 考勤统计
      • 功能介绍
      • 查询统计表头
      • 更新统计设置
      • 查询统计数据
      • 查询统计设置
    • 假勤审批
      • 获取用户审批通过数据
      • 通知审批状态更新
      • 写入审批结果
    • 考勤补卡
      • 获取可补卡时间
      • 获取补卡记录
      • 通知补卡审批发起
    • 打卡信息管理
      • 批量查询打卡流水
      • 查询打卡流水
      • 获取打卡结果
      • 导入打卡流水
    • 考勤用户管理
      • 事件
        • 用户打卡成功
        • 用户任务状态变更
      • 修改用户人脸识别信息
      • 批量查询用户人脸识别信息
      • 上传用户人脸识别照片
      • 下载用户人脸识别照片
  • 审批
    • 概述
    • 常见问题
    • 接入指南
      • 审批接入指南
      • 原生审批接入指南
      • 商店应用开发指南
      • 三方审批接入
        • 三方审批接入指南
        • 三方审批接入准备
        • 审批官方连接器
    • 原生审批定义
      • 资源介绍
      • 关联外部选项说明
      • 创建审批定义
      • 查看指定审批定义
      • 查询审批定义列表
    • 原生审批实例
      • 资源介绍
      • 创建审批实例
      • 撤回审批实例
      • 抄送审批实例
      • 预览审批流程
      • 批量获取审批实例ID
      • 获取单个审批实例详情
    • 原生审批任务
      • 资源介绍
      • 同意审批任务
      • 拒绝审批任务
      • 转交审批任务
      • 退回审批任务
      • 审批任务加签
      • 重新提交审批任务
    • 原生审批文件
      • 资源介绍
      • 上传文件
    • 原生审批评论
      • 资源介绍
      • 创建评论
      • 删除评论
      • 清空评论
      • 获取评论
    • 三方审批定义
      • 资源介绍
      • 三方快捷审批回调
      • 创建三方审批定义
    • 三方审批实例
      • 资源介绍
      • 同步三方审批实例
      • 校验三方审批实例
    • 三方审批任务
      • 资源介绍
      • 获取三方审批任务状态
    • 审批 Bot 消息
      • 发送审批 Bot 消息
      • 更新审批 Bot 消息
    • 审批查询
      • 查询实例列表
      • 查询抄送列表
      • 查询任务列表
      • 查询用户的任务列表
      • 查询审批 ID(专用)
    • 审批事件
      • 功能介绍
      • 订阅步骤
      • 常见问题
      • 事件接口
        • 订阅审批事件
        • 取消订阅审批事件
      • 公用事件
        • 审批抄送状态变更
        • 审批任务状态变更
        • 审批实例状态变更
        • 审批定义更新
      • 特殊事件
        • 出差审批
        • 外出审批
        • 补卡审批
        • 换班审批
        • 加班审批
        • 请假审批
  • 服务台
    • 概述
    • 接入指南
    • 客服
      • 客服功能管理
        • 更新客服信息
        • 获取客服邮箱
      • 客服工作日程
        • 创建客服工作日程
        • 删除客服工作日程
        • 更新客服工作日程
        • 查询指定客服工作日程
        • 查询全部客服工作日程
      • 客服技能
        • 创建客服技能
        • 删除客服技能
        • 更新客服技能
        • 查询指定客服技能
        • 查询全部客服技能
      • 客服技能规则
        • 客服技能及运算符
        • 获取客服技能列表
    • 工单
      • 事件
        • 创建工单
        • 工单状态变更
      • 工单管理
        • 创建服务台对话
        • 更新工单详情
        • 查询指定工单详情
        • 获取服务台工单内消息图像
        • 回复用户提问结果至工单
        • 查询全部工单详情
        • 获取服务台自定义字段
      • 工单消息
        • 工单消息内容
        • 发送工单消息
        • 获取工单消息详情
        • 服务台机器人向工单绑定的群内发送消息
      • 工单自定义字段
        • 概述
        • 创建工单自定义字段
        • 删除工单自定义字段
        • 更新工单自定义字段
        • 获取指定工单自定义字段
        • 获取全部工单自定义字段
      • 工单自定义字段
    • 知识库
      • 知识库管理
        • 富文本
        • 创建知识库
        • 获取知识库详情
        • 修改知识库
        • 删除知识库
        • 获取全部知识库详情
        • 获取知识库图像
        • 搜索知识库
      • 知识库分类
        • 创建知识库分类
        • 获取知识库分类
        • 更新知识库分类详情
        • 删除知识库分类详情
        • 获取全部知识库分类
    • 推送中心
      • 事件
        • 推送审核通知事件
      • 创建推送
      • 更新推送
      • 查询推送
      • 预览推送
      • 提交审核
      • 取消审核
      • 执行推送
      • 取消推送
    • 事件订阅
      • 订阅服务台事件
      • 取消订阅服务台事件
  • 任务
    • 任务概述
    • Markdown 模块
    • 任务字段补充说明
    • 任务管理
      • 功能介绍
      • 事件
        • 任务信息变更(租户维度)
        • 任务信息变更
      • 创建任务
      • 删除任务
      • 更新任务
      • 完成任务
      • 取消完成任务
      • 查询指定任务
      • 查询所有任务
    • 提醒
      • 功能介绍
      • 新增提醒时间
      • 删除提醒时间
      • 查询提醒时间列表
    • 评论
      • 概述
      • 事件
        • 任务评论信息变更
      • 获取评论列表
      • 创建评论
      • 删除评论
      • 更新评论
      • 获取评论详情
    • 关注人
      • 功能介绍
      • 批量删除关注人
      • 新增关注者
      • 删除指定关注人
      • 获取关注者列表
    • 执行者
      • 功能介绍
      • 批量删除执行者
      • 新增执行者
      • 删除指定执行者
      • 获取执行者列表
  • 邮箱
    • 邮件组
      • 邮件组管理
        • 创建邮件组
        • 删除邮件组
        • 修改邮件组部分信息
        • 修改邮件组全部信息
        • 查询指定邮件组
        • 批量获取邮件组
      • 邮件组成员
        • 创建邮件组成员
        • 删除邮件组成员
        • 查询指定邮件组成员
        • 获取所有邮件组成员
        • 批量创建邮件组成员
        • 批量删除邮件组成员
      • 邮件组别名
        • 创建邮件组别名
        • 删除邮件组别名
        • 获取邮件组所有别名
      • 邮件组权限成员
        • 创建邮件组权限成员
        • 删除邮件组权限成员
        • 获取邮件组权限成员
        • 批量获取邮件组权限成员
        • 批量创建邮件组权限成员
        • 批量删除邮件组权限成员
    • 公共邮箱
      • 公共邮箱管理
        • 创建公共邮箱
        • 删除公共邮箱
        • 修改公共邮箱
        • 修改公共邮箱全部信息
        • 查询所有公共邮箱
        • 查询指定公共邮箱
      • 公共邮箱成员
        • 添加公共邮箱成员
        • 删除公共邮箱成员
        • 删除公共邮箱所有成员
        • 获取公共邮箱成员信息
        • 查询所有公共邮箱成员信息
        • 批量添加公共邮箱成员
        • 批量删除公共邮箱成员
      • 公共邮箱别名
        • 创建公共邮箱别名
        • 删除公共邮箱别名
        • 查询公共邮箱的所有别名
    • 用户邮箱
      • 从回收站删除用户邮箱地址
      • 创建用户邮箱别名
      • 删除用户邮箱别名
      • 获取用户邮箱所有别名
    • 邮箱地址
      • 查询邮箱地址状态
  • 应用信息
    • 应用管理
      • 校验应用管理员
      • 获取应用管理员管理范围
      • 获取应用在企业内的可用范围
      • 获取用户可用的应用
      • 获取企业安装的应用
      • 更新应用可用范围
      • 查询应用管理员列表
    • 应用商店
      • 查询用户是否在应用开通范围
      • 查询租户购买的付费方案
      • 查询订单详情
    • 应用
      • 获取应用版本列表
      • 查看待审核的应用列表
      • 获取应用信息
      • 获取应用版本信息
      • 更新应用审核状态
      • 更新应用分组信息
    • 应用使用情况
      • 获取应用使用概览
    • 应用反馈
      • 更新应用反馈
      • 获取应用反馈列表
    • 事件
      • 新增应用反馈
      • 反馈更新
      • 应用创建
      • 首次启用应用
      • 应用停启用
      • 应用商店应用购买
      • app_ticket 事件
      • 应用卸载
      • 应用可用性范围增加
      • 申请发布应用
      • 撤回应用发布申请
      • 未命名文档
  • 企业信息
    • 获取企业信息
  • 认证信息
    • 获取认证信息
  • 个人设置
    • 系统统计
      • 功能介绍
      • 创建系统状态
      • 删除系统状态
      • 修改系统状态
      • 获取系统状态
      • 批量开启系统状态
      • 批量关闭系统状态
  • 搜索
    • 概述
    • 接入指南
    • 常见问题
    • 数据源
      • 创建数据源
      • 删除数据源
      • 修改数据源
      • 获取数据源
      • 批量获取所有的数据源
    • 数据项
      • 批量为数据项创建索引
      • 为指定数据项创建索引
      • 获取数据项
      • 删除数据项
    • 数据范式
      • 创建数据范式
      • 删除数据范式
      • 修改数据范式
      • 获取数据范式
  • AI 能力
    • 光学字符识别
      • 识别图片中的文字
    • 语音识别
      • 识别语音文件 (ASR)
      • 识别流式语音 (ASR)
    • 机器翻译
      • 识别文本语种
      • 翻译文本
  • 管理后台
    • 登录密码管理
      • 重置用户的企业邮箱密码
    • 数据报表管理
      • 功能介绍
      • 获取部门维度的用户活跃和功能使用数据
      • 获取用户维度的用户活跃和功能使用数据
    • 企业勋章
      • 功能介绍
      • 勋章管理
        • 创建勋章
        • 修改勋章信息
        • 上传勋章图片
        • 获取勋章列表
        • 获取勋章详情
      • 勋章授予名单
        • 创建授予名单
        • 删除授予名单
        • 修改授予名单
        • 获取授予名单列表
        • 获取授予名单详情
  • 飞书人事(标准版)
    • 接入指南
    • 批量获取员工花名册信息
    • 下载人员的附件
  • 飞书人事(企业版)
    • 休假管理
      • 批量查询员工请假记录
  • 招聘
    • 概述
    • 错误码
    • 招聘相关配置
      • 职位
        • 新建职位
        • 更新职位
        • 更新职位设置
        • 获取职位设置
        • 获取职位信息
        • 获取职位上的招聘人员信息
      • 流程
        • 获取招聘流程信息
    • 获取候选人
      • 内推
        • 获取内推信息
    • 候选人管理
      • 人才
        • 通过手机号或邮箱获取人才 ID
        • 获取人才信息
      • 投递流程
        • 投递管理
          • 创建投递
          • 终止投递
          • 获取投递信息
          • 获取投递列表
        • Offer
          • 获取 Offer 信息
        • 入职
          • 更新 e-HR 导入任务结果
          • 操作候选人入职
          • 更新入职状态
          • 通过投递 ID 获取入职信息
          • 通过员工 ID 获取入职信息
      • 备注
        • 创建备注
        • 更新备注
        • 获取备注
        • 获取备注列表
      • 简历来源
        • 获取简历来源列表
    • 附件
      • 获取附件信息
      • 获取附件预览信息
  • OKR
    • 概述
    • OKR周期
      • 获取OKR周期列表
    • OKR 内容
      • 获取用户的 OKR 列表
      • 批量获取OKR
    • 用户OKR
      • 获取用户的OKR列表
    • OKR 进展记录
      • 创建 OKR 进展记录
      • 删除 OKR 进展记录
      • 更新 OKR 进展记录
      • 获取 OKR 进展记录
      • 上传进展记录图片
    • 指标管理
      • 获取指标库
      • 获取指标表
      • 更新指标项
      • 批量更新指标项
      • 获取指标项
  • 实名认证
    • 录入身份信息
    • 上传人脸基准图片
    • 裁剪人脸图片
    • 查询人脸认证结果
  • 智能门禁
    • 概述
    • 用户管理
      • 事件
        • 用户变更
      • 获取单个用户信息
      • 获取用户列表
      • 修改用户部分信息
      • 上传人脸图片
      • 下载人脸图片
    • 门禁设备
      • 获取设备列表
    • 人脸图片
      • 概述
  • 企业百科
    • 概述
    • 草稿
      • 创建草稿
      • 更新草稿
    • 词条
      • 创建免审词条
      • 更新免审词条
      • 提取潜在的百科词条
      • 获取词条详情
      • 获取词条列表
      • 精准搜索词条
      • 模糊搜索词条
      • 词条高亮
    • 分类
      • 获取百科分类
    • 图片管理
      • 上传图片
      • 下载图片
  • 妙记
    • 获取妙计统计数据
      • 获取妙记统计数据
    • 妙记信息
      • 获取妙记信息
  • 工作台
    • 我的常用推荐规则
      • 获取当前设置的推荐规则列表
  • 企业
    • 获取企业信息
  1. 订阅流程

接收并处理事件

为了让开发者可以便捷地接收并处理事件,飞书开放平台提供了 Java SDK、Golang SDK 和 NodeJS SDK。有关 SDK 的详细介绍,可以参考服务端 SDK 介绍。
本文介绍基本的事件处理方法。接收到事件后,一般需要对事件进行安全校验和解密。
可以查看事件列表,了解目前支持订阅的所有事件。
如果应用没有及时接收到订阅的事件,可以在开发者后台,日志检索 > 事件日志检索 页面,查看日志信息,确认飞书开放平台是否推送了所订阅的事件。
img

事件推送逻辑#

推送加密事件#

如果配置了Encrypt Key,在进行业务逻辑处理前,需要先对事件解密。有关 Encrypt Key 配置方法的详细介绍,请参考(可选)配置 Encrypt Key。有关事件解密方法的详细介绍,请参考本文下方的事件解密。

推送周期和频次#

订阅的事件发生时,飞书将会通过 HTTP POST 请求发送 JSON 格式的事件数据到预先配置的请求地址。
应用收到 HTTP POST 请求后,需要在 1 秒内以 HTTP 200 状态码响应该请求。否则飞书开放平台认为本次推送失败,并以 15s、5m、1h、6h 的间隔重新推送事件,最多重试 4 次。
从上述描述可以看出,事件重发的最长时间窗口约为 7.5 小时,请检查和处理在 7.5 小时内的重复事件。可以使用如下方式判断事件唯一性:
对于 1.0 版本的事件,通过事件结构中的 uuid 字段判断事件唯一性。
对于 2.0 版本的事件,通过事件结构中的 event_id 字段判断事件唯一性。下面对事件结构进行了详细介绍。

事件推送顺序#

为了保证用户的事件可用性以及内外部数据变化一致性,对于部分事件,开放平台使用了有序事件的形式进行推送。即在用户对前一事件接收成功后,才会推送下一事件。
对于有序事件,用户需要保证相应前后事件的正常消费,避免造成事件的阻塞或收到事件不及时。

事件结构#

事件包括 v1.0 和 v2.0 两个版本,不同版本的事件结构不同。添加事件时,从页面上可以看出,添加的是哪个版本的事件。
img

v1.0 版本事件结构#

下面列举了一个 v1.0 版本的事件示例。
ts 字段表示事件发送的时间,一般近似于事件发生的时间。
uuid 字段是事件的唯一标识。
token 字段即 Verification Token。
event 结构体记录的是事件的详细信息,不同事件的信息不同。其中,通过 event.type 字段,可以判断事件类型。
{ 
    "ts": "1502199207.7171419",
    "uuid": "bc447199585340d1f3728d26b1c0297a",
    "token": "41a9425ea7df4536a7623e38fa321bae",
    "type": "event_callback",
    "event": { 
        "app_id": "cli_9c8609450f78d102",
        "chat_id": "oc_26b66a5eb603162b849f91bcd8815b20",
        "operator": {
            "open_id": "ou_2d2c0399b53d06fd195bb393cd1e38f2",
            "user_id": "gfa21d92"
        },
        "tenant_key": "736588c9260f175c",
        "type": "p2p_chat_create",
        "user": {
            "name": "user_name",
            "open_id": "ou_7dede290d6a27698b969a7fd70ca53da",
            "user_id": "gfa21d92"
        }
    }
}

v2.0 版本事件结构#

下面列举了一个 v2.0 版本的事件示例。
schema 字段表示事件的版本。v1.0 版本的事件,无此字段。
header.event_id 字段是事件的唯一标识。
header.token 字段即 Verification Token。
header.create_time 字段表示事件发送的时间,一般近似于事件发生的时间。
header.event_type 字段表示事件类型。
event 结构体记录的是事件的详细信息,不同事件的信息不同。
{
    "schema": "2.0",
    "header": { 
        "event_id": "f7984f25108f8137722bb63cee927e66",
        "token": "066zT6pS4QCbgj5Do145GfDbbagCHGgF",
        "create_time": "1603977298000000",
        "event_type": "contact.user_group.created_v3",
        "tenant_key": "xxxxxxx",
        "app_id": "cli_xxxxxxxx",
    },
    "event":{
    }
}

事件处理方法#

为了提升事件订阅的安全性,接收到飞书开放平台推送的事件后,可以进行安全校验。如果是加密事件,需要先解密事件,再解析事件详情。

安全校验#

业务方收到开放平台推送的事件时(不包括请求网址校验),如果需要确保这个请求的来源是开放平台而非伪造,有两种方式进行安全校验:Verification Token 校验和签名校验。

Verification Token 校验#

这种校验方式简单,但是安全性较低:
如果是加密事件,需要解密和解析事件,获取 Verification Token 进行校验。
请参考本文下方的事件解密,了解如何解密事件;可以在应用管理平台的 事件订阅 页面,查看 Verification Token,以便和从事件中解析出的 Verification Token 对比。
img
如果是未加密事件,需要解析事件,获取 Verification Token 进行校验。明文传输,也有 Verification Token 泄露风险。

签名校验#

校验方式#
这种校验方式相对复杂,但是安全性高,不需要解密和解析事件。校验方式如下:
1.
获取 encrypt_key。
在应用管理平台的 事件订阅 页面,可以查看 encrypt_key。
img
2.
校验请求来源:
将请求头 X-Lark-Request-Timestamp、X-Lark-Request-Nonce 与 encrypt_key 拼接后 按照 encode('utf-8') 编码得到 byte[] b1,再拼接上请求的原始 body, 得到一个 byte[] b。
将 b 用 sha256 加密,得到字符串 s, 校验 s 是否和请求头 X-Lark-Signature 一致。
示例代码#
下面的示例代码,包括如下参数:
timestamp:对应请求头中的 X-Lark-Request-Timestamp。
nonce:对应请求头中的 X-Lark-Request-Nonce。
encrypt_key:从开发者后台获取的 Encrypt Key。有关 Encrypt Key 的详细介绍,可以参考(可选)配置 Encrypt Key。
Python 3#
import hashlib
bytes_b1 = (timestamp + nonce + encrypt_key).encode('utf-8')
bytes_b = bytes_b1 + body
h = hashlib.sha256(bytes_b)
signature = h.hexdigest()

# check if request headers['X-Lark-Signature'] equals to signature
Java#
import org.apache.commons.codec.binary.Hex;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
class Main {
  public String calculateSignature(String timestamp, String nonce, String encryptKey, String bodyString) throws NoSuchAlgorithmException {
      StringBuilder content = new StringBuilder();
      content.append(timestamp).append(nonce).append(encryptKey).append(bodyString);
      MessageDigest alg = MessageDigest.getInstance("SHA-256");
      String sign = Hex.encodeHexString(alg.digest(content.toString().getBytes()));
      return sign;
  }
  
}
Golang#
import (
   "crypto/sha256"
   "fmt"
)
func calculateSignature(timestamp, nonce, encryptKey, bodystring string) string {
   var b strings.Builder
   b.WriteString(timestamp)
   b.WriteString(nonce)
   b.WriteString(encryptKey)
   b.WriteString(bodystring) //bodystring 指整个请求体,不要在反序列化后再计算
   bs := []byte(b.String())
   h := sha256.New()
   h.Write(bs)
   bs = h.Sum(nil)
   sig := fmt.Sprintf("%x", bs)
   return sig
}
Node.js#
var crypto = require('crypto');
function calculateSignature(timestamp, nonce, encryptKey, body) {
        const content = timestamp + nonce + encryptKey + body
        const sign = crypto.createHash('sha256').update(content).digest('hex');
        return sign
}
C##
using System.Security.Cryptography;
public static string calculateSignature(string timestamp, string nonce, string encryptKey, string body) {
        StringBuilder content = new StringBuilder();
        content.Append(timestamp);
        content.Append(nonce);
        content.Append(encryptKey);
        content.Append(body);
        SHA256 sha256 = new SHA256CryptoServiceProvider();  
        byte[] bytes_out = sha256.ComputeHash(Encoding.Default.GetBytes(content.ToString()));  
        string result = BitConverter.ToString(bytes_out);  
        result = result.Replace("-", "");  
        return result;  
}
PHP#
<?php
$encrypt_key = "";  // 开放平台后台的 Encrypt Key
$timestamp = "";
$nonce = "";
$body = ""; // 指整个请求体,不要在反序列化后再计算
$signature = hash("sha256", $timestamp . $nonce . $encrypt_key . $body);
// check if request headers['X-Lark-Signature'] equals to signature 

事件解密#

加密原理#

事件内容采用 AES-256-CBC 加密,加密原理如下:
1.
使用 SHA256 对 Encrypt Key进行哈希得到密钥key。
2.
使用 PKCS7Padding 方式将事件内容进行填充。
3.
生成 16 字节的随机数作为初始向量 iv。
4.
使用 iv 和 key 对事件内容加密得到 encryped_event。
5.
应用收到的密文为 base64(iv+encryped_event)。

示例代码#

当订阅的消息事件发生时,就会触发回调,应用将收到加密的事件内容,请参考下面的示例代码进行事件解密,获取事件内容。
Python 3#
import hashlib
import base64
from Crypto.Cipher import AES
class  AESCipher(object):
    def __init__(self, key):
        self.bs = AES.block_size
        self.key=hashlib.sha256(AESCipher.str_to_bytes(key)).digest()
    @staticmethod
    def str_to_bytes(data):
        u_type = type(b"".decode('utf8'))
        if isinstance(data, u_type):
            return data.encode('utf8')
        return data
    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s) - 1:])]
    def decrypt(self, enc):
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return  self._unpad(cipher.decrypt(enc[AES.block_size:]))
    def decrypt_string(self, enc):
        enc = base64.b64decode(enc)
        return  self.decrypt(enc).decode('utf8')
encrypt = "P37w+VZImNgPEO1RBhJ6RtKl7n6zymIbEG1pReEzghk="
cipher = AESCipher("test key")
print("明文:\n{}".format(cipher.decrypt_string(encrypt)))
Java#
package com.larksuite.oapi.sample;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class Decrypt {
    public static void main(String[] args) throws Exception {
        Decrypt d = new Decrypt("test key");
        System.out.println(d.decrypt("P37w+VZImNgPEO1RBhJ6RtKl7n6zymIbEG1pReEzghk=")); //hello world
    }
    private byte[] keyBs;
    public Decrypt(String key) {
        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            // won't happen
        }
        keyBs = digest.digest(key.getBytes(StandardCharsets.UTF_8));
    }
    public String decrypt(String base64) throws Exception {
        byte[] decode = Base64.getDecoder().decode(base64);
        Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING");
        byte[] iv = new byte[16];
        System.arraycopy(decode, 0, iv, 0, 16);
        byte[] data = new byte[decode.length - 16];
        System.arraycopy(decode, 16, data, 0, data.length);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBs, "AES"), new IvParameterSpec(iv));
        byte[] r = cipher.doFinal(data);
        if (r.length > 0) {
            int p = r.length - 1;
            for (; p >= 0 && r[p] <= 16; p--) {
            }
            if (p != r.length - 1) {
                byte[] rr = new byte[p + 1];
                System.arraycopy(r, 0, rr, 0, p + 1);
                r = rr;
            }
        }
        return new String(r, StandardCharsets.UTF_8);
    }
}
Golang#
package main
import (
        "crypto/aes"
        "crypto/cipher"
        "crypto/sha256"
        "encoding/base64"
        "errors"
        "fmt"
        "strings"
)
func main() {
        s, err := Decrypt("P37w+VZImNgPEO1RBhJ6RtKl7n6zymIbEG1pReEzghk=", "test key")
        if err != nil {
                panic(err)
        }
        fmt.Println(s) //hello world
}
func Decrypt(encrypt string, key string) (string, error) {
        buf, err := base64.StdEncoding.DecodeString(encrypt)
        if err != nil {
                return "", fmt.Errorf("base64StdEncode Error[%v]", err)
        }
        if len(buf) < aes.BlockSize {
                return "", errors.New("cipher  too short")
        }
        keyBs := sha256.Sum256([]byte(key))
        block, err := aes.NewCipher(keyBs[:sha256.Size])
        if err != nil {
                return "", fmt.Errorf("AESNewCipher Error[%v]", err)
        }
        iv := buf[:aes.BlockSize]
        buf = buf[aes.BlockSize:]
        // CBC mode always works in whole blocks.
        if len(buf)%aes.BlockSize != 0 {
                return "", errors.New("ciphertext is not a multiple of the block size")
        }
        mode := cipher.NewCBCDecrypter(block, iv)
        mode.CryptBlocks(buf, buf)
        n := strings.Index(string(buf), "{")
        if n == -1 {
                n = 0
        }
        m := strings.LastIndex(string(buf), "}")
        if m == -1 {
                m = len(buf) - 1
        }
        return string(buf[n : m+1]), nil
}
Node.js#
C##
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace decrypt
{
        class AESCipher
        {
                const int BlockSize = 16;
                private byte[] key;
                public AESCipher(string key)
                {
                        this.key = SHA256Hash(key);
                }
                public string DecryptString(string enc)
                {
                        byte[] encBytes = Convert.FromBase64String(enc);
                        RijndaelManaged rijndaelManaged = new RijndaelManaged();
                        rijndaelManaged.Key = this.key;
                        rijndaelManaged.Mode = CipherMode.CBC;
                        rijndaelManaged.IV = encBytes.Take(BlockSize).ToArray();
                        ICryptoTransform transform = rijndaelManaged.CreateDecryptor();
                        byte[] blockBytes = transform.TransformFinalBlock(encBytes, BlockSize, encBytes.Length - BlockSize);
                        return System.Text.Encoding.UTF8.GetString(blockBytes);
                }
                public static byte[] SHA256Hash(string str)
                {
                        byte[] bytes = Encoding.UTF8.GetBytes(str);
                        SHA256 shaManaged = new SHA256Managed();
                        return shaManaged.ComputeHash(bytes);
                }
                public static void Main(string[] args)
                {
                        string encrypt = "P37w+VZImNgPEO1RBhJ6RtKl7n6zymIbEG1pReEzghk=";
                        AESCipher cipher = new AESCipher("test key");
                        Console.WriteLine(cipher.DecryptString(encrypt));
                }
        }
}
PHP#
<?php
$encrypt_data = ""; // 待解密的信息
$encrypt_key = ""; // 从开发者后台获取 Encrypt Key
$base64_decode_message = base64_decode($encrypt_data);
$iv = substr($base64_decode_message, 0, 16);
$encryped_event = substr($base64_decode_message, 16);
$decrypt = openssl_decrypt($encryped_event, 'AES-256-CBC', hash('sha256', $encrypt_key, true), OPENSSL_RAW_DATA, $iv);
print($decrypt); 
// get the real event

【飞书】API开发者 微信交流群

用微信扫右侧二维码,加入【飞书】API开发者 交流群,互助沟通

扫码加入交流群
上一页
申请权限
下一页
服务端 SDK
Built with