import db from "../../db" import { Context, DB, LarkServer, MsgProxy } from "../../types" import { safeJsonStringify } from "../../utils/pathTools" const LOG_COLLECTION = "message_log" /** * 校验消息请求的参数 * @param {Context.Data} ctx - 上下文数据,包含请求体和响应生成器 * @returns {false | Response} 如果校验失败,返回响应对象;否则返回 false */ const validateMessageReq = ({ body, genResp, }: Context.Data): 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.Data} ctx - 上下文数据,包含请求体、日志记录器、响应生成器和 Lark 服务 * @returns {Promise} 返回响应对象 */ export const manageMessageReq = async ( ctx: Context.Data ): Promise => { const { body: rawBody, genResp, larkService } = ctx const body = rawBody as MsgProxy.Body // 校验参数 const validateRes = validateMessageReq(ctx) if (validateRes) return validateRes // 处理消息内容 const finalContent = typeof body.content !== "string" ? safeJsonStringify(body.content) : body.content // 初始化发送结果对象 const sendRes = { chat_id: {} as Record, open_id: {} as Record, union_id: {} as Record, user_id: {} as Record, email: {} as Record, } // 发送消息列表 const sendList = [] as Promise[] // 构造消息记录 const baseLog: DB.MessageLogCreate = { ...body, final_content: finalContent, } // 校验 api_key const apiKeyInfo = await db.apiKey.getOne(body.api_key) if (!apiKeyInfo) { const error = "api key not found" db.log.create(LOG_COLLECTION, { ...baseLog, error }) return genResp.notFound(error) } // 获取 app name const appName = apiKeyInfo.expand?.app?.name if (!appName) { const error = "app name not found" db.log.create(LOG_COLLECTION, { ...baseLog, error }) return genResp.notFound(error) } // 如果有 group_id,则发送给所有 group_id 中的人 if (body.group_id) { // 获取所有接收者 const group = await db.messageGroup.getOne(body.group_id!) if (!group) { const error = "message group not found" db.log.create(LOG_COLLECTION, { ...baseLog, error }) return genResp.notFound(error) } const { chat_id, open_id, union_id, user_id, email } = group // 构造发送消息函数 const makeSendFunc = (receive_id_type: LarkServer.ReceiveIDType) => { return (receive_id: string) => { sendList.push( larkService .child(appName) .message.send( 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")) } // 如果有 receive_id,则发送给所有 receive_id 中的人 if (body.receive_id && body.receive_id_type) { body.receive_id.split(",").forEach((receive_id) => { sendList.push( larkService .child(appName) .message.send( body.receive_id_type, receive_id, body.msg_type, finalContent ) .then((res) => { sendRes[body.receive_id_type][receive_id] = res }) ) }) } try { // 发送消息 await Promise.allSettled(sendList) // 保存消息记录 db.log.create(LOG_COLLECTION, { ...baseLog, send_result: sendRes }) return genResp.ok(sendRes) } catch { const error = "send msg failed" db.log.create(LOG_COLLECTION, { ...baseLog, error }) return genResp.serverError(error, sendRes) } }