**此文档用于说明怎么二次开发对接其他对话渠道,现在已支持的渠道: **

  1. WxOpenai: 微信对话开放渠道,需求注册微信对话开放渠道取得token
  2. ChatGPT: ChatGPT,需求取得ChatGPTSessionToken,且该计划有可能已失效,可使用其他计划替换此部分完成代码

对话渠道功能暂未接入vika,现在是硬编码方法,环境变量装备表暂不可用,感兴趣的开发者能够完成后提交代码。具体逻辑如下:

微信应用平台如何对接ChatGPT应用

下面开始撸代码

第一步

在根目录下找到 wechat-openai-qa-bot/index.ts 文件,定位到如下代码是当接收到消息时恳求对话机器人,其中 await wxai(sysConfig, bot, talker, room, message) 和await wxai(sysConfig, bot, talker, undefined, message)是恳求对话渠道的方法,自定义对话渠道时只需求对wxai()进行完成

import { wxai } from './src/plugins/wxai.js'

wxai.js 代码如下

if (room && roomId && !isSelfMsg) {
// 智能问答敞开时履行
if (sysConfig.WX_OPENAI_ONOFF && ((text.indexOf(keyWord) != -1 && sysConfig.AT_AHEAD) || !sysConfig.AT_AHEAD)) {
if (sysConfig.roomWhiteListOpen) {
const isInRoomWhiteList = sysConfig.roomWhiteList.includes(roomId)
if (isInRoomWhiteList) {
log.info('当时群在白名单内,恳求问答...')
await wxai(sysConfig, bot, talker, room, message)
} else {
log.info('当时群不在白名单内,流程结束')
}
}
if (!sysConfig.roomWhiteListOpen) {
log.info('体系未敞开白名单,恳求问答...')
await wxai(sysConfig, bot, talker, room, message)
}
}
// IM服务敞开时履行
if (sysConfig.imOpen && bot.Message.Type.Text === message.type()) {
configData.clientChatEn.clientChatId = talker.id + ' ' + room.id
configData.clientChatEn.clientChatName = talker.name() + '@' + topic
// log.debug(configData)
socket.emit('CLIENT_ON', {
clientChatEn: configData.clientChatEn,
serverChatId: configData.serverChatEn.serverChatId,
})
const data = {
msg: {
contentType: 'text',
content: text,
role: 'client',
avatarUrl: '/static/image/im_server_avatar.png',
},
}
log.info(JSON.stringify(data))
sendMsg(data)
}
}
if ((!room || !room.id) && !isSelfMsg) {
// 智能问答敞开时履行
if (sysConfig.WX_OPENAI_ONOFF && ((text.indexOf(keyWord) != -1 && sysConfig.AT_AHEAD) || !sysConfig.AT_AHEAD)) {
if (sysConfig.contactWhiteListOpen) {
const isInContactWhiteList = sysConfig.contactWhiteList.includes(talker.id)
if (isInContactWhiteList) {
log.info('当时老友在白名单内,恳求问答...')
await wxai(sysConfig, bot, talker, undefined, message)
} else {
log.info('当时老友不在白名单内,流程结束')
}
}
if (!sysConfig.contactWhiteListOpen) {
log.info('体系未敞开老友白名单,对所有老友有用,恳求问答...')
await wxai(sysConfig, bot, talker, undefined, message)
}
}
}
} catch (e) {
log.error('建议恳求wxai失利', e)
}

第二步

在根目录下找到 wechat-openai-qa-bot/src/plugins/wxai.js文件,对callBot和aibot()进行拓宽


let useBot = 0
const callBot = botTpyes[useBot]

let answer = {}
switch (callBot) {
case 'WxOpenai':
// log.info('开始恳求微信对话渠道...')
init({
EncodingAESKey: sysConfig.EncodingAESKey,
TOKEN: sysConfig.WX_TOKEN,
})
const roomid = room?.id
const wxid = talker.id
const nickName = talker.name()
const topic = await room?.topic()
// log.info(opt)
let answerJson
try {
const username = room ? (nickName + '/' + topic) : nickName
const userid = room ? (wxid + '/' + roomid) : wxid
const signature = genToken({
userid,
username,
})
let queryData
if (sysConfig.DIFF_REPLY_ONOFF && room) {
queryData = {
first_priority_skills: [topic || ''],
query,
second_priority_skills: ['通用问题'],
signature,
}
} else {
queryData = {
first_priority_skills: ['通用问题'],
query,
signature,
}
}
const resMsg = await chatAibot(queryData)
// console.debug(resMsg)
log.info('对话返回原始:', resMsg)
// log.info('对话返回:', JSON.stringify(resMsg).replace(/[\r\n]/g, "").replace(/\ +/g, ""))
log.info('回答内容:', resMsg.msgtype, resMsg.query, resMsg.answer)
// console.debug(resMsg.query)
// console.debug(resMsg.answer)
if (resMsg.msgtype && resMsg.confidence > 0.8) {
switch (resMsg.msgtype) {
case 'text':
answer = {
messageType: types.Message.Text,
text: resMsg.answer || resMsg.msg[0].content,
}
break
case 'miniprogrampage':
answerJson = JSON.parse(resMsg.answer)
answer = {
messageType: types.Message.MiniProgram,
text: answerJson.miniprogrampage,
}
break
case 'image':
answerJson = JSON.parse(resMsg.answer)
answer = {
messageType: types.Message.Image,
text: answerJson.image,
}
break
case 'callback':
if (resMsg.answer_type === 'text') {
answer = {
messageType: types.Message.Text,
text: resMsg.answer,
}
}
break
default:
log.info(JSON.stringify({ msg: '没有射中关键字', nickName, query, roomid, topic }))
break
}
if (sysConfig.DIFF_REPLY_ONOFF) {
if (room && (resMsg.skill_name !== topic && resMsg.skill_name !== '通用问题')) {
answer = {}
}
}
}
} catch (err) {
log.error(JSON.stringify(err))
}
break
case 'ChatGPT':
const content = query
try {
const api = new ChatGPTAPI({ sessionToken: config.ChatGPTSessionToken })
// ensure the API is properly authenticated (optional)
await api.ensureAuth()
let t0 = new Date().getTime()
console.log('content: ', content);
// send a message and wait for the response
const response = await api.sendMessage(content)
//TODO: format response to compatible with wechat messages
let t1 = new Date().getTime()
console.log('response: ', response);
console.log('耗时: ', (t1 - t0) / 1000, 's');
// response is a markdown-formatted string
answer = {
messageType: types.Message.Text,
text: response,
}
} catch (err) {
console.error(err)
}
break
default:
console.debug('没有匹配')
break
}
return answer
}