首页IT科技飞书的定位(关于飞书事件订阅功能的应用)

飞书的定位(关于飞书事件订阅功能的应用)

时间2025-05-03 02:09:10分类IT科技浏览6154
导读:此项目源码我也是站在巨人的肩膀上进行一个二次应用,感谢这位大神的共享...

此项目源码我也是站在巨人的肩膀上进行一个二次应用             ,感谢这位大神的共享

附上源码链接--Feishu-Event-Subscribe: 【实验】飞书的事件订阅 主要是通讯录发生变动-比如新增             、编辑员工-将会将事件信息发送到指定的API接口             。 (gitee.com)

本人修改后的源码链接--飞书订阅事件

【实验】飞书的事件订阅

主要是通讯录发生变动-比如新增                     、编辑员工-将会将事件信息发送到指定的API接口                     。

参考文档

事件订阅概述

前情提要

开发调试

飞书可以自己在pc客户端上创建一个自己的测试企业                     ,用于开发调试       。

飞书事件回调均使用Json交互       ,爽不爽?

配置

注意点

Encrypt Key是可选的      ,如果配了       、就要对每个收到的请求消息解密使用 飞书的事件订阅请求消息体目前有两个版本                     ,有些同一个功能事件(比如用户更改)就有两种版本 飞书事件推送全都推到同一个用户定义的URL上              ,而且都是POST JSON形式 签名校验需要自己写

配置请求网址和事件订阅

进入开发者后台      ,在开发者后台的应用列表中                    ,点击需要配置应用              ,进入应用详情页      。

在应用详情页中,点击左侧面板中 事件订阅 菜单                     。之后的配置均在该菜单页面下页面!

可选:配置 Encrypt Key                     ,可以不配                     ,配的话就需要对飞书的消息进行解密了(是对每条飞书推送过来的事件都要进行解密),解密后得到的才是正确的json格式              。解密代码样例(这个是飞书官方提供的):

import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; public class NotifyDataDecrypter { private byte[] key; /** * @param encryptKey 飞书应用配置的 Encrypt Key */ public NotifyDataDecrypter(String encryptKey) { MessageDigest digest = null; try { digest = MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { // wont happen } key = digest.digest(encryptKey.getBytes(StandardCharsets.UTF_8)); } /** * 解密 * @param encrypt 请求json encrypt的对应的值 */ public String decrypt(String encrypt) throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException { byte[] decode = Base64.getDecoder().decode(encrypt); 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(key, "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); } }

设置Encrypt Key收到的请求消息体Json统一的格式都是             ,需要解密后才能使用:

// 收到的请求 { "encrypt": "ds3da3sj32421lkkld4s5ao" // 加密字符串 }

配置 请求网址URL                     ,就是说       ,后续飞书会将事件推送至改URL上             ,URL要求如下:

当应用订阅的事件触发时                     ,开放平台会向该网址发送相应的 HTTP POST 请求      。 每个应用只能配置一个请求网址       ,该应用订阅的所有事件通知都会发送到该请求网址                    。

当在应用后台配置该 请求网址URL 的时候      ,飞书回向该URL发送一个POST请求进行URL校验                     ,只有这个URL做出正确响应才能保存成功              。URL校验会根据你是否配置了Encrypt Key发送不同的消息体Json。

未设置Encrypt Key发送的就是明文的Json:

// 收到的请求 { "challenge": "ajls384kdjx98XX", // 应用需要原样返回的值 "token": "xxxxxx", // Token的使用可参考文档“通过Token验证事件来源             ” "type": "url_verification" // 表示这是一个验证请求 }

设置Encrypt Key发送的就是加密的              ,解密之后的格式就是上面未设置Encrypt Key的明文Json格式:

// 实际收到的请求 { "encrypt": "ds3da3sj32421lkkld4s5ao" // 加密字符串 } // 解密后 { "challenge": "ajls384kdjx98XX", // 应用需要原样返回的值 "token": "xxxxxx", // Token的使用可参考文档“通过Token验证事件来源                     ” "type": "url_verification" // 表示这是一个验证请求 }

不管加密还是没加密      ,URL校验都要求用户服务器在1s内向飞书返回如下格式:

//响应内容如下 { "challenge": "ajls384kdjx98XX" // 应用需要原样返回的值 }

请求网址配置成功后                    ,在下方你能看到可以订阅的事件列表              ,通过是否订阅的开关来 订阅 / 取消订阅事件                    。你想要什么类型的事件就在这里加什么事件,增加      、取消后要进入 版本管理与发布重新进行应用的发布                    ,让你订阅 / 取消的事件生效                     。

接受并响应事件

飞书通过HTTP POST发送Json格式时间数据到用户服务器中。用户服务器需要在1s内以HTTP 200状态码相应该请求(不需要返回什么Json数据什么的)                     ,否则视为此次事件推送失败,并以5s                     、5m              、1h      、6h的间隔重新推送事件             ,最多重试4次             。

为了避免同一个事件处理了多次                     ,你需要使用event_id(2.0版本事件)或者uuid(1.0版本事件)对事件的唯一性进行检查                     。 如果你填写了Encrypt Key       ,在进行业务逻辑处理前请先参考这里进行解密       。 你可以检查 token (设置了Encrypt Key需要先解密             ,才能获取token)是否与开发者后台的 Verification Token 相同以确保这个事件的来源是飞书开放平台                     ,而不是恶意的第三方伪造的事件             。

响应事件的版本

目前响应事件的数据格式有2个版本       ,现在新接入的事件都是采用2.0版本的格式                     。1.0版本就是返回一个用户Id给你然后你还要拿着用户Id在请求一次飞书接口;2.0版本就是直接把改动实体数据一次性全给你了      ,无需二次调用飞书接口       。

事件返回包含schema字段                     ,则是2.0版本;

如果接入了两个版本              ,会收到两种不同版本的事件!!!!!

// 2.0 版本示例 { "schema": "2.0", // 事件格式的版本      。无此字段的即为1.0 "header": { "event_id": "f7984f25108f8137722bb63cee927e66", // 事件的唯一标识 "token": "066zT6pS4QCbgj5Do145GfDbbagCHGgF", // 即Verification Token "create_time": "1603977298000000", // 事件发送的时间 "event_type": "contact.user_group.created_v3", // 事件类型 "tenant_key": "xxxxxxx", // 企业标识 "app_id": "cli_xxxxxxxx", // 应用ID }, "event":{ ... // 不同事件此处数据不同 } } // 1.0 版本示例 { "ts": "1502199207.7171419", // 事件发送的时间      ,一般近似于事件发生的时间                     。 "uuid": "bc447199585340d1f3728d26b1c0297a", // 事件的唯一标识 "token": "41a9425ea7df4536a7623e38fa321bae", // 即Verification Token "type": "event_callback", // event_callback-事件推送                    ,url_verification-url地址验证 "event":{ ... // 不同事件此处数据不同 } }

事件顺序性

飞书见按照事件发生的顺序推送              ,对于相关数据的不同事件,将由开放平台保证推送顺序                    ,只有前一个接收响应成功才会推送下一个消息              。

有序事件的策略 问:假如上一个事件相应飞书失败                     ,且飞书重试4次(最多4次)之后均失败,后面的事件难道就卡住不动了? 不会             ,重复推送直至失效就会推送下一个了      。 开放平台将基于开放业务选择对应的顺序规则 如果有序事件消费失败                     ,将对此事件重复推送直至失效后才会推送下一事件

安全校验

事件安全校验是「可选」的       ,可以针对收到的http请求进行检验             ,以确认其合法性                    。

获取 encrypt_key: 访问我的后台 -> 开发者后台 -> 点击应用 -> 事件订阅                     , 在事件订阅页面中查看 encrypt_key              。 校验请求来源: 将请求头 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 一致                    。

参考代码

import org.apache.commons.codec.binary.Hex; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class FeishuSignatureUtils { /** * https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-security-verification * * @param timestamp Http请求头中的X-Lark-Request-Timestamp * @param nonce Http请求头中的X-Lark-Request-Nonce * @param encryptKey 飞书应用后台自己配置的encrypt key * @param bodyString 事件请求json串 */ public static 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"); return Hex.encodeHexString(alg.digest(content.toString().getBytes())); } }
声明:本站所有文章              ,如无特殊说明或标注      ,均为本站原创发布                     。任何个人或组织                    ,在未征得本站同意时              ,禁止复制              、盗用、采集                    、发布本站内容到任何网站                     、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理             。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
win7里面的放大镜可以关闭吗(Win7系统中,放大镜的使用方法) 企业网站优化的操作方法详解(从研究到页面优化,打造企业网站)