发送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

从零开始:Stable Diffusion API本地部署与实战调用指南

1. 环境准备与本地部署 想要玩转Stable Diffusion API,第一步得先把环境搭建好。这就像你要做菜,总得先有个厨房对吧?我推荐直接从GitHub克隆官方stable-diffusion-webui项目,这是最稳妥的选择。不过要注意,你的显卡最好是NVIDIA的,显存至少4GB起步,不然跑起来会非常吃力。 安装过程其实比想象中简单。先确保系统有Python 3.10.6,然后按顺序执行这几个命令: git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git cd stable-diffusion-webui pip install -r requirements.txt 启动时有个关键点要注意:必须加上--api参数!这个参数就像是打开大门的钥匙,不加的话API功能就用不了。启动命令长这样: python launch.py --api 第一次运行会自动下载模型文件,文件比较大可能要等一会儿。我遇到过下载卡住的情况,这时候可以手动把模型文件放到models/Stable-dif

2026中国无人机氢燃料电池行业发展分析:机遇与趋势展望

2026中国无人机氢燃料电池行业发展分析:机遇与趋势展望

一、行业核心概况:产品特性与发展基础 无人机氢燃料电池是专为无人机设计的清洁能源动力装置,通过氢气与氧气的电化学反应生成电能,仅排放水蒸气,真正实现零污染。其系统主要由氢气储存罐、燃料电池堆、电池管理系统构成,相较于传统锂电池,能量密度可达300-1000Wh/kg,是锂电池的3-5倍,能将无人机续航时间从0.5-1小时延长至3-10小时,补能时间从1-2小时缩短至3-15分钟,完美适配长航时、重载飞行需求,成为未来无人机动力的核心发展方向。 2025年全球无人机氢燃料电池产量达28.73万套,平均售价为714.28美元/套,行业平均毛利率为30.78%,主流企业产能集中在5万-30万套/年。从产品分类来看,行业主要分为水冷与风冷两大技术路线:水冷燃料电池系统额定功率更高、结构更复杂,起步较早,多用于大功率无人机场景;风冷系统结构简单、成本较低,适配中小功率无人机,近年来随着技术迭代,逐步成为市场增长主力,2025年国内空冷燃料电池在无人机领域的市场规模达19.8亿元,占氢动力无人机整体市场的27.7%。 按照功率划分,无人机氢燃料电池主要涵盖200W-500W、500W-100

保姆级教程:Windows下安装OpenClaw + 接入飞书机器人,看这一篇就够了!

文章目录 * 前言 * ⚠️ 重要提示:隐私安全优先 * 第一部分:Windows环境准备 * 1.1 系统要求 * 1.2 安装nvm for Windows(推荐) * 1.3 安装Node.js 22.x版本 * 第二部分:安装OpenClaw * 2.1 一键安装脚本(推荐) * 2.2 初始化配置 * 2.3 启动服务并验证 * 第三部分:配置大模型API(核心前提) * 第四部分:飞书机器人配置(核心步骤) * 4.1 安装飞书插件 * 4.2 创建飞书企业自建应用 * 4.3 添加机器人能力 * 4.4

低代码时代PHP开发者如何突围?掌握这3种插件模式稳拿高薪

第一章:低代码时代PHP开发者的职业挑战 在低代码平台迅速普及的当下,传统PHP开发者面临前所未有的职业转型压力。可视化拖拽界面、自动化流程生成和一键部署功能大幅降低了应用开发门槛,使得非技术人员也能快速构建基础业务系统。这一趋势直接冲击了以CRUD操作为核心的中小型PHP项目市场。 技能价值的重新定义 过去依赖LAMP(Linux, Apache, MySQL, PHP)栈快速交付系统的开发者,如今必须面对平台化工具的竞争。低代码引擎如OutSystems、Mendix甚至国内的明道云,能够在几分钟内完成一个表单加审批流的应用搭建,而传统PHP开发则需要数小时乃至数天。 应对策略与能力升级 为保持竞争力,PHP开发者应主动拓展技术边界,重点关注以下方向: * 深入理解底层架构与性能优化机制 * 掌握微服务与API设计,提升系统集成能力 * 学习DevOps流程,增强自动化部署与监控技能 * 转向复杂业务逻辑与安全控制等低代码难以覆盖的领域 代码能力仍是核心优势 尽管低代码平台便捷,但在定制化需求面前仍显僵化。例如,处理复杂的权限树结构时,PHP仍具备不可替代的