飞书自定义机器人使用指南

飞书自定义机器人使用指南

整理时间: 2026-02-06 15:47
来源: 飞书开放平台官方文档
原文链接: https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot
整理人: AI助手

摘要

自定义机器人是一种只能在当前群聊中使用的机器人,无需租户管理员审核即可通过调用 webhook 地址完成消息推送。本文档详细介绍自定义机器人的添加、配置、安全设置以及支持的消息类型。


1. 注意事项

  • 仅当前群聊可用:自定义机器人只能在当前群聊内使用,无法添加到其他群聊
  • 需要开发基础:需具备服务端开发基础,通过 HTTP POST 请求调用 webhook
  • 无需审核:添加后即可使用,但不具有任何数据访问权限
  • 频率限制:单租户单机器人 100 次/分钟,5 次/秒
  • ⚠️ 建议避开整点及半点时间(如 10:00、17:30),避免 11232 限流错误
  • 请求体大小限制:不能超过 20 KB

2. 功能介绍

适用场景:
- 监控报警推送
- 销售线索通知
- 运营内容推送
- 自动化消息通知

安全设置支持三种维度:
1. 自定义关键词
2. IP 白名单
3. 签名校验


3. 在群组中添加自定义机器人

3.1 操作步骤

  1. 邀请机器人进群
  2. 进入目标群组 → 点击右上角「设置」
  3. 选择「群机器人」→「添加机器人」
  4. 找到并点击「自定义机器人」
  5. 设置头像、名称与描述,点击「添加」

  6. 获取 webhook 地址
    https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx
    ⚠️ 请妥善保存,不要公布在 Gitlab、博客等公开网站

  7. 测试调用

macOS:
bash curl -X POST -H "Content-Type: application/json" \ -d '{"msg_type":"text","content":{"text":"request example"}}' \ https://open.feishu.cn/open-apis/bot/v2/hook/****

Windows (cmd):
bash curl -X POST -H "Content-Type: application/json" -d "{\"msg_type\":\"text\",\"content\":{\"text\":\"request example\"}}" https://open.feishu.cn/open-apis/bot/v2/hook/****

Windows (PowerShell):
bash curl.exe -X POST -H "Content-Type: application/json" -d '{\"msg_type\":\"text\",\"content\":{\"text\":\"requestexample\"}}' https://open.feishu.cn/open-apis/bot/v2/hook/****

成功返回:
json { "code": 0, "data": {}, "msg": "success" }


4. 安全设置

4.1 方式一:自定义关键词

  • 最多设置 10 个关键词,回车间隔
  • 消息需至少包含一个关键词才能发送成功
  • 仅对 texttitle 等文本参数生效

校验失败返回:

{
  "code": 19024,
  "msg": "Key Words Not Found"
}

4.2 方式二:IP 白名单

  • 最多设置 10 个 IP 地址或地址段
  • 支持段输入:123.12.1.*123.1.1.1/24

校验失败返回:

{
  "code": 19022,
  "msg": "Ip Not Allowed"
}

4.3 方式三:签名校验

使用 HmacSHA256 算法计算签名:

签名字符串格式: timestamp + "\n" + 密钥

时间戳要求: 距当前时间不超过 1 小时(3600 秒)

示例代码

Java:

private static String GenSign(String secret, int 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));
}

Python:

import hashlib
import base64
import hmac

def gen_sign(timestamp, secret):
    string_to_sign = '{}\n{}'.format(timestamp, 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

Go:

func GenSign(secret string, timestamp int64) (string, error) {
    stringToSign := fmt.Sprintf("%v", timestamp) + "\n" + secret
    h := hmac.New(sha256.New, []byte(stringToSign))
    _, err := h.Write([]byte{})
    if err != nil {
        return "", err
    }
    signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
    return signature, nil
}

请求体示例:

{
  "timestamp": "1599360473",
  "sign": "xxxxxxxxxxxxxxxxxxxxx",
  "msg_type": "text",
  "content": {
    "text": "request example"
  }
}

校验失败返回:

{
  "code": 19021,
  "msg": "sign match fail or timestamp is not within one hour from current time"
}

5. 支持发送的消息类型

5.1 文本消息 (text)

{
  "msg_type": "text",
  "content": {
    "text": "新更新提醒"
  }
}

@ 用法:

<!-- @ 单个用户 -->
<at user_id="ou_xxx">名字</at>

<!-- @ 所有人 -->
<at user_id="all">所有人</at>

@ 用户示例:

{
  "msg_type": "text",
  "content": {
    "text": "<at user_id=\"ou_xxx\">Tom</at> 新更新提醒"
  }
}

5.2 富文本消息 (post)

{
  "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"
          }]
        ]
      }
    }
  }
}

支持的标签:
| 标签 | 说明 | 必填字段 |
|------|------|----------|
| text | 文本 | text |
| a | 超链接 | text, href |
| at | @用户 | user_id |
| img | 图片 | image_key |

5.3 群名片 (share_chat)

{
  "msg_type": "share_chat",
  "content": {
    "share_chat_id": "oc_f5b1a7eb27ae2****339ff"
  }
}

5.4 图片消息 (image)

{
  "msg_type": "image",
  "content": {
    "image_key": "img_ecffc3b9-8f14-400f-a014-05eca1a4310g"
  }
}

图片需通过「上传图片」接口获取 image_key

5.5 飞书卡片 (interactive)

{
  "msg_type": "interactive",
  "card": {
    "schema": "2.0",
    "config": {
      "update_multi": true
    },
    "body": {
      "direction": "vertical",
      "padding": "12px 12px 12px 12px",
      "elements": [
        {
          "tag": "markdown",
          "content": "西湖,位于中国浙江省杭州市...",
          "text_align": "left"
        },
        {
          "tag": "button",
          "text": {
            "tag": "plain_text",
            "content": "🌞更多景点介绍"
          },
          "behaviors": [{
            "type": "open_url",
            "default_url": "https://baike.baidu.com/..."
          }]
        }
      ]
    },
    "header": {
      "title": {
        "tag": "plain_text",
        "content": "今日旅游推荐"
      },
      "template": "blue"
    }
  }
}

注意事项:
- 仅支持 URL 跳转,不支持回调服务端
- @ 用户仅支持 Open ID 或 User ID,不支持 email、union_id
- 需将 content 替换为 card 结构体并 JSON 转义


6. 常见问题

Q1: 如何实现 @ 指定人、@ 所有人?

  • 文本消息:使用 <at user_id="ou_xxx">名字</at>
  • 富文本消息:使用 "tag": "at", "user_id": "ou_xxx"
  • 卡片消息:使用 <at id=ou_xxx></at>
  • @ 所有人user_idall

Q2: 如何获得 @ 指定人时的 open_id?

自定义机器人本身不能获取 open_id,需通过以下方案:

方案一:通过邮箱/手机号反查
1. 创建自建应用
2. 申请权限:contact:user.id:readonly
3. 调用「通过手机号或邮箱获取用户 ID」接口

方案二:解析用户消息
1. 创建自建应用
2. 申请权限:im:messageim:message.p2p_msg
3. 订阅「接收消息」事件
4. 从消息中解析被 @ 用户的 open_id

Q3: 自定义机器人能响应用户消息吗?

不能。自定义机器人只能推送消息,无法接收和响应用户消息。

Q4: 如何撤回自定义机器人发送的消息?

调用「撤回消息」API,需传入发送消息时返回的 message_id


7. 相关链接


本文档基于飞书开放平台官方文档整理,如有更新请以官方文档为准。