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

1,051 阅读2分钟

**此文档用于说明如何二次开发对接其他对话平台,目前已支持的平台: **

  1. WxOpenai: 微信对话开放平台,需要注册微信对话开放平台获得token
  2. ChatGPT: ChatGPT,需要获得ChatGPTSessionToken,且该方案有可能已失效,可使用其他方案替换此部分实现代码

对话平台功能暂未接入vika,目前是硬编码方式,环境变量配置表暂不可用,感兴趣的开发者可以实现后提交代码。具体逻辑如下:

image.png

下面开始撸代码

第一步

在根目录下找到 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

  


}