167 lines
4.7 KiB
TypeScript
167 lines
4.7 KiB
TypeScript
import { stringifyJson } from "@egg/hooks"
|
||
import { LarkService } from "@egg/net-tool"
|
||
|
||
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 && !body.group_id) {
|
||
return genResp.badRequest("api_key or group_id 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<Response>} 返回响应对象
|
||
*/
|
||
export const manageMessageReq = async (ctx: Context): Promise<Response> => {
|
||
const { body: rawBody, genResp, requestId, db } = 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<string, Record<string, any>> = {
|
||
chatId: {},
|
||
openId: {},
|
||
unionId: {},
|
||
userId: {},
|
||
email: {},
|
||
}
|
||
|
||
// 发送消息列表
|
||
const sendList = [] as Promise<any>[]
|
||
|
||
// 构造消息记录
|
||
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,
|
||
}
|
||
|
||
let larkService: LarkService | null = null
|
||
|
||
if (body.api_key) {
|
||
// 校验 api_key
|
||
const apiKeyInfo = await db.apiKey.getWithApp(body.api_key)
|
||
if (!apiKeyInfo) {
|
||
const error = "api key not found"
|
||
await db.log.create({ ...baseLog, error })
|
||
return genResp.notFound(error)
|
||
}
|
||
|
||
// 生成 Lark 服务
|
||
larkService = genLarkService(apiKeyInfo.expand.app.name, requestId)
|
||
}
|
||
|
||
// 如果有 group_id,则发送给所有 group_id 中的人
|
||
if (body.group_id) {
|
||
// 获取所有接收者
|
||
const group = await db.receiveGroup.getWithApp(body.group_id!)
|
||
if (!group) {
|
||
const error = "message group not found"
|
||
await db.log.create({ ...baseLog, error })
|
||
return genResp.notFound(error)
|
||
}
|
||
|
||
if (!larkService) {
|
||
if (!group.expand?.app?.name) {
|
||
const error = "api key not found"
|
||
await db.log.create({ ...baseLog, error })
|
||
return genResp.notFound(error)
|
||
}
|
||
larkService = genLarkService(group.expand.app.name, requestId)
|
||
}
|
||
|
||
const { chatId, userId } = 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 (userId) userId.map(makeSendFunc("user_id"))
|
||
}
|
||
|
||
if (!larkService) {
|
||
const error = "api key not found"
|
||
await db.log.create({ ...baseLog, error })
|
||
return genResp.notFound(error)
|
||
}
|
||
|
||
// 如果有 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)
|
||
}
|
||
}
|