import PuppetMini from '../puppet-mini.js' import type { MiniMessagePayload } from '../help/struct.js' import { getUserInfo, aesEncrypt } from './service.js' import { log } from '../config.js' import * as PUPPET from '@juzi/wechaty-puppet' import Hashids from 'hashids' import ChatHistory from './mongo/chatHistory.js' import Feedback from './mongo/feedback.js' import { saveMessage, saveFeedback, getMessage, updateMessage } from './mongo/service.js' import type { HistoryMessage } from './mongo/service.js' async function parseMessage (ctx: any) { log.info('parseMessage', JSON.stringify(ctx.request.body)) if (ctx.request.body.type === PUPPET.types.Message.Image) { log.verbose('not support type') } // 先获取缓存token 的用户数据,获取到直接用 const userId = await PuppetMini.cacheManager.getUserToken(ctx.request.body.talkerToken) if (userId) { const userInfo = await PuppetMini.cacheManager.getContact(userId) if (userInfo) { const message: MiniMessagePayload = { id: ctx.request.body.id, listenerId: PuppetMini.chatbotId, talkerAvatar: userInfo.avatar, talkerId: userInfo.id, talkerName: userInfo.name, text: ctx.request.body.text, timestamp: ctx.request.body.timestamp, type: ctx.request.body.type, } void saveMessage({ botId: PuppetMini.chatbotId, buttons: [], content: '', conversionId: userInfo.id, goods: [], isBot: false, msgId: ctx.request.body.id, position: 'right', text: ctx.request.body.text, timestamp: ctx.request.body.timestamp, title: '', type: 'text', }) await PuppetMini.cacheManager.setMessage(message.id, message) PuppetMini.instance.emit('message', { messageId: message.id }) ctx.response.body = { code: 0, data: { msgId: message.id, }, message: '', } return } } // 缓存里token 对应的用户不存在再实时获取用户信息,并设置到用户信息中 const info = await getUserInfo(ctx.request.body.talkerToken) if (info) { const message: MiniMessagePayload = { id: ctx.request.body.id, listenerId: PuppetMini.chatbotId, talkerAvatar: info.appHeadUrl, talkerId: info.mobile, talkerName: info.appName, text: ctx.request.body.text, timestamp: ctx.request.body.timestamp, type: ctx.request.body.type, } await PuppetMini.cacheManager.setUserToken(ctx.request.body.talkerToken, info.mobile) void saveMessage({ botId: PuppetMini.chatbotId, buttons: [], content: '', conversionId: info.mobile, goods: [], isBot: false, msgId: ctx.request.body.id, position: 'right', text: ctx.request.body.text, timestamp: ctx.request.body.timestamp, title: '', type: 'text', }) await PuppetMini.cacheManager.setMessage(message.id, message) const hashids = new Hashids(PuppetMini.serviceSalt) await PuppetMini.cacheManager.setContact(info.mobile, { alias: info.customerId, avatar: info.appHeadUrl || '', hashId: hashids.encode(info.mobile.toString().split('')), id: info.mobile || '', name: info.appName, phone: info.mobile, }) PuppetMini.instance.emit('message', { messageId: message.id }) ctx.response.body = { code: 0, data: { msgId: message.id, }, message: '', } return } ctx.response.body = { code: 403, data: null, message: 'token失效或验证失败', } } async function initChat (ctx: any) { log.silly('initChat', JSON.stringify(ctx.request.body)) const info = await getUserInfo(ctx.request.body.token) if (info) { const hashids = new Hashids(PuppetMini.serviceSalt) const contactInfo = { alias: info.customerId, avatar: info.appHeadUrl || '', hashId: hashids.encode(info.mobile.toString().split('')), id: info.mobile || '', name: info.appName, phone: info.mobile, } await PuppetMini.cacheManager.setUserToken(ctx.request.body.token, contactInfo.id) await PuppetMini.cacheManager.setContact(contactInfo.id, contactInfo) // const jsConfig = await getJsConfig(ctx.request.body.url) const connectInfo = { // jsConfig, mqName: PuppetMini.mqttName, mqPd: PuppetMini.mqttPd, mqPort: PuppetMini.mqttPort, mqUrl: PuppetMini.mqttHost, userId: contactInfo.hashId, } ctx.response.body = { code: 0, data: aesEncrypt(connectInfo), message: '', } return } ctx.response.body = { code: 403, data: null, message: 'token失效或验证失败', } } async function parseFile (ctx: any) { log.info('parseFileMessage', JSON.stringify(ctx.request.body)) const messageId = ctx.params.messageId const file = await PuppetMini.cacheManager.getFile(messageId) const buffer = await file?.toBuffer() ctx.set('Content-Type', file?.mediaType) ctx.set('Content-Disposition', 'attachment; filename=' + encodeURIComponent(ctx.params.fileName)) ctx.set('Access-Control-Expose-Headers', 'Content-Disposition') ctx.body = buffer } async function getChatHistory (ctx: any) { let userId = await PuppetMini.cacheManager.getUserToken(ctx.request.body.conversationId) if (!userId) { // 缓存里token 对应的用户不存在再实时获取用户信息,并设置到用户信息中 const info = await getUserInfo(ctx.request.body.conversationId) if (info) { await PuppetMini.cacheManager.setUserToken(ctx.request.body.token, info.mobile) userId = info.mobile || '' // @ts-ignore const res = await ChatHistory.getConversationList({ botId: PuppetMini.chatbotId, conversionId: userId, limit: ctx.request.body.pageSize, page: ctx.request.body.page, }) ctx.response.body = { code: 0, data: res, message: '', } return } ctx.response.body = { code: 403, data: null, message: 'token失效或验证失败', } return } // @ts-ignore const res = await ChatHistory.getConversationList({ botId: PuppetMini.chatbotId, conversionId: userId, limit: ctx.request.body.pageSize, page: ctx.request.body.page, }) ctx.response.body = { code: 0, data: res, message: '', } } async function getSimpleChatHistory (ctx: any) { if (ctx.request.body.key !== PuppetMini.feedPageKey) { ctx.response.body = { code: 403, data: null, message: '验证失败', } return } // @ts-ignore const res = await ChatHistory.getConversationList({ botId: PuppetMini.chatbotId, conversionId: ctx.request.body.conversationId, limit: ctx.request.body.pageSize, page: ctx.request.body.page, }) ctx.response.body = { code: 0, data: res, message: '', } } async function feedback (ctx: any) { const { msgId, like, unlike, unlikeReason } = ctx.request.body const message: HistoryMessage | null = await getMessage(msgId) const commonMessage = message ? { answer: message.text || message.content || message.title || message.fileUrl, botId: message.botId, buttons: message.buttons, content: message.content, conversionId: message.conversionId, fileUrl: message.fileUrl, goods: message.goods, isBot: message.isBot, mediaType: message.mediaType, msgId: message.msgId, position: message.position, quoteId: message.quoteId, text: message.text, timestamp: message.timestamp, title: message.title, type: message.type, } : {} if (message?.quoteId) { const questionMessage = await getMessage(message.quoteId) if (questionMessage) { let question = questionMessage.text if (questionMessage.type === 'goodsCard' || questionMessage.type === 'textCard') { question = questionMessage.content } await updateMessage(message.msgId, { like, unlike, unlikeReason, }) // @ts-ignore await saveFeedback({ ...commonMessage, like, question, unlike, unlikeReason, }) ctx.response.body = { code: 0, data: {}, message: '', } return } } if (message) { await updateMessage(message.msgId, { like, unlike, unlikeReason, }) // @ts-ignore await saveFeedback({ ...commonMessage, like, question: '', unlike, unlikeReason, }) ctx.response.body = { code: 0, data: {}, message: '', } return } ctx.response.body = { code: 404, data: {}, message: '反馈失败,请稍后重试', } } async function getFeedbackList (ctx: any) { if (ctx.request.body.key !== PuppetMini.feedPageKey) { ctx.response.body = { code: 403, data: null, message: '验证失败', } return } // @ts-ignore const res = await Feedback.getFeedbackList({ botId: PuppetMini.chatbotId, limit: ctx.request.body.pageSize, page: ctx.request.body.page, }) ctx.response.body = { code: 0, data: res, message: '', } } async function getFeedbackAll (ctx: any) { if (ctx.request.body.key !== PuppetMini.feedPageKey) { ctx.response.body = { code: 403, data: null, message: '验证失败', } return } // @ts-ignore const res = await Feedback.find({ botId: PuppetMini.chatbotId }) ctx.response.body = { code: 0, data: res, message: '', } } async function getChatAnswer (ctx: any) { let userId = await PuppetMini.cacheManager.getUserToken(ctx.request.body.conversationId) if (!userId) { // 缓存里token 对应的用户不存在再实时获取用户信息,并设置到用户信息中 const info = await getUserInfo(ctx.request.body.conversationId) if (info) { await PuppetMini.cacheManager.setUserToken(ctx.request.body.token, info.mobile) userId = info.mobile || '' // @ts-ignore const res = await ChatHistory.getAnswerByMsgId({ botId: PuppetMini.chatbotId, conversionId: userId, msgId: ctx.request.body.msgId, }) ctx.response.body = { code: 0, data: res.list, message: '', } return } ctx.response.body = { code: 403, data: null, message: 'token失效或验证失败', } return } // @ts-ignore const res = await ChatHistory.getAnswerByMsgId({ botId: PuppetMini.chatbotId, conversionId: userId, msgId: ctx.request.body.msgId, }) ctx.response.body = { code: 0, data: res.list, message: '', } } export { parseMessage, initChat, parseFile, getChatHistory, feedback, getFeedbackList, getFeedbackAll, getSimpleChatHistory, getChatAnswer }