import { stringifyJson } from "@egg/hooks" import db from "../../db" import { Log } from "../../db/log" import { Context, LarkServer, MsgProxy } from "../../types" import genLarkService from "../../utils/genLarkService" const ID_TYPE_MAP = { chat_id: "chatId", open_id: "openId", union_id: "unionId", user_id: "userId", email: "email", } /** * 校验消息请求的参数 * @param {Context} ctx - 上下文数据,包含请求体和响应生成器 * @returns {false | Response} 如果校验失败,返回响应对象;否则返回 false */ const validateMessageReq = ({ body, genResp }: Context): false | Response => { if (!body.api_key) { return genResp.badRequest("api_key is required") } if (!body.group_id && !body.receive_id) { return genResp.badRequest("group_id or receive_id is required") } if (body.receive_id && !body.receive_id_type) { return genResp.badRequest("receive_id_type is required") } if (!body.msg_type) { return genResp.badRequest("msg_type is required") } if (!body.content) { return genResp.badRequest("content is required") } return false } /** * 处理消息请求 * @param {Context} ctx - 上下文数据,包含请求体、日志记录器、响应生成器和 Lark 服务 * @returns {Promise} 返回响应对象 */ export const manageMessageReq = async (ctx: Context): Promise => { const { body: rawBody, genResp, requestId } = ctx const body = rawBody as MsgProxy.Body // 校验参数 const validateRes = validateMessageReq(ctx) if (validateRes) return validateRes // 处理消息内容 const finalContent = typeof body.content !== "string" ? stringifyJson(body.content) : body.content // 初始化发送结果对象 const sendResult: Record> = { chatId: {}, openId: {}, unionId: {}, userId: {}, email: {}, } // 发送消息列表 const sendList = [] as Promise[] // 构造消息记录 const baseLog: Log = { apiKey: body.api_key, groupId: body.group_id, receiveId: body.receive_id, receiveIdType: body.receive_id_type, msgType: body.msg_type, content: body.content, finalContent, } // 校验 api_key const apiKeyInfo = await db.apiKey.getOne(body.api_key) if (!apiKeyInfo) { const error = "api key not found" await db.log.create({ ...baseLog, error }) return genResp.notFound(error) } // 生成 Lark 服务 const larkService = genLarkService(apiKeyInfo.expand.app.name, requestId) // 如果有 group_id,则发送给所有 group_id 中的人 if (body.group_id) { // 获取所有接收者 const group = await db.receiveGroup.getOne(body.group_id!) if (!group) { const error = "message group not found" await db.log.create({ ...baseLog, error }) return genResp.notFound(error) } const { chatId, openId, unionId, userId, email } = group // 构造发送消息函数 const makeSendFunc = (receive_id_type: LarkServer.ReceiveIDType) => { return (receive_id: string) => { sendList.push( larkService.message .send(receive_id_type, receive_id, body.msg_type, finalContent) .then((res) => { sendResult[ID_TYPE_MAP[receive_id_type]][receive_id] = res }) ) } } // 创建消息列表 if (chatId) chatId.map(makeSendFunc("chat_id")) if (openId) openId.map(makeSendFunc("open_id")) if (unionId) unionId.map(makeSendFunc("union_id")) if (userId) userId.map(makeSendFunc("user_id")) if (email) email.map(makeSendFunc("email")) } // 如果有 receive_id,则发送给所有 receive_id 中的人 if (body.receive_id && body.receive_id_type) { body.receive_id.split(",").forEach((receive_id) => { sendList.push( larkService.message .send(body.receive_id_type, receive_id, body.msg_type, finalContent) .then((res) => { sendResult[ID_TYPE_MAP[body.receive_id_type]][receive_id] = res }) ) }) } try { // 发送消息 await Promise.allSettled(sendList) // 保存消息记录 await db.log.create({ ...baseLog, sendResult }) return genResp.ok(sendResult) } catch { const error = "send msg failed" await db.log.create({ ...baseLog, error }) return genResp.serverError(error, sendResult) } }