n8n飞书webhook配置(飞书机器人、飞书bot、feishu bot)Crypto节点、js timestamp代码、Crypto node

自定义机器人使用指南

利用 n8n 打造飞书 RSS 推送机器人

文章目录

  • 自定义机器人使用指南
    • 注意事项
    • 功能介绍
    • 在群组中添加自定义机器人
      • 操作步骤
        • 邀请自定义机器人进群。
          • - 进入目标群组,在群组右上角点击更多按钮,并点击 设置。
          • - 在右侧 设置 界面,点击 群机器人。
          • - 在 群机器人 界面点击 添加机器人。
          • - 在 添加机器人 对话框,找到并点击 自定义机器人。
          • - 设置自定义机器人的头像、名称与描述,并点击 添加。
        • 获取自定义机器人的 webhook 地址,并点击 完成。
        • 测试调用自定义机器人的 webhook 地址,向所在群组发送消息。
          • - 用任意方式向 webhook 地址发起一个 HTTP POST 请求。
          • - 命令执行后,进入自定义机器人所在群组查看测试消息。
      • 后续步骤
    • 为自定义机器人添加安全设置
      • 方式一:设置自定义关键词
        • - 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。
        • - 在 安全设置 区域,选择 自定义关键词。
        • - 在输入框添加关键词。
        • - 点击 保存,使生效配置。
      • 方式二:设置 IP 白名单
        • - 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。
        • - 在 安全设置 区域,选择 IP 白名单。
        • - 在输入框添加 IP 地址。
        • - 点击 保存,使配置生效。
      • 方式三:设置签名校验
        • - 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。
        • - 在 安全设置 区域,选择 签名校验。
        • - 点击 复制,复制秘钥。
        • - 点击 保存,使配置生效。
        • - 计算签名字符串。
          • Java 示例代码
          • Go 示例代码
          • Python 示例代码
        • - 获取签名字符串。
      • 注意:在n8n中用crypto模块获取签名字符串(配置方法❤❤❤)
        • HMAC 的正确用法是:
        • 但是飞书提供的代码是:
        • 第一个参数key变成了timestamp和secret的拼接(用换行符),第二个参数msg为空。
        • 所以我们节点配置如下:
        • 完整工作流json代码如下:
    • 删除自定义机器人
    • 支持发送的消息类型说明
      • 发送文本消息
      • 发送富文本消息
      • 发送群名片
      • 发送图片
      • 发送飞书卡片
    • 常见问题
      • 如何实现 @ 指定人、@ 所有人?
      • 如何获得 @ 指定人时所需要的 open_id?
      • 自定义机器人能响应用户消息吗?
      • 如何撤回自定义机器人发送的消息?

自定义机器人使用指南

自定义机器人是一种只能在当前群聊中使用的机器人。该类机器人无需经过租户管理员审核,即可在当前群聊中通过调用 webhook 地址的方式完成消息推送。本文主要介绍自定义机器人的使用方式。

注意事项

  • 自定义机器人只能在当前群聊内使用,同一个自定义机器人无法添加到其他群聊。

  • 你需要具备一定的服务端开发基础,通过请求调用自定义机器人的 webhook 地址,实现消息推送功能。

  • 自定义机器人在添加至群组后即可使用,无需租户管理员审核。该特性提升了开发机器人的便携性,但出于租户数据安全考虑,也限制了自定义机器人的使用场景,自定义机器人不具有任何数据访问权限。

  • 如果你希望实现机器人群管理、获取用户信息等能力,建议参考开发卡片交互机器人,通过机器人应用实现。自定义机器人和机器人应用的能力对比,请参见能力对比。

  • 自定义机器人的频率控制和普通应用不同,为单租户单机器人 100 次/分钟,5 次/秒。建议发送消息尽量避开诸如 10:00、17:30 等整点及半点时间,否则可能出现因系统压力导致的 11232 限流错误,导致消息发送失败。

  • 发送消息时,请求体的数据大小不能超过 20 KB。

功能介绍

企业存在给特定群组自动推送消息的场景,例如,推送监控报警、销售线索、运营内容等。在该类场景下,你可以在群组中添加自定义机器人,自定义机器人默认提供 webhook,通过服务端调用 webhook 地址,即可将外部系统的消息通知即时推送到群组中。自定义机器人也包含了 自定义关键词、IP 白名单 和 签名 三种维度的安全配置,便于控制 webhook 的调用范围。

自定义机器人消息推送示例,如下图所示:
在这里插入图片描述

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

操作步骤

邀请自定义机器人进群。
- 进入目标群组,在群组右上角点击更多按钮,并点击 设置。

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

获取自定义机器人的 webhook 地址,并点击 完成。

机器人对应的 webhook 地址 格式如下:

https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx

请妥善保存好此 webhook 地址,不要公布在 Gitlab、博客等可公开查阅的网站上,避免地址泄露后被恶意调用发送垃圾消息。

在这里插入图片描述

后续你可以在群组名称右侧点击机器人图片,进入自定义机器人详情页,管理自定义机器人的配置信息。
在这里插入图片描述

测试调用自定义机器人的 webhook 地址,向所在群组发送消息。
- 用任意方式向 webhook 地址发起一个 HTTP POST 请求。

你需要具备一定的服务端开发基础,通过服务端 HTTP POST 请求方式调用 webhook 地址。以 curl 指令为例,请求示例如下。你可以通过 macOS 系统的终端,或者 Windows 系统的控制台应用,执行以下命令进行测试。

macOS

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)

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)

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/****

示例命令说明:

  • 请求方式:POST

  • 请求头:Content-Type: application/json

  • 请求体:{"msg_type":"text","content":{"text":"request example"}}

  • webhook 地址:https://open.feishu.cn/open-apis/bot/v2/hook/**** 为示例值,你在实际调用时需要替换为自定义机器人真实的 webhook 地址。

向自定义机器人发送请求时,支持发送文本、富文本、群名片以及消息卡片等多种消息类型。各类消息类型的请求说明,参见支持发送的消息类型说明。

执行命令后:

  • 如果请求成功,命令行将会回显以下信息。

    {"StatusCode": 0,               //冗余字段,用于兼容存量历史逻辑,不建议使用"StatusMessage": "success",    //冗余字段,用于兼容存量历史逻辑,不建议使用"code": 0,"data": {},"msg": "success"
    }
    
  • 如果请求体格式错误,则会返回以下信息。

    {"code": 9499,"msg": "Bad Request","data": {}
    }
    

    你可以通过以下说明,检查请求体是否存在问题。

    • 请求体内容格式是否与各消息类型的示例代码一致。

    • 请求体大小不能超过 20 K。

- 命令执行后,进入自定义机器人所在群组查看测试消息。

在这里插入图片描述

后续步骤

成功添加自定义机器人后,推荐你为自定义机器人添加安全设置,以保证机器人接收请求的安全性。具体操作参见下文为自定义机器人添加安全设置。

为自定义机器人添加安全设置

在群组中添加自定义机器人后,你可以为机器人添加安全设置。安全设置用于保护自定义机器人不被恶意调用,例如,当 webhook 地址因保管不当而泄露后,可能会被恶意开发者调用发送垃圾信息。通过添加安全设置,只有在符合安全设置条件的情况下,才可以成功调用机器人。

目前提供的安全设置方式如下:

  • 我们强烈建议为自定义机器人添加安全设置,以提高安全性。
  • 在同一个自定义机器人中,你可以设置一个或多个方法。
  • 自定义关键词:只有包含至少一个关键词的消息,可以成功发送。

  • IP 白名单:只有在白名单内的 IP 地址,可以成功请求 webhook 发送消息。

  • 签名校验:设置签名。发送的请求必须通过签名校验,才可以成功请求 webhook 发送消息。

方式一:设置自定义关键词

- 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。

你也可以在群组设置中打开机器人列表。

在这里插入图片描述

- 在 安全设置 区域,选择 自定义关键词。

在这里插入图片描述

- 在输入框添加关键词。

最多可以同时设置 10 个关键词,多个关键词之间使用回车键间隔。设置后,只有包含至少一个关键词的消息才会被成功发送。

例如,关键词设置了 应用报警 与 项目更新,则请求 webhook 发送的消息内容需要至少包含 应用报警 或 项目更新 其中一个关键词。

设置关键词后,如果发送请求时自定义关键词校验失败,则会返回以下信息。

// 关键词校验失败
{"code": 19024,"msg": "Key Words Not Found"
}
- 点击 保存,使生效配置。

注意:自定义关键词只对 text、title 这类文本参数值生效。例如,发送富文本消息时包含超链接标签 {"tag":"a","text":"请查看","href":"http://www.example.com/"},则自定义关键词只过滤 text 参数值,不会过滤 href 参数值。

(看不懂啥意思!)

方式二:设置 IP 白名单

- 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。

你也可以在群组设置中打开机器人列表。

在这里插入图片描述

- 在 安全设置 区域,选择 IP 白名单。

在这里插入图片描述

- 在输入框添加 IP 地址。

支持添加 IP 地址或地址段,最多可设置 10 个,使用回车键间隔。支持段输入,例如 123.12.1.*123.1.1.1/24。设置后,机器人 webhook 地址只处理来自 IP 白名单范围内的请求。

设置 IP 白名单后,白名单之外的 IP 地址请求 webhook 时会校验失败,并返回以下信息。

// IP校验失败
{"code": 19022,"msg": "Ip Not Allowed"
}
- 点击 保存,使配置生效。

方式三:设置签名校验

- 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。

你也可以在群组设置中打开机器人列表。

在这里插入图片描述

- 在 安全设置 区域,选择 签名校验。

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

在这里插入图片描述

- 点击 复制,复制秘钥。
- 点击 保存,使配置生效。
- 计算签名字符串。

设置签名校验后,向 webhook 发送请求需要签名校验来保障来源可信。所校验的签名需要通过时间戳与秘钥进行算法加密,即将timestamp + "\n" + 密钥当做签名字符串,使用 HmacSHA256 算法计算空字符串的签名结果,再进行 Base64 编码。其中,timestamp是指距当前时间不超过 1 小时(3600 秒)的时间戳,时间单位:s。例如,1599360473。

本文提供了以下不同语言的代码示例,用于计算获得签名字符串。

Java 示例代码
package sign;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Base64;
public class SignDemo {public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {String secret = "demo";int timestamp = 1599360473;System.out.printf("sign: %s", GenSign(secret, timestamp));
}private static String GenSign(String secret, int 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));}
}
Go 示例代码
func GenSign(secret string, timestamp int64) (string, error) {//timestamp + key 做sha256, 再进行base64 encodestringToSign := fmt.Sprintf("%v", timestamp) + "\n" + secretvar data []byteh := hmac.New(sha256.New, []byte(stringToSign))_, err := h.Write(data)if err != nil {return "", err}signature := base64.StdEncoding.EncodeToString(h.Sum(nil))return signature, nil
}
Python 示例代码
import hashlib
import base64
import hmac
def gen_sign(timestamp, secret):# 拼接timestamp和secretstring_to_sign = '{}\n{}'.format(timestamp, secret)hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest()# 对结果进行base64处理sign = base64.b64encode(hmac_code).decode('utf-8')return sign
- 获取签名字符串。

以 Java 示例代码为例,获取当前时间戳以及密钥后,运行程序获得签名字符串。

在这里插入图片描述

获取签名字符串后,在向 webhook 发送请求时,需要加上时间戳(timestamp)和签名字符串(sign)字段信息。示例配置如下所示。

// 开启签名验证后发送文本消息
{"timestamp": "1599360473",        // 时间戳。"sign": "xxxxxxxxxxxxxxxxxxxxx",  // 得到的签名字符串。"msg_type": "text","content": {"text": "request example"}
}

如果发送请求时校验失败,你可以通过以下说明排查问题。

所使用的时间戳距离发送请求的时间已间隔 1 小时以上,签名已过期。

服务器时间与标准时间有较大偏差,导致签名过期。请注意检查、校准你的服务器时间。

签名不匹配导致的校验不通过,将返回以下信息。

// 签名校验失败
{"code": 19021,"msg": "sign match fail or timestamp is not within one hour from current time"
}

注意:在n8n中用crypto模块获取签名字符串(配置方法❤❤❤)

HMAC 的正确用法是:
hmac.new(key=secret, msg=data, digestmod=hashlib.sha256)
但是飞书提供的代码是:
string_to_sign = '{}\n{}'.format(timestamp, secret)
hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest()
第一个参数key变成了timestamp和secret的拼接(用换行符),第二个参数msg为空。
所以我们节点配置如下:

在这里插入图片描述
在这里插入图片描述

{"timestamp": "{{Math.round(new Date().getTime()/1000)}}",
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

{{ $json.timestamp + '\n' + 'XRkoNa93xgcXy5ZwB77PLh'}}

在这里插入图片描述
在这里插入图片描述

完整工作流json代码如下:
{"nodes": [{"parameters": {"method": "POST","url": "https://open.feishu.cn/open-apis/bot/v2/hook/************************","sendBody": true,"specifyBody": "json","jsonBody": "={\n    \"timestamp\": \"{{ $json.timestamp}}\",\n    \"sign\": \"{{ $json.sign}}\",\n    \"msg_type\": \"text\",\n    \"content\": {\n        \"text\": \"request example\"\n    }\n}","options": {}},"type": "n8n-nodes-base.httpRequest","typeVersion": 4.2,"position": [496,0],"id": "0cf5fa50-e7ef-405d-b1c9-5edc1dc49889","name": "HTTP Request"},{"parameters": {},"type": "n8n-nodes-base.manualTrigger","typeVersion": 1,"position": [-176,0],"id": "2fc6c5ad-97ae-41ab-b932-6fdfb8481b8e","name": "When clicking ‘Execute workflow’"},{"parameters": {"action": "hmac","type": "SHA256","value": "=","dataPropertyName": "sign","secret": "={{ $json.timestamp + '\\n' + 'XRkoNa93xgcX**************'}}","encoding": "base64"},"type": "n8n-nodes-base.crypto","typeVersion": 1,"position": [272,0],"id": "5d2be349-404f-4b4d-9acf-b6674c293774","name": "Crypto"},{"parameters": {"mode": "raw","jsonOutput": "={\n  \"timestamp\": \"{{Math.round(new Date().getTime()/1000)}}\",\n}\n","options": {}},"type": "n8n-nodes-base.set","typeVersion": 3.4,"position": [48,0],"id": "5206a964-60f9-4fa2-9e84-874b6086f467","name": "Edit Fields"}],"connections": {"When clicking ‘Execute workflow’": {"main": [[{"node": "Edit Fields","type": "main","index": 0}]]},"Crypto": {"main": [[{"node": "HTTP Request","type": "main","index": 0}]]},"Edit Fields": {"main": [[{"node": "Crypto","type": "main","index": 0}]]}},"pinData": {},"meta": {"instanceId": "7dad39b1efdec274b0305a8cf49ffedcd26ca40b0ec7aafcaf3eb4e9d058f099"}
}

删除自定义机器人

在飞书群组的 设置 中,打开 群机器人 列表,找到需要删除的自定义机器人,在卡片右侧点击删除图标。
在这里插入图片描述

支持发送的消息类型说明

向自定义机器人 webhook 地址发送 POST 请求时,支持推送的消息格式有 文本、富文本、图片消息 以及 群名片 等,本章节介绍各消息类型的请求格式与展示效果。

发送文本消息

请求消息体示例

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

实现效果
在这里插入图片描述

参数说明

  • 参数 msg_type 值为对应消息类型的映射关系,文本消息的 msg_type 对应值为 text。

  • 参数 content 包含消息内容,文本消息的消息内容参数说明如下表所示。

    字段类型是否必填示例值描述
    textstringTest content文本内容。

文本消息的 @ 用法

// @ 单个用户
<at user_id="ou_xxx">名字</at>
// @ 所有人
<at user_id="all">所有人</at>
  • @ 单个用户时,user_id字段需填入用户的 Open ID 或 User ID,且必须是有效值(仅支持 @ 自定义机器人所在群的群成员),否则取名字展示,并不产生实际的 @ 效果。

在外部群聊中,仅支持使用 Open ID @ 单个用户,不支持 User ID。

  • @ 所有人时,必须满足所在群开启 @ 所有人功能。

文本消息 @ 用法示例

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

发送富文本消息

富文本消息是指包含文本、超链接、图标等多种文本样式的复合文本信息。

请求消息体示例

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

实现效果
在这里插入图片描述

参数说明
参数 msg_type 值为对应消息类型的映射关系,富文本消息的 msg_type 对应值为 post。

参数 content 包含消息内容,文本消息的消息内容参数说明如下表所示。

字段类型是否必填示例值描述
postobjectnone富文本消息。
∟ zh_cnobjectnonezh_cn、en_us 分别是富文本的中、英文配置,富文本消息中至少需要包含一种语言的配置。包含的参数说明,参见下文的《zh_cn、en_us 字段说明表》。
∟ en_usobjectnonezh_cn、en_us 分别是富文本的中、英文配置,富文本消息中至少需要包含一种语言的配置。包含的参数说明,参见下文的《zh_cn、en_us 字段说明表》。

zh_cn、en_us 字段说明表。

字段类型是否必填示例值描述
titlestringTest title富文本消息的标题。
content[]paragraph[[{“tag”: “text”,“text”: “text content”}]]富文本消息内容。由多个段落组成,每个段落为一个[]节点,其中包含若干个节点。

富文本支持的标签和参数说明
文本标签:text

字段类型是否必填示例值描述
textstringText content文本内容。
un_escapebooleanfalse表示是否 unescape 解码。默认值为 false,未用到 unescape 时可以不填。

超链接标签:a

字段类型是否必填示例值描述
textstring测试地址超链接的文本内容。
hrefstringhttps://open.feishu.cn默认的链接地址,你需要确保链接地址的合法性,否则消息会发送失败。

@ 标签:at

字段类型是否必填示例值描述
user_idstringou_18eac85d35a26****02e8bbbb用户的 Open ID 或 User ID。
- @ 单个用户时,user_id字段必须是有效值(仅支持 @ 自定义机器人所在群的群成员)。
- @ 所有人时,填 all。
user_namestringJian Li用户名称。

图片标签:img

字段类型是否必填示例值描述
image_keystringd640eeea-4d2f-4cb3-88d8-c96fa5****图片的唯一标识。可通过 上传图片 接口获取 image_key。

发送群名片

机器人只能分享其所在群的群名片。
请求消息体示例

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

实现效果
在这里插入图片描述

参数说明

字段类型是否必填示例值描述
share_chat_idstringoc_f5b1a7eb27ae2****339ff群 ID。获取方式请参见 群 ID 说明。

发送图片

请求消息体示例

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

实现效果
在这里插入图片描述

参数说明

字段类型是否必填示例值描述
image_keystringimg_ecffc3b9-8f14-400f-a014-05eca1a4310g图片Key。可通过 上传图片 接口获取 image_key。

发送飞书卡片

飞书卡片是一种轻量的消息推送应用,可由按钮、图片等多种组件搭建而成。了解飞书卡片,参考飞书卡片概述。了解如何使用自定义机器人发送由搭建工具搭建的卡片模板(template),参考使用自定义机器人发送飞书卡片。

注意事项
通过自定义机器人发送的消息卡片,只支持通过按钮、文字链方式跳转 URL,不支持点击后回调信息到服务端的请求回调交互。

在飞书卡片中如果需要 @ 某一用户,则需要注意:自定义机器人仅支持通过 Open ID 或 User ID 实现 @ 用户,暂不支持email、union_id等其他方式。

发送卡片时,需要将消息体的 content 字符串替换为 card 结构体,并对整个请求消息体进行 JSON 转义。

请求消息体示例

{"msg_type": "interactive","card": {"schema": "2.0","config": {"update_multi": true,"style": {"text_size": {"normal_v2": {"default": "normal","pc": "normal","mobile": "heading"}}}},"body": {"direction": "vertical","padding": "12px 12px 12px 12px","elements": [{"tag": "markdown","content": "西湖,位于中国浙江省杭州市西湖区龙井路1号,杭州市区西部,汇水面积为21.22平方千米,湖面面积为6.38平方千米。","text_align": "left","text_size": "normal_v2","margin": "0px 0px 0px 0px"},{"tag": "button","text": {"tag": "plain_text","content": "🌞更多景点介绍"},"type": "default","width": "default","size": "medium","behaviors": [{"type": "open_url","default_url": "https://baike.baidu.com/item/%E8%A5%BF%E6%B9%96/4668821","pc_url": "","ios_url": "","android_url": ""}],"margin": "0px 0px 0px 0px"}]},"header": {"title": {"tag": "plain_text","content": "今日旅游推荐"},"subtitle": {"tag": "plain_text","content": ""},"template": "blue","padding": "12px 12px 12px 12px"}}
}

以上消息体压缩并转义的结果如下所示,你可将其放入 CURL 命令中的请求体中查看效果:

{\"msg_type\":\"interactive\",\"card\":{\"schema\":\"2.0\",\"config\":{\"update_multi\":true,\"style\":{\"text_size\":{\"normal_v2\":{\"default\":\"normal\",\"pc\":\"normal\",\"mobile\":\"heading\"}}}},\"body\":{\"direction\":\"vertical\",\"padding\":\"12px 12px 12px 12px\",\"elements\":[{\"tag\":\"markdown\",\"content\":\"西湖,位于中国浙江省杭州市西湖区龙井路1号,杭州市区西部,汇水面积为21.22平方千米,湖面面积为6.38平方千米。\",\"text_align\":\"left\",\"text_size\":\"normal_v2\",\"margin\":\"0px 0px 0px 0px\"},{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"🌞更多景点介绍\"},\"type\":\"default\",\"width\":\"default\",\"size\":\"medium\",\"behaviors\":[{\"type\":\"open_url\",\"default_url\":\"https://baike.baidu.com/item/%E8%A5%BF%E6%B9%96/4668821\",\"pc_url\":\"\",\"ios_url\":\"\",\"android_url\":\"\"}],\"margin\":\"0px 0px 0px 0px\"}]},\"header\":{\"title\":{\"tag\":\"plain_text\",\"content\":\"今日旅游推荐\"},\"subtitle\":{\"tag\":\"plain_text\",\"content\":\"\"},\"template\":\"blue\",\"padding\":\"12px 12px 12px 12px\"}}}

实现效果
在这里插入图片描述

相关操作
你可以通过飞书卡片搭建工具快速生成卡片,并获取数据结构进行使用,从工具中生成的数据结构对应请求消息体中的 card 字段。

常见问题

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

你可以在机器人发送的普通文本消息(text)、富文本消息(post)、消息卡片(interactive)中,使用 at 标签实现 @ 人效果。具体请求示意如下:

在普通文本消息(text)中 @ 人、@ 所有人

at标签说明

// @ 指定用户
<at user_id="ou_xxx">Name</at> //取值须使用 open_id 或 user_id 来 @ 指定人
// @ 多个指定用户
<at user_id="ou_xxx1">Name1</at><at user_id="ou_xxx2">Name2</at> //取值须使用 open_id 或 user_id 来 @ 指定人
// @ 所有人
<at user_id="all">所有人</at> 

请求体示意

{"msg_type": "text","content": {"text": "<at user_id = \"ou_f43d7bf0bxxxxxxxxxxxxxxx\">Tom</at> text content"}
}

在富文本消息(post)中 @ 人、@所有人:

at标签说明

// @ 指定用户
{"tag": "at","user_id": "ou_xxxxxxx", //取值须使用 open_id 或 user_id 来 @ 指定人"user_name": "tom"
}
// @ 多个指定用户
{"tag": "at","user_id": "ou_xxxxxxx1", //取值须使用 open_id 或 user_id 来 @ 指定人"user_name": "tom1"
},
{"tag": "at","user_id": "ou_xxxxxxx2", //取值须使用 open_id 或 user_id 来 @ 指定人"user_name": "tom2"
}
// @ 所有人
{"tag": "at","user_id": "all", //取值使用"all"来at所有人"user_name": "所有人"
} 

请求体示意

{"msg_type": "post","content": {"post": {"zh_cn": {"title": "我是一个标题","content": [[{"tag": "text","text": "第一行 :"},{"tag": "at","user_id": "ou_xxxxxx", //取值须使用 open_id 或 user_id 来 @ 指定人"user_name": "tom"}],[{"tag": "text","text": "第二行:"},{"tag": "at","user_id": "all","user_name": "所有人"}]]}}}
}

在消息卡片 (interactive) 中@人、@所有人

可以使用消息卡片Markdown内容中的at人标签,标签示意如下

// at 指定用户
<at id=ou_xxx></at> //取值须使用 open_id 或 user_id 来 @ 指定人
// at 所有人
<at id=all></at> 

请求体中的 card 内容示意:

{"msg_type": "interactive","card": {"elements": [{"tag": "div","text": {"content": "at所有人<at id=all></at> \n at指定人<at id=ou_xxxxxx></at>", //取值须使用 open_id 或 user_id 来 @ 指定人"tag": "lark_md"}}]}
}

如何获得 @ 指定人时所需要的 open_id?

自定义机器人不需要租户管理员审核即可向所在的群(包括外部群)发送消息。这一开发上的灵活性也限制自定义机器人不具有任何数据访问权限,否则会在管理员不知情的条件下,泄露租户的隐私信息.

基于这个前提,自定义机器人本身不能调用接口获取用户的 open_id,或直接通过用户的邮箱、手机号来 @ 人(恶意开发者可能用这种方式扫出群成员的头像、姓名等隐私信息)。因此,你可以开发一个机器人应用,使用以下受管控的方案获得用户的open_id,然后参考 怎么实现机器人 @ 人,在自定义机器人推送的消息中 @ 人。

方案一:通过邮箱或手机号反查用户的open_id

你需要创建一个自建应用。

为应用申请权限。

通过手机号或邮箱获取用户 ID(contact:user.id:readonly),并创建应用版本,提交发版审核。

在版本发布审核通过后,调用通过手机号或邮箱获取用户 ID接口,即可通过用户的手机号或邮箱获取用户的open_id。

方案二:解析用户发送给机器人的带 @ 人内容的消息,获取目标用户的 open_id

你需要创建一个自建应用。

完成以下应用配置操作。

为应用申请权限:获取用户发给机器人的单聊消息(im:message.p2p_msg)、获取与发送单聊、群组消息(im:message)。

订阅 消息与群组 分类下的接收消息事件。

为这个自建应用创建应用版本,提交发版审核。

在版本审核发布后,你可以在同机器人的单聊中发送 @ 某用户的消息。解析接收消息事件的返回内容,其中的消息体内上报了被 @ 用户的open_id信息。

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

不能,自定义机器人只能用于在群聊中自动发送通知,不能响应用户 @ 机器人的消息。如需实现机器人接收响应用户消息的功能,建议使用应用机器人。

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

自定义机器人自身无法撤回自己发送的消息,必须由群聊内的群主或管理员进行撤回。撤回方式:

方式一:群聊的群主或管理员在飞书客户端的群聊中直接撤回消息。
在这里插入图片描述

方式二:调用撤回消息接口,以群聊的群主或管理员身份调用该接口撤回消息。

相关问题
是否支持通过 OpenAPI 创建机器人?
同一个自定义机器人能在不同的群组使用吗?
为什么我的机器人在飞书中搜不到?在群聊内添加机器人时也搜索不到?
如何将企业内部人员与外部客户一键拉入群聊?
机器人发送消息时,如何实现 @所有人、@指定人?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/92390.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nhdeep档案管理工具软件官网

欢迎访问nhdeep官网&#xff1a; www.nhdeep.com NHDEEP提供一系列专业的单机版档案管理工具&#xff0c;满足不同场景下的档案管理需求&#xff0c;无需网络连接&#xff0c;数据安全可靠。所有工具均提供免费试用版下载。 档案综合管理系统单机版:全面的档案管理解决方案&a…

RocketMQ节点部署计算方案

节点计算公式 业务场景 预期峰值TPS&#xff1a;200,000 单组容量&#xff1a;40K TPS 容灾要求&#xff1a;同城双机房 nameServer节点数max(3, (15/50) 1) max(3, 0.3 1) max(3, 1.3) 3 Broker节点数ceil(200,000 / 40,000) 5组 总节点数 NameServer节点Broker组数(Mas…

MyBatis联合查询 - XML篇

文章目录数据库设计MyBatis 配置MyBatis 映射文件Mapper 接口总结数据库设计 建表 SQL CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL );CREATE TABLE order (id INT PRIMARY KEY AUTO_INCREMENT,user_id INT NOT NULL,order_no VARCHAR(…

Kubelet 探针如何选择 IP:status.PodIP 溯源与“同 Pod 两个 IP“现象解析

背景与现象同一个 Pod 的 readiness 和 liveness 探针日志显示连接的 IP 不一致&#xff08;例如 10.10.6.10:9999 与 10.10.6.32:9999&#xff09;。本文从 kubelet 源码入手&#xff0c;解释探针目标 IP 的来源、为何会出现两个不同 IP&#xff0c;并给出建议与验证方法。在如…

Arm Development Studio 安全通告:CVE-2025-7427

安全之安全(security)博客目录导读 目录 一、概述 二、CVE 详情 三、受影响产品 四、建议 五、致谢 六、版本历史 一、概述 ARM已知悉一个影响 Arm Development Studio 的安全漏洞&#xff0c;该漏洞可能允许攻击者执行 DLL 劫持攻击&#xff08;DLL hijacking attack&…

C#异步编程双利器:异步Lambda与BackgroundWorker实战解析

**摘要&#xff1a;**深入剖析两种异步编程范式&#xff0c;解决GUI线程阻塞难题 一、异步Lambda表达式&#xff1a;事件处理的轻量化利器 核心价值&#xff1a;简化事件响应中的异步操作&#xff0c;避免UI线程阻塞 ✅ 典型应用场景&#xff08;WPF示例&#xff09;&#xff1…

yolo world (1): 论文解读

YOLO 系列检测器以其高效性和实用性而闻名。然而,它们依赖于预定义和训练的目标类别,这限制了其在开放场景中的适用性。为了解决这一限制,我们提出了 YOLO-World,这是一种创新的方法,通过视觉-语言建模和大规模数据集预训练,增强了 YOLO 的开放词汇检测能力。具体来说,我…

【JVM】深入解析Java虚拟机

目录 1. 区分JDK&#xff0c;JRE 和 JVM 1.1 JVM 1.2 JRE 1.3 JDK 1.4 关系总结 2. 跨平台性 3. JVM中的内存划分 4. JVM的类加载机制 5. 双亲委派模型 6. 垃圾回收机制&#xff08;GC&#xff09; 6.1 识别垃圾 6.1.1 单个引用 6.1.2 多个引用 6.2 释放垃圾 6.…

98-基于Python的网上厨房美食推荐系统

基于Python的网上厨房美食推荐系统 - 技术分享博客 &#x1f4cb; 目录 项目概述技术栈系统架构核心功能实现数据库设计推荐算法数据可视化部署与优化项目特色总结与展望 &#x1f3af; 项目概述 项目背景 随着生活节奏的加快&#xff0c;越来越多的人开始关注美食制作&…

创建MyBatis-Plus版的后端查询项目

记得编码和maven库的检测&#xff01;&#xff01;&#xff01; 1、maven库导入包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupI…

开发板RK3568和stm32的异同:

RK3568 和 STM32 是两类不同定位的处理器 / 微控制器&#xff0c;在架构、性能、应用场景等方面差异显著&#xff0c;但也存在部分共性。以下从核心特性、异同点及典型场景进行对比&#xff1a;一、核心差异维度RK3568&#xff08;瑞芯微&#xff09;STM32&#xff08;意法半导…

C# 使用iText获取PDF的trailer数据

文章目录C# 使用iText获取PDF的trailer数据iText 核心概念C# 代码示例步骤 1: 确保已安装 iText步骤 2: C# 代码程序运行效果解读 Trailer 的输出总结C# 使用iText获取PDF的trailer数据 开发程序debug的时候&#xff0c;看到了PDF有个trailer数据&#xff0c;挺有意思&#xf…

京东流量资产基于湖仓架构的落地实践

在当今数字化商业浪潮中&#xff0c;数据无疑是企业的核心资产&#xff0c;而流量数据更是电商巨头京东业务运转的关键驱动力。它广泛应用于搜索推荐、广告投放等多个核心业务场景&#xff0c;直接影响着用户体验和商业效益。但随着业务规模的不断膨胀&#xff0c;传统架构在处…

​​​​​​​【Datawhale AI夏令营】多模态RAG财报问答挑战赛:学习笔记与上分思考

一、 初识赛题——从迷茫到清晰刚看到赛题时&#xff0c;坦白说有些不知所措。“多模态”、“RAG”、“图文混排PDF”&#xff0c;这些词汇组合在一起&#xff0c;听起来就像一个庞大而复杂的工程。但当我强迫自己静下心来&#xff0c;从“终点”&#xff08;提交格式和评审规则…

数据挖掘2.6 Perceptron Modeling 感知器建模

Perceptron Modeling 感知器建模Linear Discriminants 线性判别式Loss Function 损失函数misclassification 误分类0-1 Loss/Error function 0-1损失函数Hinge Loss Function 铰链损失函数Optimization 优化算法Linear Discriminants 线性判别式 线性判别式公式 f(x;w)w1x(1)w…

使用qemu运行与GDB调试内核

目录 一、前期准备 二、内核编译 三、QEMU与GDB 1、QEMU调试参数 2、gdb vmlinux 一、前期准备 内核镜像&#xff1a;bzimage gdb&#xff1a;x86_64 QEMU&#xff1a;qemu-system-x86_64 前置知识&#xff1a; &#xff08;1&#xff09;内核编译 &#xff08;2&#x…

欧盟 Radio Equipment Directive (RED)

欧盟 Radio Equipment Directive (RED) ——从 2014/53/EU 原文到 2025-08-01 强制生效的网络安全新规&#xff0c;一次看懂全部关键点。1. 法规身份与适用范围要素内容指令全称Directive 2014/53/EU on radio equipment取代指令1999/5/EC (R&TTE)适用产品所有“有意发射/接…

【FastExcel】解决ReadSheet在Map中获取对象不准确问题(已提交PR并合并到开源社区)

解决问题&#xff1a;源码ReadSheet在同一个Map中获取对象不准确问题 PR&#xff1a;Fixed the issue where different ReadSheet objects could not get the correct value when comparing them. 一&#xff1a;问题场景 ReadSheet在同一个Map中获取对象不准确(如Map<…

【网络安全入门基础教程】TCP/IP协议深入解析(非常详细)零基础入门到精通,收藏这一篇就够了

前言 这是小编给粉丝盆友们整理的网络安全入门到精通系列第三章计算机网络中TCP/IP协议的解析&#xff0c;喜欢的朋友们&#xff0c;记得给大白点赞支持和收藏一下&#xff0c;关注我&#xff0c;学习黑客技术。TCP/IP协议包含了一系列的协议&#xff0c;也叫TCP/IP协议族&…