refactor: 更新群聊助手逻辑,移除订阅功能并整合报告功能

This commit is contained in:
zhaoyingbo 2024-11-28 07:42:49 +00:00
parent 3f971a0e77
commit bc67792f30
6 changed files with 543 additions and 548 deletions

View File

@ -1,412 +1,9 @@
import { genCardOptions, LarkEvent } from "@egg/lark-msg-tool"
import manual from "./manual"
import report from "./report"
import { functionOptionList } from "../../constant/card"
import { Context, LarkServer } from "../../types"
import llm from "../../utils/llm"
import getChatHistory from "./chatHistory"
/**
*
* @param ctx -
* @param innerList -
* @param commonVal -
*/
const genGroupSelector = (
{ larkCard }: Context.Data,
innerList: LarkServer.ChatGroupData[],
commonVal: Record<string, any> = {}
) => {
const cardGender = larkCard.child("groupAgent")
// 组织群组数据
const groupOptions = genCardOptions(
innerList.reduce(
(acc, item) => {
acc[item.name] = `${item.chat_id}|${item.name}`
return acc
},
{} as Record<string, string>
)
)
return cardGender.genCard("groupSelector", {
groupOptions,
...commonVal,
})
}
/**
*
* @param ctx -
* @param commonVal -
*/
const genFunctionSelector = (
{ larkCard }: Context.Data,
commonVal: Record<string, any> = {}
) => {
const cardGender = larkCard.child("groupAgent")
// 组织功能数据
const functionOptions = genCardOptions(
functionOptionList.reduce(
(acc, item) => {
acc[item.name] = `${item.id}|${item.name}`
return acc
},
{} as Record<string, string>
)
)
return cardGender.genCard("functionSelector", {
functionOptions,
...commonVal,
})
}
/**
*
* @param ctx - body和larkService
*/
const genTimeScopeSelector = (
{ larkCard }: Context.Data,
commonVal: Record<string, any> = {}
) => {
return larkCard.child("groupAgent").genCard("timeScopeSelector", commonVal)
}
const sendGroupReport = async (
ctx: Context.Data,
messageId: string,
{
chatId,
chatName,
functionId,
functionName,
timeScope,
startTime,
endTime,
mentions,
}: {
chatId: string
chatName: string
functionId: string
functionName: string
timeScope?: string
startTime?: string
endTime?: string
mentions?: LarkEvent.Mention[]
}
) => {
const { larkService, logger, larkCard, requestId } = ctx
const cardGender = larkCard.child("groupAgent")
const updateCard = (content: any) =>
larkService.message.update(messageId, content)
// action需要返回loading的消息event需要主动update卡片所以loading就放外边了
// 记录发送loading消息后的时间戳
const processStart = Date.now()
// 获取聊天记录
const chatHistory = await getChatHistory(ctx, {
chatId,
timeScope,
startTime,
endTime,
mentions,
})
// 如果没有历史记录则返回错误消息
if (chatHistory.length === 0) {
logger.error("Chat history is empty")
await updateCard(cardGender.genErrorCard("未找到聊天记录"))
return
}
logger.debug(`Chat history: ${JSON.stringify(chatHistory)}`)
try {
const llmRes = await llm.invoke(
functionId,
{
chatHistory: JSON.stringify(chatHistory),
time: new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" }),
},
requestId
)
// 记录大模型返回结果后的时间戳
const processEnd = Date.now()
// 计算时间差并存储在processingTime变量中以秒为单位
const processingTime = ((processEnd - processStart) / 1000).toFixed(2)
logger.info(`LLM takes time: ${processingTime}s, result: ${llmRes}`)
// 动态生成content内容
const timeRange = timeScope
? `总结天数:**${timeScope}**`
: `时间范围:**${startTime}** 至 **${endTime}**`
const mentionsList = mentions
? `圈选的用户:\n${mentions
.filter((v) => v.id.user_id)
.map((mention: any) => `- ${mention.name}`)
.join("\n")}`
: ""
const content = `群聊:**${chatName}**,功能:**${functionName}**${timeRange}\n\n${mentionsList}\n\n以下内容由AI模型生成耗时**${processingTime}s**`
// 更新消息卡片
await larkService.message.update(
messageId,
cardGender.genCard("resultReport", {
content,
llmRes,
})
)
} catch (error: any) {
logger.error(`LLM error: ${error.message}`)
await larkService.message.update(
messageId,
cardGender.genErrorCard("LLM调用失败: " + error.message)
)
}
}
/**
*
* @param ctx -
* @param innerList -
*/
const parseGroupAgentQuery = async (
ctx: Context.Data,
innerList: LarkServer.ChatGroupData[],
mentions?: LarkEvent.Mention[]
) => {
// TODO处理在群聊里的情况不用获取群组名称
const {
larkBody: { msgText, chatId: rawChatId },
larkService,
larkCard,
logger,
requestId,
} = ctx
const cardGender = larkCard.child("groupAgent")
// 发送一个loading的消息
const {
data: { message_id },
} = await larkService.message.sendCard2Chat(
rawChatId,
cardGender.genPendingCard("分析中,请稍等...")
)
const updateCard = (content: any) =>
larkService.message.update(message_id, content)
// 组织群组数据
const groupInfo = JSON.stringify(
innerList.map((v) => ({
name: v.name,
id: v.chat_id,
}))
)
// 获取功能信息
const functionInfo = JSON.stringify(functionOptionList)
// 使用大模型解析用户输入
const { chatId, chatName, functionName, functionId, startTime, endTime } =
await llm.parseGroupAgentQuery(msgText, groupInfo, functionInfo, requestId)
logger.info(
`Parsed group agent query: chatId: ${chatId}, chatName: ${chatName}, functionName: ${functionName}, functionId: ${functionId}, startTime: ${startTime}, endTime: ${endTime}`
)
// 判断顺序是 群组 -> 功能 -> 时间范围
// 返回群组选择器,其他的值往里边丢就行
if (!chatId || !chatName) {
logger.info("Send group selector")
updateCard(
genGroupSelector(ctx, innerList, {
functionName,
functionId,
startTime,
endTime,
mentions,
})
)
return
}
// 返回功能选择器,其他的值往里边丢就行
if (!functionId || !functionName) {
logger.info("Send function selector")
updateCard(
genFunctionSelector(ctx, {
chatId,
chatName,
startTime,
endTime,
mentions,
})
)
return
}
// 返回时间范围选择器,其他的值往里边丢就行
if (!startTime || !endTime) {
logger.info("Send time scope selector")
updateCard(
genTimeScopeSelector(ctx, {
chatId,
chatName,
functionId,
functionName,
mentions,
})
)
return
}
logger.info("Send group report")
// 设置齐全,返回结果报告
updateCard(cardGender.genPendingCard("正在爬楼中,请稍等..."))
sendGroupReport(ctx, message_id, {
chatId,
chatName,
functionId,
functionName,
startTime,
endTime,
mentions,
})
}
/**
*
* @param ctx -
*/
const manageEventMsg = async (ctx: Context.Data) => {
const {
larkBody: { msgText, chatType, chatId: rawChatId, mentions },
larkService,
logger,
} = ctx
// 获取群组信息
const { data: innerList } = await larkService.chat.getInnerList()
logger.info(`Inner list: ${JSON.stringify(innerList)}`)
const sendCard = (content: string) =>
larkService.message.sendCard2Chat(rawChatId, content)
// 去过去掉所有非必要的信息为空的话
if (msgText.replace("/groupchat", "").replaceAll(" ", "") === "") {
// 私聊发送正常的群组选择器
if (chatType === "p2p") {
logger.info("Send group selector to p2p chat")
await sendCard(genGroupSelector(ctx, innerList, { mentions }))
return
}
// 如果是群聊,获取群聊名称并发送功能
const {
data: { name: chatName },
} = await larkService.chat.getChatInfo(rawChatId)
logger.info(`Send function selector to group chat: ${chatName}`)
await sendCard(genFunctionSelector(ctx, { chatName, mentions }))
return
}
logger.info(`User input: ${msgText}, chatType: ${chatType}, use llm to parse`)
// 用户有输入,使用大模型进行解析发送对应卡片
await parseGroupAgentQuery(ctx, innerList, mentions)
return
}
/**
* Action消息
* @param ctx -
*/
const manageActionMsg = async (ctx: Context.Data) => {
const {
larkBody: { actionOption, actionValue, messageId },
larkCard,
logger,
} = ctx
const cardGender = larkCard.child("groupAgent")
logger.debug(`Action option: ${JSON.stringify(actionOption)}`)
logger.debug(`Action value: ${JSON.stringify(actionValue)}`)
let { chatId, chatName, functionId, functionName } = actionValue
const { timeScope, startTime, endTime, cardName, mentions } = actionValue
// 如果是群组选择器返回值
if (cardName === "groupSelector") {
const [newChatId, newChatName] = (actionOption ?? "").split("|")
if (!newChatId || !newChatName) {
logger.error(
`Invalid targetChatId or targetChatName: ${JSON.stringify(actionOption)}`
)
return cardGender.genErrorCard("Invalid targetChatId or targetChatName")
}
chatId = newChatId
chatName = newChatName
}
// 如果是功能选择器返回值
if (cardName === "functionSelector") {
const [newFunctionId, newFunctionName] = (actionOption ?? "").split("|")
if (!newFunctionId || !newFunctionName) {
logger.error(
`Invalid functionId or functionName: ${JSON.stringify(actionOption)}`
)
return cardGender.genErrorCard("Invalid functionId or functionName")
}
functionId = newFunctionId
functionName = newFunctionName
}
// 时间返回的返回值就会带在timeScope里不需要再处理
// 理论上来说这里的chatId, chatName肯定是有值的不需要再判断
// 判断是否需要返回功能选择器
if (!functionId || !functionName) {
logger.info("Send function selector")
return genFunctionSelector(ctx, {
chatId,
chatName,
startTime,
endTime,
timeScope,
mentions,
})
}
// 判断是否需要返回时间范围选择器
if (!(timeScope || (startTime && endTime))) {
logger.info("Send time scope selector")
return genTimeScopeSelector(ctx, {
chatId,
chatName,
functionId,
functionName,
mentions,
})
}
logger.info("Send group report")
// 设置齐全,返回结果报告
sendGroupReport(ctx, messageId, {
chatId,
chatName,
functionId,
functionName,
timeScope,
startTime,
endTime,
mentions,
})
return cardGender.genPendingCard("正在爬楼中,请稍等...")
}
/**
* Agent的主入口
* @param ctx -
*/
const groupAgent = async (ctx: Context.Data) => {
const {
larkBody: { isEvent, isAction },
logger,
} = ctx
try {
// 如果是Event则解析自然语言并发送对应的卡片
if (isEvent) return await manageEventMsg(ctx)
// 如果是Action则取出用户选的值并判断是否需要继续发送表单卡片或者开始大模型推理
if (isAction) return await manageActionMsg(ctx)
} catch (e: any) {
logger.error(`Group agent error: ${e.message}`)
return ctx.larkCard.child("groupAgent").genErrorCard("Group agent error")
}
const groupAgent = {
manual,
report,
}
export default groupAgent

View File

@ -0,0 +1,412 @@
import { genCardOptions, LarkEvent } from "@egg/lark-msg-tool"
import { functionOptionList } from "../../constant/card"
import { Context, LarkServer } from "../../types"
import llm from "../../utils/llm"
import getChatHistory from "./chatHistory"
/**
*
* @param ctx -
* @param innerList -
* @param commonVal -
*/
const genGroupSelector = (
{ larkCard }: Context.Data,
innerList: LarkServer.ChatGroupData[],
commonVal: Record<string, any> = {}
) => {
const cardGender = larkCard.child("groupAgent")
// 组织群组数据
const groupOptions = genCardOptions(
innerList.reduce(
(acc, item) => {
acc[item.name] = `${item.chat_id}|${item.name}`
return acc
},
{} as Record<string, string>
)
)
return cardGender.genCard("groupSelector", {
groupOptions,
...commonVal,
})
}
/**
*
* @param ctx -
* @param commonVal -
*/
const genFunctionSelector = (
{ larkCard }: Context.Data,
commonVal: Record<string, any> = {}
) => {
const cardGender = larkCard.child("groupAgent")
// 组织功能数据
const functionOptions = genCardOptions(
functionOptionList.reduce(
(acc, item) => {
acc[item.name] = `${item.id}|${item.name}`
return acc
},
{} as Record<string, string>
)
)
return cardGender.genCard("functionSelector", {
functionOptions,
...commonVal,
})
}
/**
*
* @param ctx - body和larkService
*/
const genTimeScopeSelector = (
{ larkCard }: Context.Data,
commonVal: Record<string, any> = {}
) => {
return larkCard.child("groupAgent").genCard("timeScopeSelector", commonVal)
}
const sendGroupReport = async (
ctx: Context.Data,
messageId: string,
{
chatId,
chatName,
functionId,
functionName,
timeScope,
startTime,
endTime,
mentions,
}: {
chatId: string
chatName: string
functionId: string
functionName: string
timeScope?: string
startTime?: string
endTime?: string
mentions?: LarkEvent.Mention[]
}
) => {
const { larkService, logger, larkCard, requestId } = ctx
const cardGender = larkCard.child("groupAgent")
const updateCard = (content: any) =>
larkService.message.update(messageId, content)
// action需要返回loading的消息event需要主动update卡片所以loading就放外边了
// 记录发送loading消息后的时间戳
const processStart = Date.now()
// 获取聊天记录
const chatHistory = await getChatHistory(ctx, {
chatId,
timeScope,
startTime,
endTime,
mentions,
})
// 如果没有历史记录则返回错误消息
if (chatHistory.length === 0) {
logger.error("Chat history is empty")
await updateCard(cardGender.genErrorCard("未找到聊天记录"))
return
}
logger.debug(`Chat history: ${JSON.stringify(chatHistory)}`)
try {
const llmRes = await llm.invoke(
functionId,
{
chatHistory: JSON.stringify(chatHistory),
time: new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" }),
},
requestId
)
// 记录大模型返回结果后的时间戳
const processEnd = Date.now()
// 计算时间差并存储在processingTime变量中以秒为单位
const processingTime = ((processEnd - processStart) / 1000).toFixed(2)
logger.info(`LLM takes time: ${processingTime}s, result: ${llmRes}`)
// 动态生成content内容
const timeRange = timeScope
? `总结天数:**${timeScope}**`
: `时间范围:**${startTime}** 至 **${endTime}**`
const mentionsList = mentions
? `圈选的用户:\n${mentions
.filter((v) => v.id.user_id)
.map((mention: any) => `- ${mention.name}`)
.join("\n")}`
: ""
const content = `群聊:**${chatName}**,功能:**${functionName}**${timeRange}\n\n${mentionsList}\n\n以下内容由AI模型生成耗时**${processingTime}s**`
// 更新消息卡片
await larkService.message.update(
messageId,
cardGender.genCard("resultReport", {
content,
llmRes,
})
)
} catch (error: any) {
logger.error(`LLM error: ${error.message}`)
await larkService.message.update(
messageId,
cardGender.genErrorCard("LLM调用失败: " + error.message)
)
}
}
/**
*
* @param ctx -
* @param innerList -
*/
const parseGroupAgentQuery = async (
ctx: Context.Data,
innerList: LarkServer.ChatGroupData[],
mentions?: LarkEvent.Mention[]
) => {
// TODO处理在群聊里的情况不用获取群组名称
const {
larkBody: { msgText, chatId: rawChatId },
larkService,
larkCard,
logger,
requestId,
} = ctx
const cardGender = larkCard.child("groupAgent")
// 发送一个loading的消息
const {
data: { message_id },
} = await larkService.message.sendCard2Chat(
rawChatId,
cardGender.genPendingCard("分析中,请稍等...")
)
const updateCard = (content: any) =>
larkService.message.update(message_id, content)
// 组织群组数据
const groupInfo = JSON.stringify(
innerList.map((v) => ({
name: v.name,
id: v.chat_id,
}))
)
// 获取功能信息
const functionInfo = JSON.stringify(functionOptionList)
// 使用大模型解析用户输入
const { chatId, chatName, functionName, functionId, startTime, endTime } =
await llm.parseGroupAgentQuery(msgText, groupInfo, functionInfo, requestId)
logger.info(
`Parsed group agent query: chatId: ${chatId}, chatName: ${chatName}, functionName: ${functionName}, functionId: ${functionId}, startTime: ${startTime}, endTime: ${endTime}`
)
// 判断顺序是 群组 -> 功能 -> 时间范围
// 返回群组选择器,其他的值往里边丢就行
if (!chatId || !chatName) {
logger.info("Send group selector")
updateCard(
genGroupSelector(ctx, innerList, {
functionName,
functionId,
startTime,
endTime,
mentions,
})
)
return
}
// 返回功能选择器,其他的值往里边丢就行
if (!functionId || !functionName) {
logger.info("Send function selector")
updateCard(
genFunctionSelector(ctx, {
chatId,
chatName,
startTime,
endTime,
mentions,
})
)
return
}
// 返回时间范围选择器,其他的值往里边丢就行
if (!startTime || !endTime) {
logger.info("Send time scope selector")
updateCard(
genTimeScopeSelector(ctx, {
chatId,
chatName,
functionId,
functionName,
mentions,
})
)
return
}
logger.info("Send group report")
// 设置齐全,返回结果报告
updateCard(cardGender.genPendingCard("正在爬楼中,请稍等..."))
sendGroupReport(ctx, message_id, {
chatId,
chatName,
functionId,
functionName,
startTime,
endTime,
mentions,
})
}
/**
*
* @param ctx -
*/
const manageEventMsg = async (ctx: Context.Data) => {
const {
larkBody: { msgText, chatType, chatId: rawChatId, mentions },
larkService,
logger,
} = ctx
// 获取群组信息
const { data: innerList } = await larkService.chat.getInnerList()
logger.info(`Inner list: ${JSON.stringify(innerList)}`)
const sendCard = (content: string) =>
larkService.message.sendCard2Chat(rawChatId, content)
// 去过去掉所有非必要的信息为空的话
if (msgText.replace("/groupchat", "").replaceAll(" ", "") === "") {
// 私聊发送正常的群组选择器
if (chatType === "p2p") {
logger.info("Send group selector to p2p chat")
await sendCard(genGroupSelector(ctx, innerList, { mentions }))
return
}
// 如果是群聊,获取群聊名称并发送功能
const {
data: { name: chatName },
} = await larkService.chat.getChatInfo(rawChatId)
logger.info(`Send function selector to group chat: ${chatName}`)
await sendCard(genFunctionSelector(ctx, { chatName, mentions }))
return
}
logger.info(`User input: ${msgText}, chatType: ${chatType}, use llm to parse`)
// 用户有输入,使用大模型进行解析发送对应卡片
await parseGroupAgentQuery(ctx, innerList, mentions)
return
}
/**
* Action消息
* @param ctx -
*/
const manageActionMsg = async (ctx: Context.Data) => {
const {
larkBody: { actionOption, actionValue, messageId },
larkCard,
logger,
} = ctx
const cardGender = larkCard.child("groupAgent")
logger.debug(`Action option: ${JSON.stringify(actionOption)}`)
logger.debug(`Action value: ${JSON.stringify(actionValue)}`)
let { chatId, chatName, functionId, functionName } = actionValue
const { timeScope, startTime, endTime, cardName, mentions } = actionValue
// 如果是群组选择器返回值
if (cardName === "groupSelector") {
const [newChatId, newChatName] = (actionOption ?? "").split("|")
if (!newChatId || !newChatName) {
logger.error(
`Invalid targetChatId or targetChatName: ${JSON.stringify(actionOption)}`
)
return cardGender.genErrorCard("Invalid targetChatId or targetChatName")
}
chatId = newChatId
chatName = newChatName
}
// 如果是功能选择器返回值
if (cardName === "functionSelector") {
const [newFunctionId, newFunctionName] = (actionOption ?? "").split("|")
if (!newFunctionId || !newFunctionName) {
logger.error(
`Invalid functionId or functionName: ${JSON.stringify(actionOption)}`
)
return cardGender.genErrorCard("Invalid functionId or functionName")
}
functionId = newFunctionId
functionName = newFunctionName
}
// 时间返回的返回值就会带在timeScope里不需要再处理
// 理论上来说这里的chatId, chatName肯定是有值的不需要再判断
// 判断是否需要返回功能选择器
if (!functionId || !functionName) {
logger.info("Send function selector")
return genFunctionSelector(ctx, {
chatId,
chatName,
startTime,
endTime,
timeScope,
mentions,
})
}
// 判断是否需要返回时间范围选择器
if (!(timeScope || (startTime && endTime))) {
logger.info("Send time scope selector")
return genTimeScopeSelector(ctx, {
chatId,
chatName,
functionId,
functionName,
mentions,
})
}
logger.info("Send group report")
// 设置齐全,返回结果报告
sendGroupReport(ctx, messageId, {
chatId,
chatName,
functionId,
functionName,
timeScope,
startTime,
endTime,
mentions,
})
return cardGender.genPendingCard("正在爬楼中,请稍等...")
}
/**
* Agent的主入口
* @param ctx -
*/
const manual = async (ctx: Context.Data) => {
const {
larkBody: { isEvent, isAction },
logger,
} = ctx
try {
// 如果是Event则解析自然语言并发送对应的卡片
if (isEvent) return await manageEventMsg(ctx)
// 如果是Action则取出用户选的值并判断是否需要继续发送表单卡片或者开始大模型推理
if (isAction) return await manageActionMsg(ctx)
} catch (e: any) {
logger.error(`Group agent error: ${e.message}`)
return ctx.larkCard.child("groupAgent").genErrorCard("Group agent error")
}
}
export default manual

View File

@ -1,6 +1,7 @@
import { LarkService } from "@egg/net-tool"
import { appMap } from "../../constant/appMap"
import { RespMessage } from "../../constant/message"
import prisma from "../../prisma"
import { Context } from "../../types"
import genContext from "../../utils/genContext"
@ -8,27 +9,22 @@ import llm from "../../utils/llm"
import { getTimeRange } from "../../utils/time"
import getChatHistory from "./chatHistory"
interface Subscription {
id: bigint
chat_id: string
robot_id: string
initiator: string
terminator: string
created_at: Date
updated_at: Date
}
/**
*
* @param {Context.Data} ctx -
* @param {string} timeScope -
* @param {Subscription} subscription -
* @param {any} subscription -
* @returns {Promise<void>}
*/
const genReport = async (
ctx: Context.Data,
timeScope: "daily" | "weekly",
subscription: Subscription
subscription: {
id: bigint
chat_id: string
robot_id: string
initiator: string
}
) => {
const { logger, requestId, larkCard } = ctx
const cardGender = larkCard.child("groupAgent")
@ -181,10 +177,122 @@ const gen4Test = async (ctx: Context.Data, timeScope: "daily" | "weekly") => {
}
}
/**
*
* @returns
*/
const subscribe = async ({
app,
larkService,
logger,
larkBody,
larkCard,
}: Context.Data) => {
try {
const cardGender = larkCard.child("groupAgent")
// 判断是否有 chatId 和 userId
if (!larkBody.chatId || !larkBody.userId) {
logger.error(`chatId or userId is empty`)
return
}
// 先查询是否已经存在订阅
const subscription = await prisma.chat_agent_summary_subscription.findFirst(
{
where: {
chat_id: larkBody.chatId,
terminator: "",
},
}
)
// 如果已经存在订阅,则返回已经注册过了
if (subscription) {
logger.info(`chatId: ${larkBody.chatId} has been registered`)
// 发送已经注册过的消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.hasRegistered)
)
return
}
// 注册订阅
await prisma.chat_agent_summary_subscription.create({
data: {
chat_id: larkBody.chatId,
robot_id: app,
initiator: larkBody.userId,
},
})
// 发送成功消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.registerSuccess)
)
} catch (e: any) {
logger.error(`Subscribe error: ${e.message}`)
}
}
/**
*
* @returns
*/
const unsubscribe = async ({
logger,
larkBody,
larkService,
larkCard,
}: Context.Data) => {
try {
const cardGender = larkCard.child("groupAgent")
// 判断是否有 chatId 和 userId
if (!larkBody.chatId || !larkBody.userId) {
logger.error(`chatId or userId is empty`)
return
}
// 查找现有的订阅
const subscription = await prisma.chat_agent_summary_subscription.findFirst(
{
where: {
chat_id: larkBody.chatId,
terminator: "",
},
}
)
// 如果没有找到订阅,则返回错误
if (!subscription) {
logger.info(`chatId: ${larkBody.chatId} has not been registered`)
// 发送已经取消订阅的消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.cancelSuccess)
)
return
}
// 更新订阅,设置终止者和终止时间
await prisma.chat_agent_summary_subscription.update({
where: {
id: subscription.id,
},
data: {
terminator: larkBody.userId,
},
})
// 发送成功消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.cancelSuccess)
)
} catch (e: any) {
logger.error(`Unsubscribe error: ${e.message}`)
}
}
const report = {
genReport,
genAllReport,
gen4Test,
subscribe,
unsubscribe,
}
export default report

View File

@ -1,120 +0,0 @@
import { RespMessage } from "../../constant/message"
import prisma from "../../prisma"
import { Context } from "../../types"
/**
*
* @returns
*/
const subscribe = async ({
app,
larkService,
logger,
larkBody,
larkCard,
}: Context.Data) => {
try {
const cardGender = larkCard.child("groupAgent")
// 判断是否有 chatId 和 userId
if (!larkBody.chatId || !larkBody.userId) {
logger.error(`chatId or userId is empty`)
return
}
// 先查询是否已经存在订阅
const subscription = await prisma.chat_agent_summary_subscription.findFirst(
{
where: {
chat_id: larkBody.chatId,
terminator: "",
},
}
)
// 如果已经存在订阅,则返回已经注册过了
if (subscription) {
logger.info(`chatId: ${larkBody.chatId} has been registered`)
// 发送已经注册过的消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.hasRegistered)
)
return
}
// 注册订阅
await prisma.chat_agent_summary_subscription.create({
data: {
chat_id: larkBody.chatId,
robot_id: app,
initiator: larkBody.userId,
},
})
// 发送成功消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.registerSuccess)
)
} catch (e: any) {
logger.error(`Subscribe error: ${e.message}`)
}
}
/**
*
* @returns
*/
const unsubscribe = async ({
logger,
larkBody,
larkService,
larkCard,
}: Context.Data) => {
try {
const cardGender = larkCard.child("groupAgent")
// 判断是否有 chatId 和 userId
if (!larkBody.chatId || !larkBody.userId) {
logger.error(`chatId or userId is empty`)
return
}
// 查找现有的订阅
const subscription = await prisma.chat_agent_summary_subscription.findFirst(
{
where: {
chat_id: larkBody.chatId,
terminator: "",
},
}
)
// 如果没有找到订阅,则返回错误
if (!subscription) {
logger.info(`chatId: ${larkBody.chatId} has not been registered`)
// 发送已经取消订阅的消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.cancelSuccess)
)
return
}
// 更新订阅,设置终止者和终止时间
await prisma.chat_agent_summary_subscription.update({
where: {
id: subscription.id,
},
data: {
terminator: larkBody.userId,
},
})
// 发送成功消息
await larkService.message.sendCard2Chat(
larkBody.chatId,
cardGender.genSuccessCard(RespMessage.cancelSuccess)
)
} catch (e: any) {
logger.error(`Unsubscribe error: ${e.message}`)
}
}
const subscription = {
subscribe,
unsubscribe,
}
export default subscription

View File

@ -2,7 +2,7 @@ import groupAgent from "../../controller/groupAgent"
import { Context } from "../../types"
const GROUP_MAP = {
groupAgent,
groupAgent: groupAgent.manual,
}
/**

View File

@ -1,7 +1,5 @@
import tempMap from "../../constant/template"
import groupAgent from "../../controller/groupAgent"
import report from "../../controller/groupAgent/report"
import subscription from "../../controller/groupAgent/subscription"
import { Context } from "../../types"
import createKVTemp from "../sheet/createKVTemp"
@ -115,25 +113,25 @@ const manageCMDMsg = (ctx: Context.Data) => {
// 注册群组
if (msgText === "开启日报、周报") {
logger.info(`bot command is register, chatId: ${chatId}`)
subscription.subscribe(ctx)
groupAgent.report.subscribe(ctx)
return
}
// 注销群组
if (msgText === "关闭日报、周报") {
logger.info(`bot command is unregister, chatId: ${chatId}`)
subscription.unsubscribe(ctx)
groupAgent.report.unsubscribe(ctx)
return
}
// 立即发送日简报
if (msgText === "总结日报") {
logger.info(`bot command is summary, chatId: ${chatId}`)
report.gen4Test(ctx, "daily")
groupAgent.report.gen4Test(ctx, "daily")
return
}
// 立即发送周简报
if (msgText === "总结周报") {
logger.info(`bot command is summary, chatId: ${chatId}`)
report.gen4Test(ctx, "weekly")
groupAgent.report.gen4Test(ctx, "weekly")
return
}
}
@ -178,7 +176,7 @@ const manageCMDMsg = (ctx: Context.Data) => {
// 选择群组信息
if (msgText.startsWith("/g")) {
logger.info(`bot command is /groupchat, chatId: ${chatId}`)
groupAgent(ctx)
groupAgent.manual(ctx)
return
}