跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

飞书自定义机器人 Webhook 接入与发送示例

飞书自定义机器人支持通过 Webhook 地址接收消息。配置流程包括邀请机器人进群、设置安全校验密钥及获取 Hook 地址。发送消息需计算时间戳与签名(HmacSHA256),构造包含 msg_type 和 content 的 JSON 请求体。文中提供了 Java 与 Python 两种语言的 HTTP POST 实现代码,涵盖富文本消息构建与签名生成逻辑,可直接用于集成告警通知或系统推送。

信号故障发布于 2026/4/7更新于 2026/7/2341 浏览
飞书自定义机器人 Webhook 接入与发送示例

飞书自定义机器人 Webhook 接入指南

创建自定义机器人

  1. 邀请自定义机器人进群。
  2. 获取签名校验:在安全设置区域,选择签名校验。
  3. 获取自定义机器人的 webhook 地址。格式如下: https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx 请妥善保存此 webhook 地址,避免地址泄露后被恶意调用发送垃圾消息。
  4. 设置自定义机器人的头像、名称与描述,并点击添加。
  5. 在群机器人界面点击添加机器人,找到并点击自定义机器人。
  6. 在右侧设置界面,点击群机器人。
  7. 进入目标群组,在群组右上角点击更多按钮,并点击设置。
  8. 选择签名校验后,系统已默认提供了一个秘钥。你也可以点击重置,更换秘钥。

使用 Java 发送 HTTP POST 到自定义机器人

1. 计算签名校验

参考官方文档,自定义一个签名函数。

private static String genSign(String secret, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
    // 把 timestamp + "\n" + 密钥当做签名字符串
    String stringToSign = timestamp + "\n" + secret;
    // 使用 HmacSHA256 算法计算签名
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
    byte[] signData = mac.doFinal(new byte[]{});
    return new String(Base64.encodeBase64(signData));
}

2. 计算时间戳

需要注意的是,时间戳是以秒为单位的,并且要配置时区,不可直接使用 System.currentTimeMillis()/1000 来计算秒值。

long seconds = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();

3. 创建富文本消息

参考官方文档发送富文本消息。

  • 创建一个 content 对象。
private static JSONObject createOuterContent(String title, String message, String detail, String startTime, String endTime) {
    JSONObject result = new JSONObject();
    result.put("post", createPostJsonObject(title, message, detail, startTime, endTime));
    return result;
}

private static JSONObject createPostJsonObject(String title, String message, String detail, String startTime, String endTime) {
    JSONObject result = new JSONObject();
    result.put("zh_cn", createZhCNJsonObject(title, message, detail, startTime, endTime));
    return result;
}

private static JSONObject createZhCNJsonObject(String title, String message, String detail, String startTime, String endTime) {
    JSONObject result = new JSONObject();
    result.put("title", title);
    result.put("content", createContentList(message, detail, startTime, endTime));
    return result;
}

private static JSONArray createContentList(String message, String detail, String startTime, String endTime) {
    JSONArray result = new JSONArray();
    JSONArray item1 = new JSONArray();
    item1.add(createInnerHeadContent("message"));
    item1.add(createInnerTextContent(message));
    result.add(item1);
    JSONArray item2 = new JSONArray();
    item2.add(createInnerHeadContent("detail"));
    item2.add(createInnerTextContent(detail));
    result.add(item2);
    JSONArray item3 = new JSONArray();
    item3.add(createInnerHeadContent("startTime"));
    item3.add(createInnerTextContent(startTime));
    result.add(item3);
    JSONArray item4 = new JSONArray();
    item4.add(createInnerHeadContent("endTime"));
    item4.add(createInnerTextContent(endTime));
    result.add(item4);
    return result;
}

private static JSONObject createInnerHeadContent(String tag) {
    JSONObject result = new JSONObject();
    result.put("tag", "text");
    result.put("text", tag + ": ");
    return result;
}

private static JSONObject createInnerTextContent(String text) {
    JSONObject result = new JSONObject();
    result.put("tag", "text");
    result.put("text", text);
    return result;
}

完整代码 (Java)

public class FeishuWebhook {
    private static final Logger logger = LoggerFactory.getLogger(FeishuWebhook.class);
    public static final String DEFAULT_DATETIME_FORMATTER_STR = "yyyy-MM-dd HH:mm:ss";
    public static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMATTER_STR);

    public static void send(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);
    }

    private static String genSign(String secret, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(new byte[]{});
        return new String(Base64.encodeBase64(signData));
    }

    private static JSONObject createRequestBody(String secret, AlertDO alertDO) {
        JSONObject requestBody = new JSONObject();
        long seconds = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
        logger.info("seconds:{}", seconds);
        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;
    }

    private static JSONObject createOuterContent(String title, String message, String detail, String startTime, String endTime) {
        JSONObject result = new JSONObject();
        result.put("post", createPostJsonObject(title, message, detail, startTime, endTime));
        return result;
    }

    private static JSONObject createPostJsonObject(String title, String message, String detail, String startTime, String endTime) {
        JSONObject result = new JSONObject();
        result.put("zh_cn", createZhCNJsonObject(title, message, detail, startTime, endTime));
        return result;
    }

    private static JSONObject createZhCNJsonObject(String title, String message, String detail, String startTime, String endTime) {
        JSONObject result = new JSONObject();
        result.put("title", title);
        result.put("content", createContentList(message, detail, startTime, endTime));
        return result;
    }

    private static JSONArray createContentList(String message, String detail, String startTime, String endTime) {
        JSONArray result = new JSONArray();
        JSONArray item1 = new JSONArray();
        item1.add(createInnerHeadContent("message"));
        item1.add(createInnerTextContent(message));
        result.add(item1);
        JSONArray item2 = new JSONArray();
        item2.add(createInnerHeadContent("detail"));
        item2.add(createInnerTextContent(detail));
        result.add(item2);
        JSONArray item3 = new JSONArray();
        item3.add(createInnerHeadContent("startTime"));
        item3.add(createInnerTextContent(startTime));
        result.add(item3);
        JSONArray item4 = new JSONArray();
        item4.add(createInnerHeadContent("endTime"));
        item4.add(createInnerTextContent(endTime));
        result.add(item4);
        return result;
    }

    private static JSONObject createInnerHeadContent(String tag) {
        JSONObject result = new JSONObject();
        result.put("tag", "text");
        result.put("text", tag + ": ");
        return result;
    }

    private static JSONObject createInnerTextContent(String text) {
        JSONObject result = new JSONObject();
        result.put("tag", "text");
        result.put("text", text);
        return result;
    }
}

Python 版本实现

带签名验证

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"

class LarkBot:
    def __init__(self, secret: str) -> None:
        if not secret:
            raise ValueError("invalid secret key")
        self.secret = secret

    def gen_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

    def send(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"])
            return
        print("消息发送成功")

def main():
    bot = LarkBot(secret=WEBHOOK_SECRET)
    bot.send()

if __name__ == '__main__':
    main()

无签名验证

from datetime import datetime
import requests

WEBHOOK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/sss"

class LarkBot:
    def send(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"])
            return
        print("消息发送成功")

def main():
    bot = LarkBot()
    bot.send(content="我是一只高级鸽子!")

if __name__ == '__main__':
    main()

目录

  1. 飞书自定义机器人 Webhook 接入指南
  2. 创建自定义机器人
  3. 使用 Java 发送 HTTP POST 到自定义机器人
  4. 1. 计算签名校验
  5. 2. 计算时间戳
  6. 3. 创建富文本消息
  7. 完整代码 (Java)
  8. Python 版本实现
  9. 带签名验证
  10. 无签名验证
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • PyInstaller 将 Python 脚本打包为 exe 文件实战指南
  • Resilience4j 熔断降级深度解析:状态机、Fallback 与限流算法
  • Python 在 CentOS 系统上的安装、配置与部署实战
  • 零成本部署:国内畅玩 n8n 与私有 AI 模型指南
  • 苍穹外卖里的定时任务与实时消息推送实践
  • 基于 NVIDIA Jetson 的 HuggingFace LeRobot 端到端机器人学习实践
  • 基于 MuJoCo Gym 的机器人仿真、训练与部署流程
  • OpenClaw 飞书机器人配置指南
  • SPI 通信读取 255 故障排查:C++ spidev0.0 原理分析
  • 人工智能大语言模型在出版业的应用现状与趋势分析
  • 01 背包问题详解与空间优化实战
  • npm 安装 OpenClaw 遇到 Git 报错的解决方案
  • Java 泛型擦除机制:原理与限制分析
  • Stable Diffusion WebUI 云端环境搭建与参数调优实战
  • OpenClaw 技术解析:让大模型从对话走向执行
  • AI 绘画内容安全与提示词实战指南
  • 17 岁高中生开发 AI 应用,4 个月销售额达 100 万美元
  • VTJ.PRO Agent + Skills 架构重构 Vue 开发工作流解析
  • Web 安全实战:Robots.txt 协议原理、利用与防御
  • 双指针算法原理与经典题目解析

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online