发送webhook到飞书机器人

发送webhook到飞书机器人

发送webhook到飞书机器人

参考链接 自定义机器人使用指南

创建自定义机器人

  1. 邀请自定义机器人进群。
  2. 获取签名校验
    在 安全设置 区域,选择 签名校验。

获取自定义机器人的 webhook 地址
机器人对应的 webhook 地址 格式如下:
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx
请妥善保存好此 webhook 地址,不要公布在 Gitlab、博客等可公开查阅的网站上,避免地址泄露后被恶意调用发送垃圾消息。

在这里插入图片描述

设置自定义机器人的头像、名称与描述,并点击 添加。

在这里插入图片描述

在 群机器人 界面点击 添加机器人。在 添加机器人 对话框,找到并点击 自定义机器人。

在这里插入图片描述

在右侧 设置 界面,点击 群机器人。

在这里插入图片描述

进入目标群组,在群组右上角点击更多按钮,并点击 设置。

在这里插入图片描述

选择签名校验后,系统已默认提供了一个秘钥。你也可以点击 重置,更换秘钥。

在这里插入图片描述

使用java发送http post到自定义机器人

  1. 计算签名校验,参考官方文档的SignDemo.java,自定义一个签名函数
privatestaticStringgenSign(String secret,long timestamp)throwsNoSuchAlgorithmException,InvalidKeyException{//把timestamp+"\n"+密钥当做签名字符串String stringToSign = timestamp +"\n"+ secret;//使用HmacSHA256算法计算签名Mac mac =Mac.getInstance("HmacSHA256"); mac.init(newSecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8),"HmacSHA256"));byte[] signData = mac.doFinal(newbyte[]{});returnnewString(Base64.encodeBase64(signData));}
  1. 计算时间戳
    需要注意的是,时间戳是以秒为单位的,并且要配置时区,不可直接使用System.currentTimeMillis()/1000来计算秒值
long seconds =LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
  1. 创建富文本消息
    参考官方文档 发送富文本消息
    • 创建一个content对象
privatestaticJSONObjectcreateOuterContent(String title,String message,String detail,String startTime,String endTime){JSONObject result =newJSONObject(); result.put("post",createPostJsonObject(title, message, detail, startTime, endTime));return result;}privatestaticJSONObjectcreatePostJsonObject(String title,String message,String detail,String startTime,String endTime){JSONObject result =newJSONObject(); result.put("zh_cn",createZhCNJsonObject(title, message, detail, startTime, endTime));return result;}privatestaticJSONObjectcreateZhCNJsonObject(String title,String message,String detail,String startTime,String endTime){JSONObject result =newJSONObject(); result.put("title", title); result.put("content",createContentList(message, detail, startTime, endTime));return result;}privatestaticJSONArraycreateContentList(String message,String detail,String startTime,String endTime){JSONArray result =newJSONArray();JSONArray item1 =newJSONArray(); item1.add(createInnerHeadContent("message")); item1.add(createInnerTextContent(message)); result.add(item1);JSONArray item2 =newJSONArray(); item2.add(createInnerHeadContent("detail")); item2.add(createInnerTextContent(detail)); result.add(item2);JSONArray item3 =newJSONArray(); item3.add(createInnerHeadContent("startTime")); item3.add(createInnerTextContent(startTime)); result.add(item3);JSONArray item4 =newJSONArray(); item4.add(createInnerHeadContent("endTime")); item4.add(createInnerTextContent(endTime)); result.add(item4);return result;}privatestaticJSONObjectcreateInnerHeadContent(String tag){JSONObject result =newJSONObject(); result.put("tag","text"); result.put("text", tag+": ");return result;}privatestaticJSONObjectcreateInnerTextContent(String text){JSONObject result =newJSONObject(); result.put("tag","text"); result.put("text", text);return result;}
  • 再创建完整的json对象

完整代码如下

java版本

publicclassFeishuWebhook{privatestaticfinalLogger logger =LoggerFactory.getLogger(FeishuWebhook.class);publicstaticfinalStringDEFAULT_DATETIME_FORMATTER_STR="yyyy-MM-dd HH:mm:ss";publicstaticfinalDateTimeFormatterDEFAULT_DATETIME_FORMATTER=DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMATTER_STR);publicstaticvoidsend(String url,String secret,AlertDO alertDO){ logger.info("FeishuWebhook.send, url:{}, alertDO={}", url, alertDO);JSONObject requestBody =createRequestBody(secret, alertDO); logger.info("requestBody:{}", requestBody);JSONObject result =HttpUtils.postForJsonObject(url,null,null, requestBody); logger.info("result:{}", result);}privatestaticStringgenSign(String secret,long timestamp)throwsNoSuchAlgorithmException,InvalidKeyException{//把timestamp+"\n"+密钥当做签名字符串String stringToSign = timestamp +"\n"+ secret;//使用HmacSHA256算法计算签名Mac mac =Mac.getInstance("HmacSHA256"); mac.init(newSecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8),"HmacSHA256"));byte[] signData = mac.doFinal(newbyte[]{});returnnewString(Base64.encodeBase64(signData));}privatestaticJSONObjectcreateRequestBody(String secret,AlertDO alertDO){JSONObject requestBody =newJSONObject();long seconds =LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond(); logger.info("seconds:{}", seconds);// int seconds = 1734515343;try{String sign =genSign(secret, seconds); requestBody.put("timestamp", seconds); requestBody.put("sign", sign); requestBody.put("msg_type","post");String title ="通知";String message = alertDO.getMessage();String detail = alertDO.getDetail();String startTime =DEFAULT_DATETIME_FORMATTER.format(LocalDateTime.ofInstant(alertDO.getStartTime().toInstant(),ZoneId.systemDefault()));String endTime =DEFAULT_DATETIME_FORMATTER.format(LocalDateTime.ofInstant(alertDO.getEndTime().toInstant(),ZoneId.systemDefault())); requestBody.put("content",createOuterContent(title, message, detail, startTime, endTime));}catch(Exception e){ e.printStackTrace();}return requestBody;}privatestaticJSONObjectcreateOuterContent(String title,String message,String detail,String startTime,String endTime){JSONObject result =newJSONObject(); result.put("post",createPostJsonObject(title, message, detail, startTime, endTime));return result;}privatestaticJSONObjectcreatePostJsonObject(String title,String message,String detail,String startTime,String endTime){JSONObject result =newJSONObject(); result.put("zh_cn",createZhCNJsonObject(title, message, detail, startTime, endTime));return result;}privatestaticJSONObjectcreateZhCNJsonObject(String title,String message,String detail,String startTime,String endTime){JSONObject result =newJSONObject(); result.put("title", title); result.put("content",createContentList(message, detail, startTime, endTime));return result;}privatestaticJSONArraycreateContentList(String message,String detail,String startTime,String endTime){JSONArray result =newJSONArray();JSONArray item1 =newJSONArray(); item1.add(createInnerHeadContent("message")); item1.add(createInnerTextContent(message)); result.add(item1);JSONArray item2 =newJSONArray(); item2.add(createInnerHeadContent("detail")); item2.add(createInnerTextContent(detail)); result.add(item2);JSONArray item3 =newJSONArray(); item3.add(createInnerHeadContent("startTime")); item3.add(createInnerTextContent(startTime)); result.add(item3);JSONArray item4 =newJSONArray(); item4.add(createInnerHeadContent("endTime")); item4.add(createInnerTextContent(endTime)); result.add(item4);return result;}privatestaticJSONObjectcreateInnerHeadContent(String tag){JSONObject result =newJSONObject(); result.put("tag","text"); result.put("text", tag+": ");return result;}privatestaticJSONObjectcreateInnerTextContent(String text){JSONObject result =newJSONObject(); result.put("tag","text"); result.put("text", text);return result;}}

python版本
FeishuBotHypertextWithSecret.py

import base64 import hashlib import hmac from datetime import datetime import requests WEBHOOK_URL ="https://open.feishu.cn/open-apis/bot/v2/hook/xx" WEBHOOK_SECRET ="ssssssss"classLarkBot:def__init__(self, secret:str)->None:ifnot secret:raise ValueError("invalid secret key") self.secret = secret defgen_sign(self, timestamp:int)->str: string_to_sign ='{}\n{}'.format(timestamp, self.secret) hmac_code = hmac.new( string_to_sign.encode("utf-8"), digestmod=hashlib.sha256 ).digest() sign = base64.b64encode(hmac_code).decode('utf-8')return sign defsend(self)->None: timestamp =int(datetime.now().timestamp()) sign = self.gen_sign(timestamp) params ={"timestamp": timestamp,"sign": sign,"msg_type":"post","content":{"post":{"zh_cn":{"title":"项目更新通知","content":[[{"tag":"text","text":"项目有更新: "},{"tag":"a","text":"请查看","href":"http://www.example.com/"},{"tag":"at","user_id":"ou_18eac8********17ad4f02e8bbbb"}]]}}}} resp = requests.post(url=WEBHOOK_URL, json=params) resp.raise_for_status() result = resp.json()if result.get("code")and result["code"]!=0:print(result["msg"])returnprint("消息发送成功")defmain(): bot = LarkBot(secret=WEBHOOK_SECRET) bot.send()if __name__ =='__main__': main()

LarkBotWithoutSecret.py

from datetime import datetime import requests WEBHOOK_URL ="https://open.feishu.cn/open-apis/bot/v2/hook/sss"classLarkBot:defsend(self, content:str)->None: timestamp =int(datetime.now().timestamp()) params ={"timestamp": timestamp,"msg_type":"text","content":{"text": content},} resp = requests.post(url=WEBHOOK_URL, json=params) resp.raise_for_status() result = resp.json()if result.get("code")and result["code"]!=0:print(result["msg"])returnprint("消息发送成功")defmain(): bot = LarkBot() bot.send(content="我是一只高级鸽子!")if __name__ =='__main__': main()

Read more

告别手动审核!用Qwen3Guard-Gen-WEB实现自动化内容过滤

告别手动审核!用Qwen3Guard-Gen-WEB实现自动化内容过滤 在内容爆炸的时代,每天有数以亿计的文本、评论、客服对话、营销文案涌入平台。人工审核早已不堪重负:效率低、成本高、标准难统一、响应不及时——更关键的是,它根本跟不上对抗性提示、语义隐喻和跨文化表达带来的新型风险。你是否也经历过这样的场景:一条看似中性的提问,被模型生成出违规结论;一段多语言混杂的用户反馈,因规则引擎漏判而引发舆情危机;又或者,客服系统刚上线三天,就被测试人员用“绕过审查”的话术成功诱导出不当回答? Qwen3Guard-Gen-WEB 不是又一个需要写代码、调接口、配参数的安全插件。它是一套开箱即用的可视化内容安全中枢——部署完成,打开网页,粘贴文字,三秒内返回带解释的风险判断。没有Prompt工程门槛,不依赖开发资源,连非技术的内容运营同事也能独立完成每日千条内容的合规初筛。 这不是理想化的概念演示,而是已在多个内容平台、智能客服中稳定运行的生产级方案。它背后是阿里通义团队基于119万条高质量安全标注数据训练出的生成式审核模型,将“是否安全”这个分类问题,重构为一次自然、可读、可追溯的推理过程

IDEA 创建 Spring Boot Web 项目完整教程

一、新建 Spring Boot 项目 1. 打开新建项目窗口 * 打开 IntelliJ IDEA → 点击 新建项目(或从欢迎页选择 New Project) * 在左侧生成器中选择 Spring Boot *          截图如下 * 选项填写内容说明服务器 URLstart.spring.ioSpring 官方初始化地址名称demo项目名位置D:\idea项目存放路径(建议不要含中文 / 空格)语言Java开发语言类型Maven项目构建工具组org.example项目组织标识工件demo项目模块名软件包名称com.example.demo根包名JDK21 Oracle OpenJDK 21.0.8你的 JDK 版本Java17源码兼容版本(Spring Boot 4.0.3 推荐 Java 17+)打包Jar可执行 Jar 包(Spring

用 Vue 3 重构 Dify 聊天前端(上篇):项目搭建与基础架构

用 Vue 3 重构 Dify 聊天前端(上篇):项目搭建与基础架构

本系列教程将带你从零开始,用 Vue 3 + TypeScript 复刻一个类似 Dify 的 AI 聊天前端。上篇聚焦项目搭建、类型设计、路由认证、HTTP 封装和状态管理。 项目简介 背景 Dify 是一个开源的 LLM 应用开发平台,提供了对话式 AI 的后端服务。在实际项目中,我们往往需要自建前端来对接Dify后端 API或LLM后端服务,实现定制化的聊天界面。 本项目的目标:用 Vue 3 构建一个生产级的 AI 聊天前端,具备以下能力: * SSE 流式输出(打字机效果) * Markdown 渲染 + 代码高亮 * 用户认证 * 文件/图片上传 * 聊天会话历史管理 * 工作流执行可视化 * Agent 思考过程展示 * 移动端响应式适配

动态表单开发新范式:基于JSON Schema的低代码前端效率提升指南

动态表单开发新范式:基于JSON Schema的低代码前端效率提升指南 【免费下载链接】json-editorJSON Schema Based Editor 项目地址: https://gitcode.com/gh_mirrors/js/json-editor 在现代前端开发中,表单构建往往是最耗时且重复的工作之一。你是否曾为一个简单的数据收集页面编写数百行HTML和验证逻辑?是否在需求变更时,不得不同步修改表单UI、数据模型和验证规则?JSON Schema驱动的动态表单技术正彻底改变这一现状。本文将深入探索如何利用JSON Schema实现表单自动化,通过零代码配置大幅提升前端开发效率,让开发者从繁琐的重复劳动中解放出来。 一、表单开发的困境与破局之道 1.1 传统表单开发的痛点剖析 为什么表单开发总是让开发者头疼?传统方式存在三大核心痛点: 首先是代码冗余。一个包含10个字段的简单表单,通常需要编写HTML结构、CSS样式、JavaScript验证逻辑和数据处理代码,形成大量重复劳动。其次是维护成本高。当需求变更时,需要同时修改UI、验证规则和数据模型,容易出现不