柚子快報邀請碼778899分享:飛書自定義機器人消息接入指南
柚子快報邀請碼778899分享:飛書自定義機器人消息接入指南
操作流程
第一步
邀請自定義機器人入群:進入你的目標群組,打開會話設置,找到群機器人,并點擊添加機器人,選擇自定義機器人加入群聊。
為機器人輸入一個合適的名字和描述,也可以為機器人設置一個合適的頭像,然后點擊下一步。
第二部:配置 webhook
獲取該機器人的 webhook 地址,格式如下:
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx
第三步:調(diào)用webhook發(fā)送消息
用任意方式向該 webhook 發(fā)起 HTTP POST 請求,即可向這個自定義機器人所在的群聊發(fā)送消息。
注意
你需要一定的服務端開發(fā)基礎,通過服務端請求方式調(diào)用webhook地址。 以curl指令為例,請求示例如下:
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/xxxxxxxxxxxxxxxxx
請將上述代碼中 https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx 更換為真實webhook的地址。 若測試出錯,請先檢查復制的指令是否和測試指令結(jié)構(gòu)一致。
如請求成功,返回體為:
{
"code": 0,
"msg": "success",
"data": {},
"Extra": null,//冗余字段,用于兼容存量歷史邏輯,不建議使用
"StatusCode": 0,//冗余字段,用于兼容存量歷史邏輯,不建議使用
"StatusMessage": "success"http://冗余字段,用于兼容存量歷史邏輯,不建議使用
}
如請求體格式錯誤,返回體如下。請檢查:
請求體內(nèi)容格式是否與各消息類型的示例代碼一致請求體大小不能超過20k
{
"code": 9499,
"msg": "Bad Request",
"data": {}
}
添加安全設置
如果未妥善保管webhook地址,可能存在webhook地址泄露后,被惡意開發(fā)者調(diào)用,發(fā)送垃圾信息的風險,我們強烈建議對其進行安全設置。安全設置目前提供了 3 種方式,可根據(jù)需求選擇一種及以上方式進行配置。
方式一:自定義關(guān)鍵詞
最多設置 10 個關(guān)鍵詞。設定后,只有包含至少一個關(guān)鍵詞的消息才會被發(fā)送。如,將自定義關(guān)鍵詞設為“應用報警”和“項目更新”后,自定義機器人發(fā)送的消息至少包含其中一個詞,才會被發(fā)送到群聊。
發(fā)送請求后,若自定義關(guān)鍵詞校驗失敗,將返回以下信息:
// 關(guān)鍵詞校驗失敗
{
"code": 19024,
"msg": "Key Words Not Found"
}
方式二:IP 白名單
? 最多設置 10 個 IP 地址或地址段。設定后,只處理來自所設 IP 地址范圍的請求。支持段輸入,如 123.12.1.* 或 123.1.1.1/24
// IP校驗失敗
{
"code": 19022,
"msg": "Ip Not Allowed"
}
方式三:簽名校驗
設定后,發(fā)送的請求是需要簽名驗證來保障來源可信。 簽名的算法:把 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 = 100;
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));
}
}
? 獲得簽名后,在發(fā)送請求時需加上 timestamp 和 sign (即獲得的簽名)字段。發(fā)送文本消息的請求例如下:
// 開啟簽名驗證后發(fā)送文本消息
{
"timestamp": "1599360473",
"sign": "xxxxxxxxxxxxxxxxxxxxx",
"msg_type": "text",
"content": {
"text": "request example"
}
}
發(fā)送請求后,若簽名校驗失敗,請排查以下原因:
時間戳距發(fā)送時已超過 1 小時,簽名已過期;服務器時間與標準時間有比較大的偏差,導致簽名過期。請注意檢查、校準你的服務器時間;簽名不匹配,校驗不通過。將返回以下信息:
// 簽名校驗失敗
{
"code": 19021,
"msg": "sign match fail or timestamp is not within one hour from current time"
}
發(fā)送消息
自定義機器人添加完成后,就能向其 webhook 地址發(fā)送 POST 請求,從而在群聊中推送消息了。支持推送的消息格式有文本、富文本、圖片消息和群名片等。 在消息體中,參數(shù)msg_type和對應的消息類型的映射關(guān)系如下:
參數(shù)(msg_type)消息類型參考文檔text文本文本消息格式說明post富文本富文本消息格式說明image圖片上傳圖片share_chat分享群名片–interactive消息卡片消息卡片消息
文本消息
請求的消息體示例:
{
"msg_type": "text",
"content": {
"text": "新更新提醒"
}
}
富文本消息
請求的消息體示例:
{
"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"
}
]
]
}
}
}
}
發(fā)送群名片
請求的消息體示例:
{
"msg_type":"image",
"content":{
"image_key": "img_ecffc3b9-8f14-400f-a014-05eca1a4310g"
}
}
image_key的獲取方法,可參考上傳圖片說明文檔。
發(fā)送卡片消息
消息卡片可由按鈕、圖片等多種組件類型搭建而成。關(guān)于消息卡片的設計規(guī)范、格式等信息,請詳見開放平臺文檔-消息卡片。
自定義機器人發(fā)送的消息卡片,只支持通過按鈕、文字鏈方式跳轉(zhuǎn)url,不支持點擊后回調(diào)信息到服務端的 回傳交互在消息卡片中如果要@提到某用戶,請注意:自定義機器人僅支持通過open_id(什么是open_id?)的方式實現(xiàn),暫不支持email、user_id等其他方式。
請求的消息體示例:
注意:發(fā)送消息卡片時,需要將消息體的content字符串替換為card結(jié)構(gòu)體
{
"msg_type": "interactive",
"card": {
"elements": [{
"tag": "div",
"text": {
"content": "**西湖**,位于浙江省杭州市西湖區(qū)龍井路1號,杭州市區(qū)西部,景區(qū)總面積49平方千米,匯水面積為21.22平方千米,湖面面積為6.38平方千米。",
"tag": "lark_md"
}
}, {
"actions": [{
"tag": "button",
"text": {
"content": "更多景點介紹 :玫瑰:",
"tag": "lark_md"
},
"url": "https://www.example.com",
"type": "default",
"value": {}
}],
"tag": "action"
}],
"header": {
"title": {
"content": "今日旅游推薦",
"tag": "plain_text"
}
}
}
}
如何實現(xiàn)@指定人、@所有人
可以在機器人發(fā)送的普通文本消息(text)、富文本消息(post)、消息卡片(interactive)中,使用at標簽實現(xiàn)@人效果。具體請求示意如下
在普通文本消息 (text) 中@人、@所有人:
at標簽說明:
// at 指定用戶
// at 所有人
請求體示意:
{
"msg_type": "text",
"content": {
"text": "
}
}
(2) 在富文本消息 (post) 中@人、@所有人:
at標簽說明:
// at 指定用戶
{
"tag": "at",
"user_id": "ou_xxxxxxx",//取值必須使用ou_xxxxx格式的 open_id 來at指定人
"user_name": "tom"
}
// at 所有人
{
"tag": "at",
"user_id": "all",//取值使用"all"來at所有人
"user_name": "所有人"
}
請求體示意:
{
"msg_type": "post",
"content": {
"zh_cn": {
"title": "我是一個標題",
"content": [
[{
"tag": "text",
"text": "第一行 :"
},
{
"tag": "at",
"user_id": "ou_xxxxxx",
"user_name": "tom"
}
],
[{
"tag": "text",
"text": "第二行:"
},
{
"tag": "at",
"user_id": "all",
"user_name": "所有人"
}
]
]
}
}
}
(3) 在消息卡片 (interactive) 中@人、@所有人:
可以使用消息卡片Markdown內(nèi)容中的at人標簽,標簽示意:
// at 指定用戶
// at 所有人
請求體中的 card 內(nèi)容示意:
{
"msg_type": "interactive",
"card": {
"elements": [{
"tag": "div",
"text": {
"content": "at所有人
"tag": "lark_md"
}
}]
}
}
以上消息內(nèi)容可支持 markdown 格式的語法
飛書 Java 代碼示例
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
/**
* 飛書消息提醒
*/
@Component
public class FeiShuUtils {
@Resource
private RestTemplate restTemplate;
// 發(fā)送文本消息
public void sendTextMessage() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Map
text.put("msg_type", "text");
Map
// content.put("text", "項目告警通知:" + sdf.format(new Date()));
content.put("text", "項目告警通知
text.put("content", content);
String url = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxxx";
String response = restTemplate.postForObject(url, text, String.class);
System.out.println(response);
}
// 發(fā)送富文本消息
public void sendRichTextMessage() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = "{\n" +
" \"msg_type\": \"post\",\n" +
" \"content\": {\n" +
" \"post\": {\n" +
" \"zh_cn\": {\n" +
" \"title\": \"項目更新通知\",\n" +
" \"content\": [\n" +
" [\n" +
" {\n" +
" \"tag\": \"text\",\n" +
" \"text\": \"項目有更新: \"\n" +
" },\n" +
" {\n" +
" \"tag\": \"a\",\n" +
" \"text\": \"請查看\",\n" +
" \"href\": \"http://www.baidu.com/\"\n" +
" },\n" +
" {\n" +
" \"tag\": \"at\",\n" +
" \"user_id\": \"all\",\n" +
" \"user_name\": \"所有人\"\n" +
" }\n" +
" ]\n" +
" ]\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
HttpHeaders headers = new HttpHeaders();
// 設置請求頭編碼格式防止亂碼
headers.add("Content-Type", "application/json; charset=UTF-8");
HttpEntity
String url = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxxx";
String response = restTemplate.postForObject(url, requestEntity, String.class);
System.out.println(response);
}
// 發(fā)送圖片消息
public void sendImage() {
String str = "{\n" +
" \"msg_type\":\"image\",\n" +
" \"content\":{\n" +
" \"image_key\": \"img_ecffc3b9-8f14-400f-a014-05eca1a4310g\"\n" +
" }\n" +
"} ";
String url = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxxx";
String response = restTemplate.postForObject(url, str, String.class);
System.out.println(response);
}
// 發(fā)送卡片消息
public void sendCard() {
String str = "{\n" +
" \"msg_type\": \"interactive\",\n" +
" \"card\": {\n" +
" \"config\": {\n" +
" \"wide_screen_mode\": true\n" +
" },\n" +
" \"elements\": [\n" +
" {\n" +
" \"tag\": \"markdown\",\n" +
" \"content\": \"這里是卡片文本,支持使用markdown標簽設置文本格式。例如:\\n*斜體* 、**粗體**、~~刪除線~~、[文字鏈接](https://www.feishu.cn)、
" },\n" +
" {\n" +
" \"alt\": {\n" +
" \"content\": \"\",\n" +
" \"tag\": \"plain_text\"\n" +
" },\n" +
" \"img_key\": \"img_v2_041b28e3-5680-48c2-9af2-497ace79333g\",\n" +
" \"tag\": \"img\"\n" +
" },\n" +
" {\n" +
" \"tag\": \"action\",\n" +
" \"actions\": [\n" +
" {\n" +
" \"tag\": \"button\",\n" +
" \"text\": {\n" +
" \"tag\": \"plain_text\",\n" +
" \"content\": \"這是跳轉(zhuǎn)按鈕\"\n" +
" },\n" +
" \"type\": \"primary\",\n" +
" \"url\": \"https://feishu.cn\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" ],\n" +
" \"header\": {\n" +
" \"template\": \"blue\",\n" +
" \"title\": {\n" +
" \"content\": \"這里是卡片標題\",\n" +
" \"tag\": \"plain_text\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
HttpHeaders headers = new HttpHeaders();
// 設置請求頭編碼格式防止亂碼
headers.add("Content-Type", "application/json; charset=UTF-8");
HttpEntity
String url = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxxx";
String response = restTemplate.postForObject(url, requestEntity, String.class);
System.out.println(response);
}
}
發(fā)送結(jié)果
柚子快報邀請碼778899分享:飛書自定義機器人消息接入指南
精彩文章
本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。