feat: 改由透传消息接口
This commit is contained in:
parent
b9474d00d3
commit
3b97b1def5
49
routes/bot/activeMsg.ts
Normal file
49
routes/bot/activeMsg.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { fetchCIMonitor } from "../../service";
|
||||
import { getActionType, getIsActionMsg } from "../../utils/msgTools";
|
||||
import { updateCard } from "../../utils/sendMsg";
|
||||
|
||||
const makeChatIdCard = (body: LarkUserAction) => {
|
||||
return JSON.stringify({ text: `chatId: ${body.open_chat_id}` });
|
||||
};
|
||||
|
||||
const makeCICard = async () => {
|
||||
const card = await fetchCIMonitor();
|
||||
if (!card) return "";
|
||||
return JSON.stringify(card);
|
||||
};
|
||||
|
||||
const ACTION_MAP = {
|
||||
chat_id: makeChatIdCard,
|
||||
ci: makeCICard,
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理按钮点击事件
|
||||
* @param {LarkUserAction} body
|
||||
*/
|
||||
const manageBtnClick = async (body: LarkUserAction) => {
|
||||
const { action } = body?.action?.value as {
|
||||
action: keyof typeof ACTION_MAP;
|
||||
};
|
||||
if (!action) return;
|
||||
const card = await ACTION_MAP[action](body);
|
||||
if (!card) return;
|
||||
// 更新飞书的卡片
|
||||
await updateCard(body.open_message_id, card);
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理Action消息
|
||||
* @param {LarkUserAction} body
|
||||
*/
|
||||
export const manageActionMsg = async (body: LarkUserAction) => {
|
||||
// 过滤非Action消息
|
||||
if (!getIsActionMsg(body)) {
|
||||
return false;
|
||||
}
|
||||
const actionType = getActionType(body);
|
||||
if (actionType === "button") {
|
||||
manageBtnClick(body);
|
||||
}
|
||||
return true;
|
||||
};
|
@ -1,38 +1,12 @@
|
||||
import { fetchCIMonitor } from "../../service";
|
||||
import { getChatId, getIsEventMsg, getMsgType } from "../../utils/msgTools";
|
||||
import { sendMsg } from "../../utils/sendMsg";
|
||||
|
||||
/**
|
||||
* 是否为事件消息
|
||||
* @param {LarkMessageEvent} body
|
||||
*/
|
||||
const isEventMsg = (body: LarkMessageEvent) => {
|
||||
return body?.header?.event_type === "im.message.receive_v1";
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取事件文本类型
|
||||
* @param {LarkMessageEvent} body
|
||||
* @returns
|
||||
*/
|
||||
const getMsgType = (body: LarkMessageEvent) => {
|
||||
return body?.event?.message?.message_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取对话流Id
|
||||
* @param {LarkMessageEvent} body
|
||||
* @returns
|
||||
*/
|
||||
const getChatId = (body: LarkMessageEvent) => {
|
||||
return body?.event?.message?.chat_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取文本内容并剔除艾特信息
|
||||
* @param {LarkMessageEvent} body
|
||||
* @returns {string} 文本内容
|
||||
*/
|
||||
const getMsgText = (body: LarkMessageEvent) => {
|
||||
export const getMsgText = (body: LarkMessageEvent) => {
|
||||
// TODO: 如果之后想支持单独提醒,这里需要做模板解析
|
||||
try {
|
||||
const { text } = JSON.parse(body?.event?.message?.content);
|
||||
@ -78,67 +52,33 @@ const filterIllegalMsg = (body: LarkMessageEvent) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理info指令
|
||||
* @param chatId 聊天流Id
|
||||
*/
|
||||
const manageInfoCommand = (chatId: string) => {
|
||||
const content = JSON.stringify({ text: `chatId: ${chatId}` });
|
||||
sendMsg("chat_id", chatId, "text", content);
|
||||
};
|
||||
|
||||
/**
|
||||
* 过滤出指令
|
||||
* 回复普通消息
|
||||
* @param {LarkMessageEvent} body
|
||||
* @returns {boolean} 是否为info指令
|
||||
*/
|
||||
const filterCommand = (body: LarkMessageEvent) => {
|
||||
const chatId = getChatId(body);
|
||||
const text = getMsgText(body);
|
||||
if (text === "info") {
|
||||
manageInfoCommand(chatId);
|
||||
return true;
|
||||
}
|
||||
if (text === "ci") {
|
||||
fetchCIMonitor();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const replyNomalMsg = async (body: LarkMessageEvent) => {
|
||||
const chatId = getChatId(body);
|
||||
const content = JSON.stringify({
|
||||
elements: [
|
||||
{
|
||||
tag: "markdown",
|
||||
content: "**目前支持的指令**\n1. info\n2. ci",
|
||||
},
|
||||
],
|
||||
header: {
|
||||
template: "blue",
|
||||
title: {
|
||||
content: "欢迎使用小煎蛋 ₍ᐢ..ᐢ₎♡",
|
||||
tag: "plain_text",
|
||||
},
|
||||
type: "template",
|
||||
data: {
|
||||
template_id: "ctp_AAyVx5R39xU9",
|
||||
},
|
||||
});
|
||||
sendMsg("chat_id", chatId, "interactive", content);
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理Event消息
|
||||
* @param {LarkUserAction} body
|
||||
*/
|
||||
export const manageEventMsg = async (body: LarkMessageEvent) => {
|
||||
// 过滤非Event消息
|
||||
if (!isEventMsg(body)) {
|
||||
if (!getIsEventMsg(body)) {
|
||||
return false;
|
||||
}
|
||||
// 过滤非法消息
|
||||
if (filterIllegalMsg(body)) {
|
||||
return true;
|
||||
}
|
||||
// 过滤指令
|
||||
if (filterCommand(body)) {
|
||||
return true;
|
||||
}
|
||||
// 临时返回消息
|
||||
replyNomalMsg(body);
|
||||
return true;
|
||||
|
@ -1,13 +1,16 @@
|
||||
import { manageEventMsg } from "./eventMsg"
|
||||
import { manageActionMsg } from "./activeMsg";
|
||||
import { manageEventMsg } from "./eventMsg";
|
||||
|
||||
export const manageBotReq = async (req: Request) => {
|
||||
const body = await req.json() as any
|
||||
const body = (await req.json()) as any;
|
||||
// 验证机器人
|
||||
if (body?.type === 'url_verification') {
|
||||
console.log("🚀 ~ manageBotReq ~ url_verification:")
|
||||
return Response.json({ challenge: body?.challenge })
|
||||
if (body?.type === "url_verification") {
|
||||
console.log("🚀 ~ manageBotReq ~ url_verification:");
|
||||
return Response.json({ challenge: body?.challenge });
|
||||
}
|
||||
// 处理Event消息
|
||||
if (await manageEventMsg(body)) return new Response("success")
|
||||
return new Response("hello, glade to see you!")
|
||||
}
|
||||
if (await manageEventMsg(body)) return new Response("success");
|
||||
// 处理Action消息
|
||||
if (await manageActionMsg(body)) return new Response("success");
|
||||
return new Response("hello, glade to see you!");
|
||||
};
|
||||
|
@ -1,15 +1,28 @@
|
||||
import db from "../../db";
|
||||
import { sendMsg } from "../../utils/sendMsg";
|
||||
|
||||
interface MessageReqJson {
|
||||
group_id: string;
|
||||
interface BaseMsg {
|
||||
msg_type: MsgType;
|
||||
content: string;
|
||||
}
|
||||
|
||||
interface GroupMsg extends BaseMsg {
|
||||
group_id: string;
|
||||
}
|
||||
|
||||
interface NormalMsg extends BaseMsg {
|
||||
receive_id: string;
|
||||
receive_id_type: ReceiveIDType;
|
||||
}
|
||||
|
||||
type MessageReqJson = GroupMsg & NormalMsg;
|
||||
|
||||
const validateMessageReq = (body: MessageReqJson) => {
|
||||
if (!body.group_id) {
|
||||
return new Response("group_id is required");
|
||||
if (!body.group_id && !body.receive_id) {
|
||||
return new Response("group_id or receive_id is required");
|
||||
}
|
||||
if (body.receive_id && !body.receive_id_type) {
|
||||
return new Response("receive_id_type is required");
|
||||
}
|
||||
if (!body.msg_type) {
|
||||
return new Response("msg_type is required");
|
||||
@ -24,16 +37,8 @@ export const manageMessageReq = async (req: Request) => {
|
||||
const body = (await req.json()) as MessageReqJson;
|
||||
// 校验参数
|
||||
const validateRes = validateMessageReq(body);
|
||||
if (validateRes) {
|
||||
return validateRes;
|
||||
}
|
||||
// 获取所有接收者
|
||||
const group = (await db.messageGroup.getOne(body.group_id)) as PBMessageGroup;
|
||||
if (!group) {
|
||||
return new Response("group not found");
|
||||
}
|
||||
if (validateRes) return validateRes;
|
||||
|
||||
const { chat_id, open_id, union_id, user_id, email } = group;
|
||||
// 遍历所有id发送消息,保存所有对应的messageId
|
||||
const sendRes = {
|
||||
chat_id: {} as Record<string, any>,
|
||||
@ -42,33 +47,63 @@ export const manageMessageReq = async (req: Request) => {
|
||||
user_id: {} as Record<string, any>,
|
||||
email: {} as Record<string, any>,
|
||||
};
|
||||
|
||||
// 发送消息列表
|
||||
const sendList = [] as Promise<any>[];
|
||||
|
||||
// 处理消息内容
|
||||
const finalContent =
|
||||
typeof body.content !== "string"
|
||||
? JSON.stringify(body.content)
|
||||
: body.content;
|
||||
|
||||
// 构造发送消息函数
|
||||
const makeSendFunc = (receive_id_type: ReceiveIDType) => {
|
||||
return (receive_id: string) => {
|
||||
sendList.push(
|
||||
sendMsg(receive_id_type, receive_id, body.msg_type, finalContent).then(
|
||||
(res) => {
|
||||
sendRes[receive_id_type][receive_id] = res;
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
if (body.group_id) {
|
||||
// 获取所有接收者
|
||||
const group = (await db.messageGroup.getOne(
|
||||
body.group_id!
|
||||
)) as PBMessageGroup;
|
||||
if (!group) {
|
||||
return new Response("group not found");
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
if (chat_id) chat_id.map(makeSendFunc("chat_id"));
|
||||
if (open_id) open_id.map(makeSendFunc("open_id"));
|
||||
if (union_id) union_id.map(makeSendFunc("union_id"));
|
||||
if (user_id) user_id.map(makeSendFunc("user_id"));
|
||||
if (email) email.map(makeSendFunc("email"));
|
||||
const { chat_id, open_id, union_id, user_id, email } = group;
|
||||
|
||||
// 构造发送消息函数
|
||||
const makeSendFunc = (receive_id_type: ReceiveIDType) => {
|
||||
return (receive_id: string) => {
|
||||
sendList.push(
|
||||
sendMsg(
|
||||
receive_id_type,
|
||||
receive_id,
|
||||
body.msg_type,
|
||||
finalContent
|
||||
).then((res) => {
|
||||
sendRes[receive_id_type][receive_id] = res;
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
// 创建消息列表
|
||||
if (chat_id) chat_id.map(makeSendFunc("chat_id"));
|
||||
if (open_id) open_id.map(makeSendFunc("open_id"));
|
||||
if (union_id) union_id.map(makeSendFunc("union_id"));
|
||||
if (user_id) user_id.map(makeSendFunc("user_id"));
|
||||
if (email) email.map(makeSendFunc("email"));
|
||||
}
|
||||
|
||||
if (body.receive_id && body.receive_id_type) {
|
||||
sendList.push(
|
||||
sendMsg(
|
||||
body.receive_id_type,
|
||||
body.receive_id,
|
||||
body.msg_type,
|
||||
finalContent
|
||||
).then((res) => {
|
||||
sendRes[body.receive_id_type][body.receive_id] = res;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await Promise.all(sendList);
|
||||
|
@ -1 +1,8 @@
|
||||
export const fetchCIMonitor = () => fetch("https://ci-monitor.xiaomiwh.cn/ci");
|
||||
export const fetchCIMonitor = async () => {
|
||||
try {
|
||||
const res = await fetch("https://ci-monitor.xiaomiwh.cn/ci");
|
||||
return (await res.json()) as any;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
42
utils/msgTools.ts
Normal file
42
utils/msgTools.ts
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 是否为事件消息
|
||||
* @param {LarkMessageEvent} body
|
||||
*/
|
||||
export const getIsEventMsg = (body: LarkMessageEvent) => {
|
||||
return body?.header?.event_type === "im.message.receive_v1";
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取事件文本类型
|
||||
* @param {LarkMessageEvent} body
|
||||
* @returns
|
||||
*/
|
||||
export const getMsgType = (body: LarkMessageEvent) => {
|
||||
return body?.event?.message?.message_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取对话流Id
|
||||
* @param {LarkMessageEvent} body
|
||||
* @returns
|
||||
*/
|
||||
export const getChatId = (body: LarkMessageEvent) => {
|
||||
return body?.event?.message?.chat_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* 是否为Action消息
|
||||
* @param {LarkUserAction} body
|
||||
*/
|
||||
export const getIsActionMsg = (body: LarkUserAction) => {
|
||||
return body?.action;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取Action类型
|
||||
* @param {LarkUserAction} body
|
||||
* @returns {string} Action类型
|
||||
*/
|
||||
export const getActionType = (body: LarkUserAction) => {
|
||||
return body?.action?.tag;
|
||||
};
|
@ -47,9 +47,52 @@ export const sendMsg = async (
|
||||
console.log("sendMsg error", error);
|
||||
return {
|
||||
code: 1,
|
||||
msg: "fetch error",
|
||||
msg: "sendMsg fetch error",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// sendMsg('user_id', 'liuke9', 'text', JSON.stringify({text: '这是测试消息,不要回复'}))
|
||||
/**
|
||||
* 更新卡片
|
||||
* @param {string} message_id 消息id
|
||||
* @param {*} content 消息内容,JSON结构序列化后的字符串。不同msg_type对应不同内容
|
||||
*/
|
||||
export const updateCard = async (message_id: string, content: string) => {
|
||||
const URL = `https://open.f.mioffice.cn/open-apis/im/v1/messages/${message_id}`;
|
||||
const tenant_access_token = await db.tenantAccessToken.get();
|
||||
const header = {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
Authorization: `Bearer ${tenant_access_token}`,
|
||||
};
|
||||
const body = { content };
|
||||
|
||||
try {
|
||||
const res = await fetch(URL, {
|
||||
method: "PATCH",
|
||||
headers: header,
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const data = (await res.json()) as any;
|
||||
if (data.code !== 0) {
|
||||
console.log("updateCard error", data);
|
||||
return {
|
||||
code: data.code,
|
||||
msg: data.msg,
|
||||
};
|
||||
}
|
||||
console.log("updateCard success", data);
|
||||
return {
|
||||
code: 0,
|
||||
msg: "success",
|
||||
data: {
|
||||
message_id: data.data.message_id,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
console.log("updateCard error", error);
|
||||
return {
|
||||
code: 1,
|
||||
msg: "updateCard fetch error",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user