当前位置:   article > 正文

2024 年最新使用 Wechaty 开源框架搭建部署微信机器人(微信群客服积极性检测案例)

wechaty

项目需求概述

想要实现微信群机器人进行指定部分群进行定时检测,判断群是否存在指定管理员没有进行及时回复的消息,从而在群里发送提醒管理员进行回复。

Package.json 依赖

"dependencies": {
    "moment": "^2.29.4",
    "qrcode-terminal": "^0.12.0",
    "wechaty": "^1.20.2"
}
  • 1
  • 2
  • 3
  • 4
  • 5

初始化获取群信息

bot.on('ready', async () => {
    const roomList = await bot.Room.findAll();
    checkGroupList = []
    for (let index = 0; index < roomList.length; index++) {
        let room = roomList[index];
        let groupTopic = await room.topic()
        if (groups.includes(groupTopic)) {
            let roomItem = {
                topic: groupTopic,
                obj: room,
                time: null
            }
            checkGroupList.push(roomItem)
        }
    }
    console.log(`Total ${roomList.length} rooms found`);
    finishReadyState = true
    console.log("开始定时检查任务")
    startIntervalCheck()
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

roomItem 属性

{
    topic: '唤醒手腕测试群',
    obj: WechatifiedRoomImpl {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      id: '@@5ad6740d0133c831016bb1f56f1caf9e44eb68a0bbb7f7fbcfb1a9e93778751a',
      payload: [Object],
      [Symbol(kCapture)]: false
    },
    time: null
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

更新检查表时间状态

let updateCheckGroupTime = (groupTopic, time) => {
    checkGroupList.forEach(roomItem => {
        if (roomItem.topic == groupTopic) {
            roomItem.time = time
        }
    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

消息事件监听数据

bot.on('message', async message => {
    if (finishReadyState != true) { return }
    let room = message.room()
    if (!room) { return }
    let groupTopic = await room.topic()
    if (groups.includes(groupTopic)) {
        if (message.payload.type != 7) {
            return;
        } else {
            let talkerName = message.talker().payload.name;
            if (contacts.includes(talkerName)) {
                updateCheckGroupTime(groupTopic, null)
            } else {
                console.log('新消息提醒!!!')
                updateCheckGroupTime(groupTopic, moment().format("YYYY-MM-DD HH:mm:ss"))
            }
        }
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

判断时间是否指定区间

时间配置

time.json

{
    "startTime": "04:30",
    "endTime": "09:30",
    "duration": 20
}
  • 1
  • 2
  • 3
  • 4
  • 5

判断时间是否指定区间

isTimeBetween.js

const moment = require('moment');
const fs = require("fs");

timeConfig = JSON.parse(fs.readFileSync('time.json').toString())
startTime = timeConfig.startTime
endTime = timeConfig.endTime

let isTimeBetween = (timeString, startTimeString = startTime, endTimeString = endTime) => {
    const time = moment(timeString, 'HH:mm:ss');
    const startTime = moment(startTimeString, 'HH:mm');
    const endTime = moment(endTimeString, 'HH:mm');

    if (!time.isValid() || !startTime.isValid() || !endTime.isValid()) {
        return false;
    }

    return time.isBetween(startTime, endTime, null, '[]');
}

const timeString = '21:30:01';
const isBetween = isTimeTodayBetween(timeString, "19:00:00", "20:00:00");

console.log(isBetween)

module.exports = isTimeBetween
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

检查消息是否超时

检测时间字符串是否表示的时间在距离当前时间 X 分钟范围内。

isWithinMinutes.js

const moment = require('moment');  
  
isWithinMinutes = (timeString, minutes) => {  
    const timeMoment = moment(timeString, 'YYYY-MM-DD HH:mm:ss');'YYYY-MM-DD HH:mm:ss'  
    if (!timeMoment.isValid()) {  
        return false;  
    }  
    const nowMoment = moment();  
    const diffMinutes = nowMoment.diff(timeMoment, 'minutes');  
    return Math.abs(diffMinutes) <= minutes;  
}

const timeString = '2023-03-15 12:30:00';
const X = 20;
  
const isWithinXMinutes = isWithinMinutes(timeString, X);  
  
console.log(isWithinXMinutes);

module.exports = isWithinMinutes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

配置定时检测任务

timeConfig = JSON.parse(fs.readFileSync('time.json').toString())
let duration = timeConfig.duration

let startIntervalCheck = () => {
    setInterval(async () => {
    	if (!isTimeBetween(moment().format("HH:mm:ss"))) { return }
        console.log(moment().format("YYYY-MM-DD HH:mm:ss"), "正在检测中···")
        for (let index = 0; index < checkGroupList.length; index++) {
            const room = checkGroupList[index];
            if (room.time) {
                if (!isWithinXminutes(room.time, duration)) {
                    let members = await room.obj.memberAll()
                    await room.obj.say(`@${members[0].payload.name} 超时回复消息!!! 客服摸鱼警告!!!`)
                    room.time = moment().format("YYYY-MM-DD HH:mm:ss")
                }
            }
        }
    }, 10000);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

配置授权群组、授权客服

授权客服数据

contacts.json

[
    {
        "id": "38de7ca8-d95a-4617-953c-babdaf5e0e1f",
        "content": "唤醒手腕"
    },
    {
        "id": "37e20e96-32a1-4b33-bc4e-edd7a41217db",
        "content": "夜雨星空"
    }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

授权群组数据

groups.json

[
    {
        "id": "1d4a26d8-a9b6-4759-a703-602254d92ad6",
        "content": "测试1群"
    },
    {
        "id": "3328a15a-cbb7-4042-9459-77e40f3164dd",
        "content": "测试2群"
    }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

读取数据

let groups = []
const groupsData = JSON.parse(fs.readFileSync('groups.json', 'utf8'));
groupsData.forEach(item => { groups.push(item.content) });
console.log(`【获取授权群组】` + groups + '\n')

let contacts = []
const contactsData = JSON.parse(fs.readFileSync('contacts.json', 'utf8'));
contactsData.forEach(item => { contacts.push(item.content) });
console.log(`【获取监听客服】` + contacts + '\n')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

详细完整源码 bot.js

源码目录结构

node_modules			模块包
package.json			package 配置文件

bot.js					启动脚本(启动文件 node bot.js)
isTimeBetween.js		判断时间是否指定区间
isWithinXMinutes.js		检查消息是否超时脚本工具
groups.json				授权群组数据
contacts.json			授权客服数据
time.json				配置时间数据
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

启动脚本 bot.js

const { WechatyBuilder } = require('wechaty');
const qrcode = require('qrcode-terminal');
const fs = require('fs');
const moment = require('moment');
const isWithinXminutes = require('./isWithinXminutes');
const isTimeBetween = require('./isTimeBetween');

let finishReadyState = false
let checkGroupList = []

let updateCheckGroupTime = (groupTopic, time) => {
    checkGroupList.forEach(roomItem => {
        if (roomItem.topic == groupTopic) {
            roomItem.time = time
        }
    })
}

timeConfig = JSON.parse(fs.readFileSync('time.json').toString())
let duration = timeConfig.duration

let startIntervalCheck = () => {
    setInterval(async () => {  
    	if (!isTimeBetween(moment().format("HH:mm:ss"))) { return }
        console.log(moment().format("YYYY-MM-DD HH:mm:ss"), "正在检测中···")
        for (let index = 0; index < checkGroupList.length; index++) {
            const room = checkGroupList[index];
            if (room.time) {
                if (!isWithinXminutes(room.time, duration)) {
                    let members = await room.obj.memberAll()
                    await room.obj.say(`@${members[0].payload.name} 超时回复消息!!! 客服摸鱼警告!!!`)
                    room.time = moment().format("YYYY-MM-DD HH:mm:ss")
                }
            }
        }
    }, 10000);
}

let groups = []
const groupsData = JSON.parse(fs.readFileSync('groups.json', 'utf8'));
groupsData.forEach(item => { groups.push(item.content) });
console.log(`【获取授权群组】` + groups + '\n')

let contacts = []
const contactsData = JSON.parse(fs.readFileSync('contacts.json', 'utf8'));
contactsData.forEach(item => { contacts.push(item.content) });
console.log(`【获取监听客服】` + contacts + '\n')

const bot = WechatyBuilder.build()

bot.on('scan', (code, status) => {
    qrcode.generate(code, { small: true });
})

bot.on('login', user => console.log(`User ${user} logged in`))

bot.on('message', async message => {
	if (!isTimeBetween(moment().format("HH:mm:ss"))) { return }
    if (finishReadyState != true) { return }
    let room = message.room()
    if (!room) { return }
    let groupTopic = await room.topic()
    if (groups.includes(groupTopic)) {
        if (message.payload.type != 7) {
            return;
        } else {
            let talkerName = message.talker().payload.name;
            if (contacts.includes(talkerName)) {
                updateCheckGroupTime(groupTopic, null)
            } else {
                console.log('新消息提醒!!!')
                updateCheckGroupTime(groupTopic, moment().format("YYYY-MM-DD HH:mm:ss"))
            }
        }
    }
});

bot.on('ready', async () => {
    const roomList = await bot.Room.findAll();
    checkGroupList = []
    for (let index = 0; index < roomList.length; index++) {
        let room = roomList[index];
        let groupTopic = await room.topic()
        if (groups.includes(groupTopic)) {
            let roomItem = {
                topic: groupTopic,
                obj: room,
                time: ""
            }
            checkGroupList.push(roomItem)
        }
    }
    console.log(`Total ${roomList.length} rooms found`);
    finishReadyState = true
    console.log("开始定时检查任务")
    startIntervalCheck()
})

bot.start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99

Electron 搭建 UI 界面

客服管理界面

在这里插入图片描述

时间管理界面

在这里插入图片描述
关于 electron 桌面应用搭建(待更新···)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/693509
推荐阅读
相关标签
  

闽ICP备14008679号