Browse Source

增加对讯飞星火的支持

Pchen. 1 year ago
parent
commit
9f57e0d637

+ 4 - 6
wechat/ChatGPT.js → API/ChatGPT.js

@@ -1,5 +1,4 @@
 const axios = require('axios')
-const config = require('../config') 
 const sqlite3 = require('sqlite3')
 
 //sqlite数据库路径
@@ -9,7 +8,7 @@ var db = new sqlite3.Database(sqliteDbPath)
 
 function getConfigValue(configName) {
     return new Promise((resolve, reject) => {
-        const query = 'SELECT value FROM apiconfig WHERE config = ?';
+        const query = 'SELECT value FROM gptconfig WHERE config = ?';
         db.get(query, [configName], (err, row) => {
             if (err) {
                 reject(err);
@@ -28,7 +27,6 @@ async function loadConfigValues() {
         apiKey = await getConfigValue('apiKey')
         apiUrl = await getConfigValue('apiUrl')
         app_code = await getConfigValue('app_code')
-        suffix = await getConfigValue('suffix')
         model = await getConfigValue('model')
     } catch (error) {
         console.error('加载api接口设置失败!', error)
@@ -39,7 +37,7 @@ async function loadConfigValues() {
 loadConfigValues()
 
 
-async function sendMessageToAPI(message) {
+async function getGPTMessage(message) {
     const requestData = {
         app_code: app_code,
         messages: [{ "role": "user", "content": message }],
@@ -65,7 +63,7 @@ async function sendMessageToAPI(message) {
 
 // 更新api设置到数据库
 function updateGPTConfig(configName, configValue) {
-    const query = 'REPLACE INTO apiconfig (config, value) VALUES (?, ?)';
+    const query = 'REPLACE INTO gptconfig (config, value) VALUES (?, ?)';
     db.run(query, [configName, configValue], (err) => {
         if (err) {
             console.error('更新数据失败:', err);
@@ -74,4 +72,4 @@ function updateGPTConfig(configName, configValue) {
     })
 }
 
-module.exports = { updateGPTConfig, sendMessageToAPI }
+module.exports = { updateGPTConfig, getGPTMessage }

+ 136 - 0
API/xunfei.js

@@ -0,0 +1,136 @@
+const crypto = require('crypto')
+const ws = require("ws")
+const sqlite3 = require('sqlite3')
+
+//sqlite数据库路径
+let sqliteDbPath = "./db/data.db"
+//打开数据库
+var db = new sqlite3.Database(sqliteDbPath)
+
+function getConfigValue(configName) {
+    return new Promise((resolve, reject) => {
+        const query = 'SELECT value FROM xfconfig WHERE config = ?'
+        db.get(query, [configName], (err, row) => {
+            if (err) {
+                reject(err)
+            } else {
+                const configValue = row ? row.value : null
+                // 处理字符串 'null',如果是 'null' 则返回 null
+                resolve(configValue === 'null' ? null : configValue)
+            }
+        })
+    })
+}
+
+// 读取配置信息并设置相应的变量
+async function loadConfigValues() {
+    try {
+        url = await getConfigValue('apiUrl')
+        APIKey = await getConfigValue('APIKey')
+        APISecret = await getConfigValue('APISecret')
+        app_id = await getConfigValue('app_id')
+        temperatureStr = await getConfigValue('temperature')
+        maxTokensStr = await getConfigValue('max_tokens')
+        domain = await getConfigValue('domain')
+        temperature = parseFloat(temperatureStr)
+        max_tokens = parseInt(maxTokensStr)
+    } catch (error) {
+        console.error('加载讯飞接口设置失败!', error)
+    }
+}
+
+// 调用函数加载配置信息
+(async () => {
+    try {
+        await loadConfigValues();
+    } catch (error) {
+        console.error('加载讯飞接口设置失败!', error);
+    }
+})()
+
+async function getXunfeiMessage(message) {
+
+    const dateString = new Date().toGMTString()
+    const parsedUrl = new URL(url)
+
+    const host = parsedUrl.hostname
+    const path = parsedUrl.pathname
+
+    let tmp = `host: ${host}
+date: ${dateString}
+GET ${path} HTTP/1.1`
+
+    let signature = crypto.createHmac('sha256', APISecret)
+        .update(tmp)
+        .digest('base64')
+
+    const authorization_origin =
+        `api_key="${APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="${signature}"`
+
+    let buff = Buffer.from(authorization_origin)
+    const authorization = buff.toString('base64')
+    const signUrl =
+        `wss://${host}${path}?authorization=${authorization}&date=${encodeURIComponent(dateString)}&host=${host}`
+
+    return new Promise((resolve, reject) => {
+        
+    const sock = new ws(signUrl)
+
+        sock.on("open", function () {
+            sock.send(JSON.stringify({
+                "header": {
+                    "app_id": app_id,
+                },
+                "parameter": {
+                    "chat": {
+                        "domain": domain,
+                        "temperature": temperature,
+                        "max_tokens": max_tokens,
+                    }
+                },
+                "payload": {
+                    "message": {
+                        "text": [{
+                            "role": "user",
+                            "content": message
+                        },]
+                    }
+                }
+            }))
+        })
+
+        console.log(domain,temperature)
+        let apiMessage = ''
+
+        sock.on("error", function (err) {
+            reject(err)
+        })
+
+        sock.on("close", function () {
+            resolve(apiMessage)
+        })
+
+        sock.on("message", function (data) {
+            let recMessage = JSON.parse(data.toString())
+
+            if (recMessage.payload && recMessage.payload.choices && recMessage.payload.choices.text) {
+                apiMessage += recMessage.payload.choices.text[0].content
+            } else {
+                console.log("无法识别的消息",recMessage)
+            }
+        })
+    })
+}
+
+// 更新api设置到数据库
+function updateXunfeiConfig(configName, configValue) {
+    const query = 'REPLACE INTO xfconfig (config, value) VALUES (?, ?)'
+    db.run(query, [configName, configValue], (err) => {
+        if (err) {
+            console.error('更新数据失败:', err)
+        }
+        loadConfigValues()
+    })
+}
+
+module.exports = { updateXunfeiConfig, getXunfeiMessage }

+ 11 - 9
README.md

@@ -1,6 +1,6 @@
 <h1 align="center">Web Wechat Bot</h1>
 
-「Web Wechat Bot」是一个基于Wechaty、可通过网页远程登录管理、可接入ChatGPT的微信聊天机器人,使用微信网页版协议。
+「Web Wechat Bot」是一个基于Wechaty、可通过网页远程登录管理、可接入讯飞星火、ChatGPT等大语言模型的微信聊天机器人,使用微信网页版协议。
 
 
 
@@ -28,21 +28,23 @@
 
 ```
 WebWechatBot                            
+├─ API                                  
+│  ├─ ChatGPT.js                        
+│  └─ xunfei.js                         
 ├─ db                                   
-│  └─ data.db
-├─ public                               
-│  ├─ css                               
+│  └─ data.db                                                  ├─ public                               
+│  ├─ css                                
 │  ├─ js                                
 │  └─ index.html                        
 ├─ wechat                               
-│  ├─ avatar                           
-│  ├─ getmessage.js                     
+│  ├─ avatar                                               
 │  └─ main.js                           
 ├─ app.js                               
 ├─ config.js                            
 ├─ package.json                         
 ├─ README.md                            
-└─ router.js			
+└─ router.js                            
+		
 ```
 
 
@@ -95,11 +97,11 @@ module.exports = {
 
 通过你的ip地址+端口号进入到机器人的管理界面,默认用户名为`admin`,密码`123456`
 
-在API设置页面中填入你的接口地址、API Key、模型名称等,其中app_code专为一些兼容openai接口的平台设置,可不填
+在API设置页面中填入你的接口地址、API Key、模型名称等,你可以自由选择讯飞星火和ChatGPT两个模型,其中兼容openai接口的API可填入ChatGPT的配置中
 
 ![](./images/1.png)
 
-在Wechat Bot设置界面你可以设置机器人的一些回复规则。
+在Wechat Bot设置界面你可以选择使用的语言模型、设置机器人的一些回复规则。
 
 ![](./images/2.png)
 

+ 1 - 1
config.js

@@ -1,4 +1,4 @@
 module.exports = {
-    port: 8080
+    port: 8082
 }
 

BIN
db/data.db


BIN
images/1.png


+ 2 - 1
package.json

@@ -6,6 +6,7 @@
     "express-jwt": "^8.4.1",
     "jsonwebtoken": "^9.0.2",
     "sqlite3": "^5.1.7",
-    "wechaty": "^1.20.2"
+    "wechaty": "^1.20.2",
+    "ws": "^8.16.0"
   }
 }

File diff suppressed because it is too large
+ 0 - 0
public/css/app.c633b4b3.css


File diff suppressed because it is too large
+ 0 - 0
public/css/app.e9c295cf.css


+ 1 - 1
public/index.html

@@ -1 +1 @@
-<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>webbot</title><script defer="defer" src="js/chunk-vendors.310ecf7c.js"></script><script defer="defer" src="js/app.7e5e693b.js"></script><link href="css/chunk-vendors.0e83c255.css" rel="stylesheet"><link href="css/app.e9c295cf.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but webbot doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
+<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>webbot</title><script defer="defer" src="js/chunk-vendors.310ecf7c.js"></script><script defer="defer" src="js/app.71a8e5b2.js"></script><link href="css/chunk-vendors.0e83c255.css" rel="stylesheet"><link href="css/app.c633b4b3.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but webbot doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because it is too large
+ 0 - 0
public/js/app.71a8e5b2.js


File diff suppressed because it is too large
+ 0 - 0
public/js/app.71a8e5b2.js.map


File diff suppressed because it is too large
+ 0 - 0
public/js/app.7e5e693b.js


File diff suppressed because it is too large
+ 0 - 0
public/js/app.7e5e693b.js.map


+ 33 - 7
router.js

@@ -1,5 +1,6 @@
 const express = require('express')
-const { updateGPTConfig } = require('./wechat/ChatGPT')
+const { updateGPTConfig } = require('./API/ChatGPT')
+const { updateXunfeiConfig } = require('./API/xunfei')
 const sqlite3 = require('sqlite3')
 const jsonwebtoken = require('jsonwebtoken')
 const path = require('path')
@@ -165,9 +166,8 @@ router.get('/stop', async (req, res) => {
     }
 })
 
-//获取api设置
-router.post('/getapiconfig', async (req, res) => {
-    db.all('SELECT * FROM apiconfig', [], (err, rows) => {
+router.post('/getgptconfig', async (req, res) => {
+    db.all('SELECT * FROM gptconfig', [], (err, rows) => {
         if (err) {
             res.send({ status: 500, msg: '查询失败!' })
             return
@@ -176,8 +176,17 @@ router.post('/getapiconfig', async (req, res) => {
     })
 })
 
-//设置api接口相关配置
-router.post('/apiconfig',async(req,res) => {
+router.post('/getxfconfig', async (req, res) => {
+    db.all('SELECT * FROM xfconfig', [], (err, rows) => {
+        if (err) {
+            res.send({ status: 500, msg: '查询失败!' })
+            return
+        }
+        res.send({ status: 200, msg: rows })
+    })
+})
+
+router.post('/gptconfig',async(req,res) => {
     const { apiKey,apiUrl,app_code,model } = req.body
     try {
         updateGPTConfig("apiKey", apiKey)
@@ -190,6 +199,22 @@ router.post('/apiconfig',async(req,res) => {
     }
 })
 
+router.post('/xfconfig', async (req, res) => {
+    const { temperature, max_tokens, app_id, APIKey, APISecret, apiUrl, domain } = req.body
+    try {
+        updateXunfeiConfig("temperature", temperature)
+        updateXunfeiConfig("max_tokens", max_tokens)
+        updateXunfeiConfig("app_id", app_id)
+        updateXunfeiConfig("APIKey", APIKey)
+        updateXunfeiConfig("APISecret", APISecret)
+        updateXunfeiConfig("apiUrl", apiUrl)
+        updateXunfeiConfig("domain", domain)
+        res.send({ status: 200, msg: '设置成功!' })
+    } catch (error) {
+        res.send({ status: 500, msg: '设置失败!' })
+    }
+})
+
 //获取机器人设置
 router.post('/getwxconfig', async (req, res) => {
     db.all('SELECT * FROM wxconfig', [], (err, rows) => {
@@ -203,7 +228,7 @@ router.post('/getwxconfig', async (req, res) => {
 
 //设置微信机器人
 router.post('/wxconfig', async (req, res) => {
-    const { autoReplySingle, suffix, prefix, atReply, keyWords, blackName, whiteRoom } = req.body
+    const { autoReplySingle, suffix, prefix, atReply, keyWords, blackName, whiteRoom ,model} = req.body
     try {
         setWx('autoReplySingle', autoReplySingle)
         setWx('suffix', suffix)
@@ -212,6 +237,7 @@ router.post('/wxconfig', async (req, res) => {
         setWx('atReply', atReply)
         setWx('keyWords', keyWords)
         setWx('blackName', blackName)
+        setWx('model', model)
         loadConfigValues()
         res.send({ status: 200, msg: '设置成功!' })
     } catch (error) {

BIN
wechat/avatar/avatar.jpg


+ 17 - 3
wechat/main.js

@@ -1,5 +1,6 @@
 const { WechatyBuilder } = require("wechaty")
-const { sendMessageToAPI } = require('./ChatGPT')
+const { getGPTMessage } = require('../API/ChatGPT')
+const { getXunfeiMessage } = require('../API/xunfei')
 const sqlite3 = require('sqlite3')
 
 //sqlite数据库路径
@@ -30,6 +31,7 @@ async function loadConfigValues() {
         autoReplySingle = await getConfigValue('autoReplySingle') === 'true'
         prefix = await getConfigValue('prefix')
         suffix = await getConfigValue('suffix')
+        model = await getConfigValue('model')
         whiteRoomString = await getConfigValue('whiteRoom')
         keyWordsString = await getConfigValue('keyWords')
         blackNameString = await getConfigValue('blackName')
@@ -49,11 +51,23 @@ async function loadConfigValues() {
     }
 }
 
-
-
 // 调用函数加载配置信息
 loadConfigValues()
 
+//选择模型
+async function sendMessageToAPI(message) {
+    if (model==='xunfei'){
+        const content = await getXunfeiMessage(message)
+        return content
+    }   else if (model==='chatgpt') {
+        const content = await getGPTMessage(message)
+        return content
+    }   else {
+        const content = '请在设置页面中选择语言模型'
+        return content
+    }
+}
+
 //获取时间
 function getCurrentTime() {
     const options = {

Some files were not shown because too many files changed in this diff