Skip to content

Commit

Permalink
Merge branch 'v2.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
atorber committed Dec 2, 2023
2 parents 9add4dc + 6479b5e commit 3a5d47f
Show file tree
Hide file tree
Showing 61 changed files with 5,125 additions and 1,232 deletions.
23 changes: 15 additions & 8 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# 维格表配置
VIKA_SPACE_NAME="" # 维格表空间名称,注意是名称而不是ID
VIKA_TOKEN="" #维格表token

# 基础配置
ADMINROOM_ADMINROOMTOPIC="瓦力是群主" # 管理群名称,需尽量保持名称复杂,避免重名群干扰

# 维格表配置
VIKA_SPACE_NAME="" # 维格表空间名称,与VIKA_SPACE_ID二选一只需要配置一项即可
VIKA_SPACE_ID="" # 维格表空间ID,与VIKA_SPACE_NAME二选一只需要配置一项即可
VIKA_TOKEN="" #维格表token

# 飞书多维表格配置
LARK_APP_ID="" # 飞书多维表格应用ID
LARK_APP_SECRET="" # 飞书多维表格应用Secret
LARK_BITABLE_APP_TOKEN="" # 飞书多维表格应用Verification Token
LARK_APP_USER_MOBILE="" # 飞书用户手机号,用于获取用户信息

# MQTT配置
MQTT_USERNAME="" # MQTT连接配置信息,推荐使用百度云的物联网核心套件
MQTT_PASSWORD="" # MQTT连接配置信息,推荐使用百度云的物联网核心套件
MQTT_ENDPOINT=broker.emqx.io # MQTT连接配置信息,推荐使用百度云的物联网核心套件
MQTT_PORT=1883 # MQTT连接配置信息,推荐使用百度云的物联网核心套件
MQTT_PORT_SSL=8084 # MQTT连接配置信息,推荐使用百度云的物联网核心套件
MQTT_USERNAME="" # MQTT连接配置信息
MQTT_PASSWORD="" # MQTT连接配置信息
MQTT_ENDPOINT=broker.emqx.io/mqtt # MQTT连接配置信息
MQTT_PORT=8883 # MQTT连接配置信息

# 备份
# 暂未使用
Expand Down
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
docs/
example/
example/
admin/
39 changes: 27 additions & 12 deletions example/ding-dong-bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@ import {
WechatyBuilder,
} from 'wechaty'

import { ChatFlow, getBotOps, log, logForm, ChatFlowConfig, WechatyConfig, VikaDB, IClientOptions, MqttProxy } from '../src/chatflow.js'
import {
ChatFlow,
getBotOps,
log,
logForm,
ChatFlowConfig,
WechatyConfig,
VikaDB,
// LarkDB,
IClientOptions,
MqttProxy,
} from '../src/chatflow.js'

// import { spawn } from 'child_process'

Expand All @@ -20,26 +31,29 @@ import { ChatFlow, getBotOps, log, logForm, ChatFlowConfig, WechatyConfig, VikaD

const main = async () => {

const VIKA_SPACE_NAME = process.env['VIKA_SPACE_NAME']
const VIKA_TOKEN = process.env['VIKA_TOKEN']
if (!VIKA_SPACE_NAME || !VIKA_TOKEN) {
logForm('维格表配置不全,.env文件或环境变量中设置的token和spaceName之后重启')
return
}
// 初始化数据表,可以选择Vika或Lark

// 初始化数据表
// 使用Vika
await VikaDB.init({
spaceName: VIKA_SPACE_NAME,
token: VIKA_TOKEN,
spaceName: process.env['VIKA_SPACE_NAME'],
token: process.env['VIKA_TOKEN'],
})

// 使用Lark
// await LarkDB.init({
// appId: process.env['LARK_APP_ID'],
// appSecret: process.env['LARK_APP_SECRET'],
// appToken: process.env['LARK_BITABLE_APP_TOKEN'],
// userMobile: process.env['LARK_APP_USER_MOBILE'],
// })

// 从配置文件中读取配置信息,包括wechaty配置、mqtt配置以及是否启用mqtt推送或控制
const config: {
mqttConfig: IClientOptions,
wechatyConfig: WechatyConfig,
mqttIsOn: boolean,
} | undefined = await ChatFlowConfig.init()

} | undefined = await ChatFlowConfig.init() // 默认使用vika,使用lark时,需要传入'lark'参数await ChatFlowConfig.init('lark')
// log.info('config', JSON.stringify(config, undefined, 2))
if (config) {
// 构建机器人
const ops = getBotOps(config.wechatyConfig.puppet, config.wechatyConfig.token)
Expand All @@ -48,6 +62,7 @@ const main = async () => {

// 如果MQTT推送或MQTT控制打开,则启动MQTT代理
if (config.mqttIsOn) {
log.info('启动MQTT代理...', JSON.stringify(config.mqttConfig))
try {
const mqttProxy = MqttProxy.getInstance(config.mqttConfig)
if (mqttProxy) {
Expand Down
9 changes: 0 additions & 9 deletions example/wxai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@ const skills:SkillInfoArray = [
},
]

// 使用
// const config: AIBotConfig = {
// encodingAESKey: process.env['ENCODING_AES_KEY'] || '',
// token: process.env['TOKEN'] || '',
// nonce: process.env['NONCE'] || '',
// appid: process.env['APP_ID'] || '',
// managerid: process.env['MANAGER_ID'] || '',
// }

const config: WxOpenaiBotConfig = {
encodingAESKey: '',
token: '',
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@atorber/chatflow",
"version": "2.0.53",
"version": "2.0.56",
"description": "ChatFlow-聊天机器人管理平台",
"type": "module",
"exports": {
Expand Down Expand Up @@ -28,6 +28,7 @@
"start:notls": "cross-env WECHATY_PUPPET_SERVICE_NO_TLS_INSECURE_CLIENT=true WECHATY_PUPPET_SERVICE_AUTHORITY=\"token-service-discovery-test.juzibot.com\" NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node ./example/ding-dong-bot.ts",
"start:store": "cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node ./src/plugins/store-messages-locally.ts",
"start:lark": "cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node ./tests/lark.ts",
"start:api": "cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node ./tests/api.ts",
"rm-temp": "rm -r temp; mkdir temp",
"rm-cache": "rm -r cache; mkdir cache",
"test": "npm run lint",
Expand Down Expand Up @@ -66,6 +67,7 @@
"html-to-docx": "^1.8.0",
"langchain": "^0.0.111",
"language-monitor": "^1.0.3",
"minio": "^7.1.3",
"moment": "^2.29.1",
"mqtt": "^4.3.7",
"nedb": "^1.8.0",
Expand Down
28 changes: 28 additions & 0 deletions src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 用户登录
export const login = async (
param:{
mobile:string,
password:string,
platform?:string
}) => {
let data = {}
if (param.mobile && param.mobile) {
data = {
access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJndWFyZCI6ImFwaSIsImlzcyI6ImltLndlYiIsImV4cCI6MTcyMTA3MDkwNCwiaWF0IjoxNjg1MDcwOTA0LCJqdGkiOiIyMDU0In0.-Mk4a20gur-QPxlYjgYc_eHWpWkDURJTawO0yBQ_b2g',
expires_in: 36000000,
type: 'Bearer',
}
}

return data
}

// 退出登录
export const logout = async () => {
return 'success'
}

// 刷新登录Token接口
export const refreshToken = async (token:string) => {
return token
}
69 changes: 64 additions & 5 deletions src/api/base-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import type { WhiteList } from '../services/mod.js'
import type { BusinessRoom, BusinessUser } from './contact-room-finder.js'
import { VikaDB } from '../db/vika-db.js'
import { LarkDB } from '../db/lark-db.js'
import type {
IClientOptions,
} from '../proxy/mqtt-proxy.js'
Expand Down Expand Up @@ -93,6 +94,8 @@ export class ChatFlowConfig {
static reminderList: any[]
static statisticRecords: any
static configEnv : ProcessEnv
static dataBaseType: 'vika' | 'lark'

static whiteList:WhiteList = {
contactWhiteList: {
qa: [],
Expand All @@ -110,11 +113,10 @@ export class ChatFlowConfig {

static bot:Wechaty

static async init () {

static async init (dataBaseType?:'vika' | 'lark') {
this.dataBaseType = dataBaseType || 'vika'
// log.info('初始化维格配置信息...,init()')

if (VikaDB.spaceId) {
if (this.dataBaseType === 'vika' && VikaDB.spaceId) {
const vikaIdMap: any = {}
const vikaData: any = {}
const configRecords: any[] = await VikaDB.getAllRecords(VikaDB.dataBaseIds.envSheet)
Expand All @@ -139,7 +141,63 @@ export class ChatFlowConfig {
}

// 计算clientid原始字符串
const clientString = VikaDB.token + VikaDB.spaceName
const clientString = VikaDB.token + VikaDB.spaceId
// clientid加密
const client = CryptoJS.SHA256(clientString).toString()

const mqttConfig:IClientOptions = {
username: this.configEnv.MQTT_USERNAME,
password: this.configEnv.MQTT_PASSWORD,
host: this.configEnv.MQTT_ENDPOINT,
protocol:'mqtts',
port: Number(this.configEnv.MQTT_PORT),
clientId: client,
clean: false,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
keepalive: 60,
resubscribe: true,
protocolId: 'MQTT',
protocolVersion: 4,
rejectUnauthorized: false,
}

// log.info('mqttConfig', JSON.stringify(mqttConfig, undefined, 2))
const mqttIsOn = Boolean(this.configEnv.MQTT_MQTTMESSAGEPUSH || this.configEnv.MQTT_MQTTCONTROL)

// log.info('vikaBot配置信息:', JSON.stringify(configVika, undefined, 2))

return {
wechatyConfig,
mqttConfig,
mqttIsOn,
}
} else if (this.dataBaseType === 'lark' && LarkDB.config.appToken) {
const vikaIdMap: any = {}
const vikaData: any = {}
const configRecords: any[] = await LarkDB.getAllRecords(LarkDB.dataBaseIds.envSheet)
for (let i = 0; i < configRecords.length; i++) {
const record: IRecord = configRecords[i] as IRecord
const fields = record.fields
const recordId = record.recordId
if (fields['标识|key']) {
if (fields['值|value'] && [ 'false', 'true' ].includes(fields['值|value'])) {
vikaData[record.fields['标识|key'] as string] = fields['值|value'] === 'true'
} else {
vikaData[record.fields['标识|key'] as string] = fields['值|value'] || ''
}
vikaIdMap[record.fields['标识|key'] as string] = recordId
}
}

this.configEnv = vikaData
const wechatyConfig: WechatyConfig = {
puppet: this.configEnv.WECHATY_PUPPET,
token: this.configEnv.WECHATY_TOKEN,
}

// 计算clientid原始字符串
const clientString = LarkDB.config.appId + LarkDB.config.appSecret + LarkDB.config.appToken
// clientid加密
const client = CryptoJS.SHA256(clientString).toString()

Expand All @@ -148,6 +206,7 @@ export class ChatFlowConfig {
password: this.configEnv.MQTT_PASSWORD,
host: this.configEnv.MQTT_ENDPOINT,
port: Number(this.configEnv.MQTT_PORT),
protocol:'mqtts',
clientId: client,
clean: false,
reconnectPeriod: 1000,
Expand Down
65 changes: 45 additions & 20 deletions src/api/contact.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
import nedb from '../db/nedb.js'
/* eslint-disable no-console */
/* eslint-disable camelcase */
import { ContactChat } from '../services/mod.js'

const db:any = nedb('./contact.db')
async function addUser (info:any) {
try {
const doc = await db.insert(info)
return doc
} catch (error) {
// console.log('插入数据错误', error)
// import { db } from '../db/tables.js'
// const contactData = db.contact

// 获取好友列表
export async function getContactList () {
const contactListRaw:any = await ContactChat.findAll()
// console.log('contactListRaw', JSON.stringify(contactListRaw))
const contactList: any = contactListRaw.map((value: { fields: { name: any; avatar: any; gender: any; id: any; alias: any }; recordId: any }) => {
if (value.fields.name) {
return {
avatar: value.fields.avatar,
gender: value.fields.gender,
group_id: 0,
id: value.fields.id,
is_online: 0,
motto: '',
nickname: value.fields.name,
remark: value.fields.alias,
recordId: value.recordId,
}
}
return false
}).filter((item: boolean) => item !== false)
const data = {
items: contactList,
}
return data
}
async function getUser () {
try {
const search = await db.find({})
return search[0]
} catch (error) {
// console.log('查询数据错误', error)

// 查询好友信息接口
export async function getContactInfo (_user_id:string) {
const contactInfo:any = {
avatar: '',
email: 0,
friend_apply: 0,
friend_status: 1,
gender: 0,
group_id: 0,
id: 4561,
mobile: '17773011187',
motto: '',
nickname: '97',
remark: '',
}
}
export { addUser }
export { getUser }
export default {
addUser,
getUser,
return contactInfo
}
16 changes: 16 additions & 0 deletions src/api/group-notice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { GroupNoticeChat } from '../services/mod.js'
// 获取群发通知列表
export const getGroupNoticeList = async (_data: any) => {
const res = await GroupNoticeChat.db.findAll()
return res
}

// 创建群发通知
export const createGroupNotice = (data: any) => {
return data
}

// 删除群发通知
export const deleteGroupNotice = (data: any) => {
return data
}
11 changes: 11 additions & 0 deletions src/api/keyword.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { KeywordChat } from '../services/mod.js'
// 获取关键词列表
export const getKeywordList = async (_params: any) => {
const res = await KeywordChat.db.findAll()
return res
}

// 获取关键词提示文案
export const getKeywordTips = (params: any) => {
return params
}
Loading

0 comments on commit 3a5d47f

Please sign in to comment.