feat: 添加聊天功能支持,更新相关数据模型和配置;优化群组总结逻辑
This commit is contained in:
parent
a31f0fd249
commit
feb0ada324
@ -14,6 +14,7 @@ export interface AppInfoModel extends RecordModel {
|
|||||||
appId: string
|
appId: string
|
||||||
appSecret: string
|
appSecret: string
|
||||||
appName: string
|
appName: string
|
||||||
|
errChatId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const APP_CONFIG: Record<string, string> = {}
|
export const APP_CONFIG: Record<string, string> = {}
|
||||||
|
@ -7,4 +7,5 @@ export enum RespMessage {
|
|||||||
cancelWeeklySuccess = "周报订阅取消成功",
|
cancelWeeklySuccess = "周报订阅取消成功",
|
||||||
registerFailed = "订阅失败",
|
registerFailed = "订阅失败",
|
||||||
cancelFailed = "取消订阅失败",
|
cancelFailed = "取消订阅失败",
|
||||||
|
summaryFailed = "总结失败",
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { LarkService } from "@egg/net-tool"
|
|
||||||
|
|
||||||
import { APP_MAP } from "../../constant/config"
|
|
||||||
import { RespMessage } from "../../constant/message"
|
import { RespMessage } from "../../constant/message"
|
||||||
import db from "../../db"
|
import db from "../../db"
|
||||||
import { GrpSumSubWithApp } from "../../db/grpSumSub"
|
|
||||||
import { Context } from "../../types"
|
import { Context } from "../../types"
|
||||||
import genContext from "../../utils/genContext"
|
import genContext from "../../utils/genContext"
|
||||||
import llm from "../../utils/llm"
|
import llm from "../../utils/llm"
|
||||||
@ -17,26 +13,22 @@ import getChatHistory from "./chatHistory"
|
|||||||
* @param {any} subscription - 订阅信息
|
* @param {any} subscription - 订阅信息
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
const genReport = async (
|
const genSummary = async (
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
timeScope: "daily" | "weekly",
|
timeScope: "daily" | "weekly",
|
||||||
subscription: GrpSumSubWithApp
|
trigger: "auto" | "manual"
|
||||||
) => {
|
) => {
|
||||||
const { logger, requestId, larkCard } = ctx
|
const { logger, requestId, larkCard, larkService, appInfo, larkBody } = ctx
|
||||||
|
logger.info(`genSummary ${timeScope} by ${trigger}`)
|
||||||
const cardGender = larkCard.child("groupAgent")
|
const cardGender = larkCard.child("groupAgent")
|
||||||
try {
|
try {
|
||||||
const {
|
// 获取群聊信息
|
||||||
chatId,
|
const chat = await db.chat.getAndCreate(ctx)
|
||||||
expand: {
|
if (!chat) {
|
||||||
app: { appId, appSecret, appName },
|
throw new Error("Failed to get chat info")
|
||||||
},
|
}
|
||||||
} = subscription
|
const { chatId } = chat
|
||||||
// 组织接口
|
|
||||||
const larkService = new LarkService({
|
|
||||||
appId,
|
|
||||||
appSecret,
|
|
||||||
requestId,
|
|
||||||
})
|
|
||||||
// 获取时间范围
|
// 获取时间范围
|
||||||
const { startTime, endTime } = getTimeRange(timeScope)
|
const { startTime, endTime } = getTimeRange(timeScope)
|
||||||
|
|
||||||
@ -50,9 +42,10 @@ const genReport = async (
|
|||||||
chatId,
|
chatId,
|
||||||
startTime,
|
startTime,
|
||||||
endTime,
|
endTime,
|
||||||
excludeMentions: [appName],
|
excludeMentions: [appInfo.appName],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (chatHistory.length === 0) {
|
if (chatHistory.length === 0) {
|
||||||
logger.info(`No message in chat ${chatId}`)
|
logger.info(`No message in chat ${chatId}`)
|
||||||
return
|
return
|
||||||
@ -69,29 +62,46 @@ const genReport = async (
|
|||||||
},
|
},
|
||||||
requestId
|
requestId
|
||||||
)
|
)
|
||||||
|
|
||||||
// 计时结束
|
// 计时结束
|
||||||
const processEnd = Date.now()
|
const processEnd = Date.now()
|
||||||
const processingTime = ((processEnd - processStart) / 1000).toFixed(2)
|
const processingTime = ((processEnd - processStart) / 1000).toFixed(2)
|
||||||
logger.info(
|
logger.info(
|
||||||
`LLM takes time: ${processingTime}s, see detail: http://langfuse.ai.srv/project/cm1j2tkj9001gukrgdvc1swuw/sessions/${requestId}`
|
`LLM takes time: ${processingTime}s, see detail: http://langfuse.ai.srv/project/cm1j2tkj9001gukrgdvc1swuw/sessions/${requestId}`
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成卡片内容
|
// 生成卡片内容
|
||||||
const cardContent = cardGender.genCard("autoReport", {
|
const cardContent = cardGender.genCard("autoReport", {
|
||||||
llmRes,
|
llmRes,
|
||||||
timeScope: timeScope === "daily" ? "今日日报" : "本周周报",
|
timeScope: timeScope === "daily" ? "今日日报" : "本周周报",
|
||||||
})
|
})
|
||||||
// 发送卡片消息
|
|
||||||
await larkService.message.sendCard2Chat(chatId, cardContent)
|
// 发送卡片消息,手动触发时回复原消息
|
||||||
|
if (trigger === "manual") {
|
||||||
|
await larkService.message.replyCard(larkBody.messageId, cardContent)
|
||||||
|
} else {
|
||||||
|
await larkService.message.sendCard2Chat(chatId, cardContent)
|
||||||
|
}
|
||||||
|
|
||||||
// 记录总结日志
|
// 记录总结日志
|
||||||
await db.grpSumLog.create({
|
await db.grpSumLog.create({
|
||||||
subscription: subscription.id,
|
chat: chat.id,
|
||||||
content: JSON.stringify(cardContent),
|
content: JSON.stringify(cardContent),
|
||||||
langfuseLink: `http://langfuse.ai.srv/project/cm1j2tkj9001gukrgdvc1swuw/sessions/${requestId}`,
|
langfuseLink: `http://langfuse.ai.srv/project/cm1j2tkj9001gukrgdvc1swuw/sessions/${requestId}`,
|
||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error(
|
logger.error(`Failed to summarize chat: ${error.message}`)
|
||||||
`Failed to summarize chat ${subscription.chatId}: ${error.message}`
|
const errorCard = cardGender.genErrorCard(
|
||||||
|
`${RespMessage.summaryFailed}: ${error.message}`
|
||||||
)
|
)
|
||||||
|
// 手动触发时回复原消息
|
||||||
|
if (trigger === "manual") {
|
||||||
|
await larkService.message.replyCard(larkBody.messageId, errorCard)
|
||||||
|
}
|
||||||
|
// 自动触发发送给自己的订阅群
|
||||||
|
else {
|
||||||
|
await larkService.message.sendCard2Chat(appInfo.errChatId, errorCard)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,39 +110,30 @@ const genReport = async (
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
const genAllReport = async (timeScope: "daily" | "weekly" = "daily") => {
|
const genAllReport = async (timeScope: "daily" | "weekly" = "daily") => {
|
||||||
const ctx = await genContext(new Request("https://baidu.com"))
|
const ctx = await genContext(
|
||||||
|
new Request("https://lark-egg-preview.ai.xiaomi.com")
|
||||||
|
)
|
||||||
const { logger } = ctx
|
const { logger } = ctx
|
||||||
|
logger.info(`genAllReport ${timeScope}`)
|
||||||
try {
|
try {
|
||||||
// 获取全部需要自动总结的群组
|
// 获取所有需要自动总结的群组
|
||||||
let subList = await db.grpSumSub.getAll(
|
const chatList = await db.chat.getNeedSummaryChats("all")
|
||||||
`terminator = ""${timeScope === "daily" ? ' && timeScope = "daily"' : ""}`
|
logger.debug(`chatList: ${JSON.stringify(chatList)}`)
|
||||||
)
|
if (!chatList || chatList.length === 0) {
|
||||||
|
logger.info(`No chat need to summarize`)
|
||||||
// 没有需要总结的群组
|
|
||||||
if (!subList || subList.length === 0) {
|
|
||||||
logger.info("No group needs to be summarized")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 总结
|
||||||
// 如果是周五,获取了需要日报和周报的订阅,根据chatId,过滤掉需要周报的日报订阅
|
for (const chat of chatList) {
|
||||||
if (timeScope === "weekly") {
|
const newCtx = await genContext(
|
||||||
const dailySubList = subList.filter((sub) => sub.timeScope === "daily")
|
new Request("https://lark-egg-preview.ai.xiaomi.com")
|
||||||
const weeklySubList = subList.filter((sub) => sub.timeScope === "weekly")
|
)
|
||||||
// 过滤掉需要周报的日报订阅
|
newCtx.larkBody.chatId = chat.chatId
|
||||||
subList = dailySubList
|
let scope = "daily" as "daily" | "weekly"
|
||||||
.filter(
|
if (timeScope === "weekly" && chat.weeklySummary) {
|
||||||
(dailySub) =>
|
scope = "weekly"
|
||||||
!weeklySubList.find(
|
}
|
||||||
(weeklySub) => weeklySub.chatId === dailySub.chatId
|
await genSummary(newCtx, scope, "auto")
|
||||||
)
|
|
||||||
)
|
|
||||||
.concat(weeklySubList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 一个一个群组的总结,避免触发频率限制
|
|
||||||
for (const sub of subList) {
|
|
||||||
await genReport(ctx, sub.timeScope, sub)
|
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
logger.error(`Auto summary error: ${e.message}`)
|
logger.error(`Auto summary error: ${e.message}`)
|
||||||
@ -147,102 +148,57 @@ const genAllReport = async (timeScope: "daily" | "weekly" = "daily") => {
|
|||||||
const gen4Test = async (ctx: Context, timeScope: "daily" | "weekly") => {
|
const gen4Test = async (ctx: Context, timeScope: "daily" | "weekly") => {
|
||||||
const {
|
const {
|
||||||
logger,
|
logger,
|
||||||
larkCard,
|
|
||||||
larkService,
|
|
||||||
larkBody: { chatId },
|
larkBody: { chatId },
|
||||||
} = ctx
|
} = ctx
|
||||||
try {
|
try {
|
||||||
logger.info(`timeScope: ${timeScope}`)
|
logger.info(`timeScope: ${timeScope}`)
|
||||||
// 获取需要总结的chatId
|
|
||||||
if (!chatId) {
|
|
||||||
logger.error("Invalid request body")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取订阅信息
|
|
||||||
const sub = await db.grpSumSub.getByFilter(
|
|
||||||
`terminator = "" && chatId = "${chatId}" && timeScope = "${timeScope}"`
|
|
||||||
)
|
|
||||||
// 没有订阅信息
|
|
||||||
if (!sub) {
|
|
||||||
logger.error(`No subscription found for chat ${chatId}`)
|
|
||||||
await larkService.message.sendCard2Chat(
|
|
||||||
chatId,
|
|
||||||
larkCard.genErrorCard(
|
|
||||||
`本群未订阅${timeScope === "daily" ? "日报" : "周报"}`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 总结
|
// 总结
|
||||||
await genReport(ctx, timeScope, sub)
|
await genSummary(ctx, timeScope, "manual")
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logger.error(`Failed to summarize chat ${chatId}: ${error.message}`)
|
logger.error(`Failed to summarize chat ${chatId}: ${error.message}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册消息总结的订阅
|
* 设置订阅
|
||||||
* @returns
|
* @param {Context} ctx - 请求上下文
|
||||||
|
* @param {string} timeScope - 订阅时间范围
|
||||||
|
* @param {boolean} value - 订阅值
|
||||||
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
const subscribe = async (
|
const setSubscription = async (
|
||||||
{ app, larkService, logger, larkBody, larkCard }: Context,
|
ctx: Context,
|
||||||
timeScope: "daily" | "weekly"
|
timeScope: "daily" | "weekly",
|
||||||
|
value: boolean
|
||||||
) => {
|
) => {
|
||||||
|
const { larkService, logger, larkBody, larkCard } = ctx
|
||||||
const cardGender = larkCard.child("groupAgent")
|
const cardGender = larkCard.child("groupAgent")
|
||||||
const sendErrorMsg = () =>
|
const sendErrorMsg = (message: string) =>
|
||||||
larkService.message.replyCard(
|
larkService.message.replyCard(
|
||||||
larkBody.messageId,
|
larkBody.messageId,
|
||||||
cardGender.genErrorCard(RespMessage.registerFailed)
|
cardGender.genErrorCard(
|
||||||
|
`${
|
||||||
|
value ? RespMessage.registerFailed : RespMessage.cancelFailed
|
||||||
|
}: ${message}`
|
||||||
|
)
|
||||||
)
|
)
|
||||||
try {
|
try {
|
||||||
// 判断是否有 chatId 和 userId
|
const { chatId } = larkBody
|
||||||
if (!larkBody.chatId || !larkBody.userId) {
|
if (!chatId) {
|
||||||
logger.error(`chatId or userId is empty`)
|
throw new Error("Invalid chatId")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
// 获取群组信息
|
||||||
// 获取用户信息
|
const chat = await db.chat.getAndCreate(ctx)
|
||||||
const user = await db.user.getByCtx({ larkBody, larkService } as Context)
|
if (!chat) {
|
||||||
if (!user) {
|
throw new Error("Failed to get chat info")
|
||||||
logger.error(`Failed to get user info`)
|
|
||||||
await sendErrorMsg()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// 先查询是否已经存在订阅
|
// 更新订阅信息, 如果订阅信息没有变化则不更新
|
||||||
const sub = await db.grpSumSub.getByFilter(
|
if (chat[`${timeScope}Summary`] !== value) {
|
||||||
`terminator = "" && chatId = "${larkBody.chatId} && timeScope = "${timeScope}"`
|
logger.info("value is different, update subscription")
|
||||||
)
|
const res = await db.chat.updateSummary(chat.id, timeScope, value)
|
||||||
if (sub) {
|
if (!res) {
|
||||||
logger.info(
|
throw new Error("Failed to update subscription")
|
||||||
`chatId: ${larkBody.chatId} has been registered, timeScope: ${timeScope}`
|
}
|
||||||
)
|
|
||||||
// 发送已经注册过了的消息
|
|
||||||
await larkService.message.replyCard(
|
|
||||||
larkBody.messageId,
|
|
||||||
cardGender.genSuccessCard(
|
|
||||||
timeScope === "daily"
|
|
||||||
? RespMessage.hasRegisteredDaily
|
|
||||||
: RespMessage.hasRegisteredWeekly
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 注册订阅
|
|
||||||
const createRes = await db.grpSumSub.create({
|
|
||||||
app: APP_MAP[app].id,
|
|
||||||
initiator: user.id,
|
|
||||||
terminator: "",
|
|
||||||
chatId: larkBody.chatId,
|
|
||||||
timeScope,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!createRes) {
|
|
||||||
logger.error(
|
|
||||||
`Failed to register chatId: ${larkBody.chatId}, timeScope: ${timeScope}`
|
|
||||||
)
|
|
||||||
await sendErrorMsg()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// 发送成功消息
|
// 发送成功消息
|
||||||
await larkService.message.replyCard(
|
await larkService.message.replyCard(
|
||||||
@ -255,92 +211,15 @@ const subscribe = async (
|
|||||||
)
|
)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
logger.error(`Subscribe error: ${e.message}`)
|
logger.error(`Subscribe error: ${e.message}`)
|
||||||
await sendErrorMsg()
|
await sendErrorMsg(e.message)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消消息总结的订阅
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const unsubscribe = async (
|
|
||||||
{ logger, larkBody, larkService, larkCard }: Context,
|
|
||||||
timeScope: "daily" | "weekly"
|
|
||||||
) => {
|
|
||||||
const cardGender = larkCard.child("groupAgent")
|
|
||||||
const sendErrorMsg = () =>
|
|
||||||
larkService.message.replyCard(
|
|
||||||
larkBody.messageId,
|
|
||||||
cardGender.genErrorCard(RespMessage.cancelFailed)
|
|
||||||
)
|
|
||||||
try {
|
|
||||||
// 判断是否有 chatId 和 userId
|
|
||||||
if (!larkBody.chatId || !larkBody.userId) {
|
|
||||||
logger.error(`chatId or userId is empty`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取用户信息
|
|
||||||
const user = await db.user.getByCtx({ larkBody, larkService } as Context)
|
|
||||||
if (!user) {
|
|
||||||
logger.error(`Failed to get user info`)
|
|
||||||
await sendErrorMsg()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 先查询是否已经存在订阅
|
|
||||||
const sub = await db.grpSumSub.getByFilter(
|
|
||||||
`terminator = "" && chatId = "${larkBody.chatId} && timeScope = "${timeScope}"`
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!sub) {
|
|
||||||
logger.info(
|
|
||||||
`chatId: ${larkBody.chatId} has not been registered, timeScope: ${timeScope}`
|
|
||||||
)
|
|
||||||
// 发送未注册的消息
|
|
||||||
await larkService.message.replyCard(
|
|
||||||
larkBody.messageId,
|
|
||||||
cardGender.genSuccessCard(
|
|
||||||
timeScope === "daily"
|
|
||||||
? RespMessage.cancelDailySuccess
|
|
||||||
: RespMessage.cancelWeeklySuccess
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 更新订阅
|
|
||||||
const updateRes = await db.grpSumSub.update(sub.id, {
|
|
||||||
terminator: user.id,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!updateRes) {
|
|
||||||
logger.error(
|
|
||||||
`Failed to cancel chatId: ${larkBody.chatId}, timeScope: ${timeScope}`
|
|
||||||
)
|
|
||||||
await sendErrorMsg()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发送成功消息
|
|
||||||
await larkService.message.replyCard(
|
|
||||||
larkBody.messageId,
|
|
||||||
cardGender.genSuccessCard(
|
|
||||||
timeScope === "daily"
|
|
||||||
? RespMessage.cancelDailySuccess
|
|
||||||
: RespMessage.cancelWeeklySuccess
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} catch (e: any) {
|
|
||||||
logger.error(`Unsubscribe error: ${e.message}`)
|
|
||||||
await sendErrorMsg()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const report = {
|
const report = {
|
||||||
genReport,
|
genSummary,
|
||||||
genAllReport,
|
genAllReport,
|
||||||
gen4Test,
|
gen4Test,
|
||||||
subscribe,
|
setSubscription,
|
||||||
unsubscribe,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default report
|
export default report
|
||||||
|
106
db/chat/index.ts
Normal file
106
db/chat/index.ts
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import { RecordModel } from "pocketbase"
|
||||||
|
|
||||||
|
import { Context } from "../../types"
|
||||||
|
import { managePbError } from "../../utils/pbTools"
|
||||||
|
import pbClient from "../pbClient"
|
||||||
|
|
||||||
|
const DB_NAME = "chat"
|
||||||
|
|
||||||
|
export interface Chat {
|
||||||
|
chatId: string
|
||||||
|
name: string
|
||||||
|
avatar: string
|
||||||
|
mode: "group" | "p2p" | "topic"
|
||||||
|
weeklySummary: boolean
|
||||||
|
dailySummary: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ChatModel = Chat & RecordModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个群组信息
|
||||||
|
* @param id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const getOneByChatId = (chatId: string) =>
|
||||||
|
managePbError<ChatModel>(() =>
|
||||||
|
pbClient.collection(DB_NAME).getFirstListItem(`chatId = "${chatId}"`)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建群组
|
||||||
|
* @param chat
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const create = (chat: Chat) =>
|
||||||
|
managePbError<ChatModel>(() => pbClient.collection(DB_NAME).create(chat))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取并创建群组
|
||||||
|
* @param chatId
|
||||||
|
* @param context
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const getAndCreate = async ({ larkService, logger, larkBody }: Context) => {
|
||||||
|
const { chatId } = larkBody
|
||||||
|
if (!chatId) {
|
||||||
|
logger.error(`chatId is empty`)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const chat = await getOneByChatId(chatId)
|
||||||
|
if (chat) return chat
|
||||||
|
logger.info(`chat ${chatId} not found, try to get from lark`)
|
||||||
|
const chatInfo = await larkService.chat.getChatInfo(chatId)
|
||||||
|
if (!chatInfo || chatInfo.code !== 0) return null
|
||||||
|
const { name, avatar, chat_mode } = chatInfo.data
|
||||||
|
const newChat = {
|
||||||
|
chatId,
|
||||||
|
name,
|
||||||
|
avatar,
|
||||||
|
mode: chat_mode,
|
||||||
|
weeklySummary: false,
|
||||||
|
dailySummary: false,
|
||||||
|
}
|
||||||
|
return create(newChat)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新群组总结
|
||||||
|
* @param id
|
||||||
|
* @param timeScope
|
||||||
|
* @param value
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const updateSummary = async (
|
||||||
|
id: string,
|
||||||
|
timeScope: "daily" | "weekly",
|
||||||
|
value: boolean
|
||||||
|
) =>
|
||||||
|
managePbError<ChatModel>(() =>
|
||||||
|
pbClient.collection(DB_NAME).update(id, { [`${timeScope}Summary`]: value })
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取需要总结的群组
|
||||||
|
* @param timeScope
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const getNeedSummaryChats = async (timeScope: "daily" | "weekly" | "all") => {
|
||||||
|
const filterMap = {
|
||||||
|
daily: "dailySummary = true",
|
||||||
|
weekly: "weeklySummary = true",
|
||||||
|
all: "dailySummary = true && weeklySummary = true",
|
||||||
|
}
|
||||||
|
return managePbError<ChatModel[]>(() =>
|
||||||
|
pbClient.collection(DB_NAME).getFullList({ filter: filterMap[timeScope] })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const chat = {
|
||||||
|
getAndCreate,
|
||||||
|
getOneByChatId,
|
||||||
|
updateSummary,
|
||||||
|
getNeedSummaryChats,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default chat
|
@ -3,10 +3,10 @@ import { RecordModel } from "pocketbase"
|
|||||||
import { managePbError } from "../../utils/pbTools"
|
import { managePbError } from "../../utils/pbTools"
|
||||||
import pbClient from "../pbClient"
|
import pbClient from "../pbClient"
|
||||||
|
|
||||||
const DB_NAME = "groupSummaryLog"
|
const DB_NAME = "grpSumLog"
|
||||||
|
|
||||||
export interface GroupSummaryLog {
|
export interface GroupSummaryLog {
|
||||||
subscription: string
|
chat: string
|
||||||
content: string
|
content: string
|
||||||
langfuseLink: string
|
langfuseLink: string
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
import { RecordModel } from "pocketbase"
|
|
||||||
|
|
||||||
import { AppInfoModel } from "../../constant/config"
|
|
||||||
import { managePbError } from "../../utils/pbTools"
|
|
||||||
import pbClient from "../pbClient"
|
|
||||||
|
|
||||||
const DB_NAME = "groupSummarySubscription"
|
|
||||||
|
|
||||||
export interface GroupSummarySubscription {
|
|
||||||
app: string
|
|
||||||
initiator: string
|
|
||||||
terminator: string
|
|
||||||
chatId: string
|
|
||||||
timeScope: "daily" | "weekly"
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GroupSummarySubscriptionModel = GroupSummarySubscription &
|
|
||||||
RecordModel
|
|
||||||
|
|
||||||
export interface GrpSumSubWithApp extends GroupSummarySubscriptionModel {
|
|
||||||
expand: {
|
|
||||||
app: AppInfoModel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const create = async (subscription: GroupSummarySubscription) =>
|
|
||||||
managePbError<GroupSummarySubscriptionModel>(() =>
|
|
||||||
pbClient.collection(DB_NAME).create(subscription)
|
|
||||||
)
|
|
||||||
|
|
||||||
const update = async (
|
|
||||||
id: string,
|
|
||||||
subscription: Partial<GroupSummarySubscription>
|
|
||||||
) =>
|
|
||||||
managePbError<GroupSummarySubscriptionModel>(() =>
|
|
||||||
pbClient.collection(DB_NAME).update(id, subscription)
|
|
||||||
)
|
|
||||||
|
|
||||||
const getAll = async (filter: string = "") =>
|
|
||||||
managePbError<GrpSumSubWithApp[]>(() =>
|
|
||||||
pbClient.collection(DB_NAME).getFullList({
|
|
||||||
filter,
|
|
||||||
expand: "app",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
const getByFilter = async (filter: string) =>
|
|
||||||
managePbError<GrpSumSubWithApp>(() =>
|
|
||||||
pbClient.collection(DB_NAME).getFirstListItem(filter, { expand: "app" })
|
|
||||||
)
|
|
||||||
|
|
||||||
const grpSumSub = {
|
|
||||||
create,
|
|
||||||
update,
|
|
||||||
getAll,
|
|
||||||
getByFilter,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default grpSumSub
|
|
@ -1,18 +1,18 @@
|
|||||||
import apiKey from "./apiKey"
|
import apiKey from "./apiKey"
|
||||||
|
import chat from "./chat"
|
||||||
import gitlabProject from "./gitlabProject/index."
|
import gitlabProject from "./gitlabProject/index."
|
||||||
import grpSumLog from "./grpSumLog"
|
import grpSumLog from "./grpSumLog"
|
||||||
import grpSumSub from "./grpSumSub"
|
|
||||||
import log from "./log"
|
import log from "./log"
|
||||||
import receiveGroup from "./receiveGroup"
|
import receiveGroup from "./receiveGroup"
|
||||||
import user from "./user"
|
import user from "./user"
|
||||||
|
|
||||||
const db = {
|
const db = {
|
||||||
|
chat,
|
||||||
apiKey,
|
apiKey,
|
||||||
receiveGroup,
|
receiveGroup,
|
||||||
log,
|
log,
|
||||||
user,
|
user,
|
||||||
grpSumLog,
|
grpSumLog,
|
||||||
grpSumSub,
|
|
||||||
gitlabProject,
|
gitlabProject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
package.json
10
package.json
@ -19,11 +19,11 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^19.6.1",
|
"@commitlint/cli": "^19.6.1",
|
||||||
"@commitlint/config-conventional": "^19.6.0",
|
"@commitlint/config-conventional": "^19.6.0",
|
||||||
"@eslint/js": "^9.17.0",
|
"@eslint/js": "^9.18.0",
|
||||||
"@types/node-schedule": "^2.1.7",
|
"@types/node-schedule": "^2.1.7",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"bun-types": "^1.1.43",
|
"bun-types": "^1.1.43",
|
||||||
"eslint": "^9.17.0",
|
"eslint": "^9.18.0",
|
||||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||||
"eslint-plugin-unused-imports": "^4.1.4",
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
@ -39,11 +39,11 @@
|
|||||||
"@egg/hooks": "^1.2.0",
|
"@egg/hooks": "^1.2.0",
|
||||||
"@egg/lark-msg-tool": "^1.21.0",
|
"@egg/lark-msg-tool": "^1.21.0",
|
||||||
"@egg/logger": "^1.6.0",
|
"@egg/logger": "^1.6.0",
|
||||||
"@egg/net-tool": "^1.21.0",
|
"@egg/net-tool": "^1.22.0",
|
||||||
"@egg/path-tool": "^1.4.1",
|
"@egg/path-tool": "^1.4.1",
|
||||||
"@langchain/core": "^0.3.27",
|
"@langchain/core": "^0.3.29",
|
||||||
"@langchain/langgraph": "^0.2.39",
|
"@langchain/langgraph": "^0.2.39",
|
||||||
"@langchain/openai": "^0.3.16",
|
"@langchain/openai": "^0.3.17",
|
||||||
"joi": "^17.13.3",
|
"joi": "^17.13.3",
|
||||||
"langfuse-langchain": "^3.32.0",
|
"langfuse-langchain": "^3.32.0",
|
||||||
"node-schedule": "^2.1.1",
|
"node-schedule": "^2.1.1",
|
||||||
|
@ -185,7 +185,7 @@ const manageCMDMsg = async (ctx: Context) => {
|
|||||||
logger.info(
|
logger.info(
|
||||||
`bot command is register, chatId: ${chatId}, timeScope: daily`
|
`bot command is register, chatId: ${chatId}, timeScope: daily`
|
||||||
)
|
)
|
||||||
groupAgent.report.subscribe(ctx, "daily")
|
groupAgent.report.setSubscription(ctx, "daily", true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 注册群组周报
|
// 注册群组周报
|
||||||
@ -193,7 +193,7 @@ const manageCMDMsg = async (ctx: Context) => {
|
|||||||
logger.info(
|
logger.info(
|
||||||
`bot command is register, chatId: ${chatId}, timeScope: weekly`
|
`bot command is register, chatId: ${chatId}, timeScope: weekly`
|
||||||
)
|
)
|
||||||
groupAgent.report.subscribe(ctx, "weekly")
|
groupAgent.report.setSubscription(ctx, "weekly", true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ const manageCMDMsg = async (ctx: Context) => {
|
|||||||
logger.info(
|
logger.info(
|
||||||
`bot command is unregister, chatId: ${chatId}, timeScope: daily`
|
`bot command is unregister, chatId: ${chatId}, timeScope: daily`
|
||||||
)
|
)
|
||||||
groupAgent.report.unsubscribe(ctx, "daily")
|
groupAgent.report.setSubscription(ctx, "daily", false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 注销群组周报
|
// 注销群组周报
|
||||||
@ -210,7 +210,7 @@ const manageCMDMsg = async (ctx: Context) => {
|
|||||||
logger.info(
|
logger.info(
|
||||||
`bot command is unregister, chatId: ${chatId}, timeScope: weekly`
|
`bot command is unregister, chatId: ${chatId}, timeScope: weekly`
|
||||||
)
|
)
|
||||||
groupAgent.report.unsubscribe(ctx, "weekly")
|
groupAgent.report.setSubscription(ctx, "weekly", false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 立即发送日简报
|
// 立即发送日简报
|
||||||
|
Loading…
x
Reference in New Issue
Block a user