需要背景
目前所在企业是一家创新型汽车后市场互联网科技有限公司,拓展汽车后市场B2C、B2B和O2O业务。
后期打造链接线下6家自营大型汽车业余维修中心,12家自营汽车配件、汽保设施销售核心,3000余家加盟汽修、汽配企业及10余万集体客户的服务平台;
因为客户维系和供应商征询等都是基于微信群聊的。每天要在成千盈百的群聊中提供服务。须要实时在群内产品报价,车架号辨认,图片辨认,关键字反馈。数据推送等等性能。这样的需要状况下,人力老本是微小的。
而我作为一名前端开发工程师,平时也喜爱写技术博客和交朋友,为此我也创立了微信技术交换群和微信公众号,个别我都会在文章上面贴出公众号和我的集体二维码,给有趣味的小伙伴们增加微信而后我再拉他们进群这些,然而不停的批准微信好友验证,再发送群邀请真的是太苦楚了,置信很多做公众号的小伙伴都和我一样,作为一名开发,这种重复劳动是相对不能忍耐的基于这种状况和公司业务状况,调研发现了并理解到了wechaty,发现其提供的性能可能笼罩到企业和集体微信,并且可能本人定制化开发合乎本人需要的性能。
介绍
Wechaty 是什么
微信集体号性能十分弱小和灵便,是一个非常适合用来做ChatBot的载体。它能够灵便不受限制的发送语音短信、视频、图片和文字,反对多人群聊。然而应用微信集体微信号作为ChatBot,须要通过非官方的第三方库接入微信。因为截至2018年底,微信尚无任何官网的ChatBot API公布。
Wechaty 是一个开源的的对话机器人 SDK,反对 集体号 微信。它是一个应用Typescript 构建的Node.js 利用。反对多种微信接入计划,包含网页,ipad,ios,windows, android 等。同时反对Linux, Windows, Darwin(OSX/Mac) 和 Docker 多个平台。
在GitHub上能够找到很多反对微信集体号接入的第三方类库,其中大多都是基于Web Wechat的API来实现的,如基于Python的WeixinBot,基于Node.js的Wechaty等。多数反对非Web协定的库,大多是商业公有闭源的,Wechaty是少有的开源我的项目反对非Web协定的类库。
只须要6行代码,你就能够 通过集体号 搭建一个 微信机器人性能 ,用来主动治理微信音讯。
import { Wechaty } from 'wechaty'Wechaty.instance().on('scan', qrcode => console.log('扫码登录:' + qrcode)).on('login', user => console.log('登录胜利:' + user)).on('message', message => console.log('收到音讯:' + message)).on('friendship', friendship => console.log('收到好友申请:' + friendship)).on('room-invite', invitation => console.log('收到入群邀请:' + invitation)).start()
更多功能包含
- 音讯解决:关键词回复
- 群治理:主动入群,拉人,踢人
- 主动解决好友申请
- 智能对话:通过简略配置,即可退出智能对话零碎,实现指定工作
- ... 请自行开脑洞 所有你能想到的交互模式。在微信上都有实现的可能。
每日定时拉取天气预报。
每天给你可爱的人发送早安和晚安信息。
什么成语接龙啦。快问快答等等性能
当然wechaty的性能服务并不是收费的
200/月的费用,如果你是集体开发可能会斟酌一二。然而你能够通过社区申请一个长达15天的收费token来尝试应用和开发一个小型机器人,从而决定你是否须要购买应用。
对于申请的地址我放在了这里Wechaty Token 申请及应用文档和常见问题
基于wechaty-puppet-hostie开发企业级微信机器人
目录构造
├── config│ └── index.js // 配置文件├── package.json├── service│ ├── bot-service│ │ ├── error-service.js│ │ ├── friendship-service.js│ │ ├── heartbeat-service.js│ │ ├── login-service│ │ │ ├── function-service.js│ │ │ └── index.js│ │ ├── logout-service.js│ │ ├── message-service│ │ │ ├── function-service.js│ │ │ └── index.js│ │ ├── ready-service│ │ │ ├── function-service.js│ │ │ └── index.js│ │ ├── room-invite-service.js│ │ ├── room-join-service.js│ │ ├── room-leave-service.js│ │ ├── room-topic-service.js│ │ └── scan-service│ │ └── index.js│ ├── common-service│ │ ├── chatbot-service.js│ │ ├── ding-service.js│ │ └── oss-service.js│ └── redis-service│ └── index.js├── src│ └── main.js // 入口├── store│ └── index.js // 全局存储对象├── utils│ ├── oss.js // 阿里云oss认证│ └── redis.js // redis认证登录└── yarn.lock
src/main.js
const { Wechaty } = require('wechaty') // 机器人木偶const { onScan } = require("../service/bot-service/scan-service") // 当机器人须要扫码登陆的时候会触发这个事件。const { onLogin } = require("../service/bot-service/login-service") // 当机器人胜利登陆后,会触发事件,并会在事件中传递以后登陆机器人的信息const { onLogout } = require("../service/bot-service/logout-service") // 当机器人检测到登出的时候,会触发事件,并会在事件中传递机器人的信息。const { onReady } = require("../service/bot-service/ready-service") // 当所有数据加载实现后,会触发这个事件。在wechaty-puppet-padchat 中,它意味着曾经加载实现Contact 和Room 的信息。const { onMessage } = require("../service/bot-service/message-service") // 当机器人收到音讯的时候会触发这个事件。const { onRoomInvite } = require("../service/bot-service/room-invite-service") // 当收到群邀请的时候,会触发这个事件。const { onRoomTopic } = require("../service/bot-service/room-topic-service") // 当有人批改群名称的时候会触发这个事件。const { onRoomJoin } = require("../service/bot-service/room-join-service") // 当有人进入微信群的时候会触发这个事件。机器人被动进入某个微信群,那个样会触发这个事件。const { onRoomleave } = require("../service/bot-service/room-leave-service") // 当机器人把群里某个用户移出群聊的时候会触发这个工夫。用户被动退群是无奈检测到的。const { onFriendship } = require("../service/bot-service/friendship-service") // 当有人给机器人发好友申请的时候会触发这个事件。const { onHeartbeat } = require('../service/bot-service/heartbeat-service') // 获取机器人的心跳。const { onError } = require('../service/bot-service/error-service') // 当机器人外部出错的时候会触发error 事件。const { wechatyToken } = require('../config/index') // 机器人tokenconst { globalData } = require('../store/index') // 全局对象globalData.bot = new Wechaty({ puppet: 'wechaty-puppet-hostie', puppetOptions: { token: wechatyToken }});globalData.bot .on('scan', onScan) .on('login', onLogin) .on('logout', onLogout) .on('ready', onReady) .on('message', onMessage) .on('room-invite', onRoomInvite) .on('room-topic', onRoomTopic) .on('room-join', onRoomJoin) .on('room-leave', onRoomleave) .on('friendship', onFriendship) .on('heartbeat', onHeartbeat) .on('error', onError) .start()
具体性能实现及代码
- 扫码登录 通过node启动后,触发onScan事件,将登录二维码打印在控制台,扫码登录
const QrcodeTerminal = require('qrcode-terminal');const { ScanStatus } = require('wechaty-puppet')/** * @method onScan 当机器人须要扫码登陆的时候会触发这个事件。 倡议你装置 qrcode-terminal(运行 npm install qrcode-terminal) 这个包,这样你能够在命令行中间接看到二维码。 * @param {*} qrcode * @param {*} status */const onScan = async (qrcode, status) => { try { if (status === ScanStatus.Waiting) { console.log(`========================????二维码状态:${status}????========================nn`) QrcodeTerminal.generate(qrcode, { small: true }) } } catch (error) { console.log('onScan', error) }}module.exports = { onScan }
- 登录胜利 扫码登录胜利后会触发onLogin事件,通过事件接管到登录信息和机器人信息,通过钉钉接口将登录告诉发送至钉钉群内
const { notificationLoginInformation } = require('../../common-service/ding-service')const { updateBotInfo } = require('./function-service')const { globalData } = require('../../../store/index')/** * @method onLogin 当机器人胜利登陆后,会触发事件,并会在事件中传递以后登陆机器人的信息 * @param {*} botInfo */const onLogin = async botInfo => { try { console.log('========================???? onLogin ????========================nn') console.log(`机器人信息:${JSON.stringify(botInfo)}nn`) console.log(` // // // ##DDDDDDDDDDDDDDDDDDDDDD## ## DDDDDDDDDDDDDDDDDDDD ## ## DDDDDDDDDDDDDDDDDDDD ## ## hh hh ## ## ## ## ## ## ## ## ## ### ## #### ## ## hh // hh ## ## ## ## ## ## ## ## ## ## hh // hh ## ## ## ## ## ## ## ## ## ## hh hh ## ## ## ## ## ## ## ## ## ## ## hh wwww hh ## ## ## ## ## ## ## ## #### ## hh hh ## ## ## ## ## ## ## ## ## ## ## ### ## ## ### ## MMMMMMMMMMMMMMMMMMMM ## ##MMMMMMMMMMMMMMMMMMMMMM## 微信机器人名为: [${botInfo.payload.name}] 曾经扫码登录胜利了。nn `) // 全局存储机器人信息 globalData.botPayload = botInfo.payload // 更新机器人列表 updateBotInfo() // 机器人登录登出揭示/告诉钉钉接口 notificationLoginInformation(true) } catch (error) { console.log(`onLogin: ${error}`) }}module.exports = { onLogin }— 机器人异样退出 当node服务异样终端,或者手机上退出机器人登录后会触发onLogout事件,同样钉钉群内告诉信息,并且销毁程序中运行的一些定时器等const { notificationLoginInformation } = require('../common-service//ding-service')const { globalData } = require('../../store/index')/** * @method onLogout 当机器人检测到登出的时候,会触发事件,并会在事件中传递机器人的信息。 * @param {*} botInfo */const onLogout = async botInfo => { try { console.log('========================???? onLogout ????========================') console.log(`当bot检测到登记时,将与以后登录用户的联系人收回登记。`) // 全局存储机器人信息 globalData.botPayload = botInfo.payload const { updateRoomInfoTimer, chatbotSayQueueTimer } = globalData // 机器人退出清空定时器 if (updateRoomInfoTimer) { clearTimeout(updateRoomInfoTimer) } if (chatbotSayQueueTimer) { clearInterval(chatbotSayQueueTimer) } // 机器人登录登出揭示/告诉钉钉接口 notificationLoginInformation(false) } catch (error) { console.log(`error in onLogout:${error}`) }}module.exports = { onLogout }
- 音讯接管解决 当微信接管到新的音讯时候会触发onMessage事件,通过事件内对音讯的判断,群内音讯还是私聊音讯等做出不同的逻辑解决。从而实现业务需要。局部代码如下
const dayjs = require('dayjs');const { say } = require('../../common-service/chatbot-service')const { isCanSay, roomIdentifyVin, rooImageIdentifyVin, contactIdentifyVin, contactImageIdentifyVin, messageProcessing, storageRoomMessage, storageContactMessage,} = require('./function-service')const { roomMessageFeedback, contactMessageFeedback} = require('../../common-service/ding-service')const { globalData } = require('../../../store/index');const { Message } = require('wechaty');/** * @method onMessage 当机器人收到音讯的时候会触发这个事件。 * @param {*} message */const onMessage = async message => { try { console.log('========================???? onMessage ????========================nn') // 机器人信息 const { botPayload } = globalData // 获取发送音讯的联系人 const contact = message.from() // 获取音讯所在的微信群,如果这条音讯不在微信群中,会返回null const room = message.room() // 查看这条音讯是否为机器人发送的 const isSelf = message.self() // 解决音讯内容 const text = await messageProcessing(message) // console.log(`========================???? 解决音讯后内容为:${text} ????========================nn`) // 音讯为空不解决 if (!text) return // 音讯详情 const messagePayload = message.payload // console.log(`========================???? 音讯详情:${JSON.stringify(messagePayload)} ????========================nn`) // 音讯联系人详情 const contactPayload = contact.payload // console.log(`========================???? 音讯联系人详情:${JSON.stringify(contactPayload)} ????========================nn`) // 群音讯 if (room) { console.log(`========================???? 群聊音讯 ????========================nn`) // 房间详情 const roomPayload = room.payload // console.log(`========================???? 房间详情:${JSON.stringify(roomPayload)} ????========================nn`) console.log(`音讯工夫:${dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss')}nn群聊名称:${roomPayload.topic}nn微信名称:${contactPayload.name}nn微信类型:${contactPayload.type}nn备注昵称:${contactPayload.alias}nn音讯内容:${text}nn音讯类型:${messagePayload.type}nn`); // 存储音讯内容 const storeMessage = { category: 'room', // 音讯类别,room为群聊音讯, contact为集体音讯。 isSelf: isSelf, // 是否本人发送的音讯 messageId: messagePayload.id, // 音讯id messageToId: messagePayload.toId, // 音讯接收者id messageType: messagePayload.type, // 音讯类型 messageText: text, // 音讯内容 messageTimestamp: messagePayload.timestamp, // 音讯工夫戳 messageTime: dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss'), // 音讯工夫 roomOwnerId: roomPayload.ownerId, // 群聊群主id roomTopic: roomPayload.topic, // 群聊名称 roomId: roomPayload.id, // 群聊名称 contactId: contactPayload.id, // 音讯发送者id contactName: contactPayload.name, // 音讯发送者昵称 contactType: contactPayload.type, // 音讯发送者类型 contactAvatar: contactPayload.avatar, // 音讯发送者头像 contactAlias: contactPayload.alias, // 音讯发送者备注 } // redis中存储群聊音讯内容 storageRoomMessage(roomPayload, storeMessage) // 音讯是机器人本人发的 或者 音讯发送到wechaty接管距离大于半个小时 if (isSelf || message.age() > 1800) return // 判断以后机器人在群中是否能够谈话 if (!await isCanSay(roomPayload)) return // 有人@我 const isMentionSelf = await message.mentionSelf() // 如果有人@我 if (isMentionSelf) { console.log('this message were mentioned me! [You were mentioned] tip ([有人@我]的提醒)') // 获取音讯内容,拿到整个音讯文本,去掉 @名字 const sendText = text.replace("@" + botPayload.name, "") if (sendText == '图片') { // 通过不同的关键字进行业务解决逻辑 say({ messageType: 6, sender: room, messageInfo: { fromUrl: 'https://wework.qpic.cn/wwhead/nMl9ssowtibVGyrmvBiaibzDqfABIxIv4ic0FyQRxgQVpUIaqlePxrDW8L2qPB3WnHSZclgQ1D1QhDs/0' } }) return } if (sendText == '分享') { // 通过不同的关键字进行业务解决逻辑 say({ messageType: 14, sender: room, messageInfo: { urlLink: { description: 'WeChat Bot SDK for Individual Account, Powered by TypeScript, Docker, and Love', thumbnailUrl: 'https://avatars0.githubusercontent.com/u/25162437?s=200&v=4', title: 'Welcome to Wechaty', url: 'https://github.com/wechaty/wechaty', } } }) return } if (sendText == '名片') { say({ messageType: 3, sender: room, messageInfo: { contactCard: 'contactId' } }) return } if (sendText == '小程序') { say({ messageType: 9, sender: room, messageInfo: { miniProgram: { appid: 'xxxxx', title: '我正在应用Authing认证身份,你也来试试吧', pagePath: 'pages/home/home.html', description: '身份管家', thumbUrl: '30590201000452305002010002041092541302033d0af802040b30feb602045df0c2c5042b777875706c6f61645f31373533353339353230344063686174726f6f6d3131355f313537363035393538390204010400030201000400', thumbKey: '42f8609e62817ae45cf7d8fefb532e83', } } }) return } // 群里失常谈话 } else { // 重构机器人功能测试群 if (roomPayload.id !== 'R:10696051737544800') { console.log(`========================???? 不是测试群音讯,不解决群内业务逻辑 ????========================nn`) return } if (/^[a-zA-Z0-9]{17}$/.test(text)) { // 群聊辨认vin反馈 roomIdentifyVin(room, contact, message, text) return } // 群内音讯以[弱]结尾的信息为反馈信息。反馈给后盾 if (text.indexOf('[弱]') === 0) { // 群音讯反馈 roomMessageFeedback(room, contact, text) return } // 如果是图片,则图片解析vin if (messagePayload.type === Message.Type.Image) { // 群聊图片辨认vin反馈 rooImageIdentifyVin(room, contact, message) } } // 私聊音讯 } else { console.log(`========================???? 私聊音讯 ????========================nn`) console.log(`音讯工夫:${dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss')}nn微信名称:${contactPayload.name}nn微信类型:${contactPayload.type}nn备注昵称:${contactPayload.alias}nn音讯内容:${text}nn音讯类型:${messagePayload.type}nn`); // 存储音讯内容 const storeMessage = { category: 'contact', // 音讯类别,room为群聊音讯, contact为集体音讯。 isSelf: isSelf, // 是否本人发送的音讯 messageId: messagePayload.id, // 音讯id messageToId: messagePayload.toId, // 音讯接收者id messageType: messagePayload.type, // 音讯类型 messageText: text, // 音讯内容 messageTimestamp: messagePayload.timestamp, // 音讯工夫戳 messageTime: dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss'), // 音讯工夫 contactId: contactPayload.id, // 音讯发送者id contactName: contactPayload.name, // 音讯发送者昵称 contactType: contactPayload.type, // 音讯发送者类型 contactAvatar: contactPayload.avatar, // 音讯发送者头像 contactAlias: contactPayload.alias, // 音讯发送者备注 } // redis中存储私聊音讯内容 storageContactMessage(contact, storeMessage) // 音讯是机器人本人发的 或者 音讯发送到wechaty接管距离大于半个小时 if (isSelf || message.age() > 1800) return if (/^[a-zA-Z0-9]{17}$/.test(text)) { // 私聊辨认vin反馈 contactIdentifyVin(contact, message, text) return } // 私聊音讯以[弱]结尾的信息为反馈信息。反馈给后盾 if (text.indexOf('[弱]') === 0) { // 私聊音讯反馈 contactMessageFeedback(contact, text) return } // 如果是图片,则图片解析vin if (messagePayload.type === Message.Type.Image) { // 私聊图片解析vin反馈 contactImageIdentifyVin(contact, message) } } } catch (error) { console.log(`onMessage:${error}`) }}module.exports = { onMessage }
至于其余的一些生命周期以及钩子函数。大家能够参考文档做出属于本人的利用机器人
封装say办法
因为say()办法会在多处调用,并且要依据不同的音讯类型发送的内容做出不同的数据处理。大家当前也会遇到,因而这里将我封装的一个say办法展现给大家用于参考
const { MiniProgram, UrlLink, FileBox } = require('wechaty')const dayjs = require('dayjs');const { DelayQueueExector } = require('rx-queue');const { redisHexists, redisHset, redisHget, redisSet, redisLpush } = require('../redis-service/index')const { globalData } = require('../../store/index')const delay = new DelayQueueExector(10000);/** * @method say 机器人发送音讯 * @param {*} messageType 音讯类型 7文本,1文件,6图片,3集体名片,14卡片链接 9小程序 * @param {*} sender 起源 房间 || 集体 实例对象 * @param {*} messageInfo 内容 *//** * messageInfo 数据结构 * tetx: string 文本音讯必传 * fileUrl: string 文件音讯必传 * imageUr: string 图片音讯必传 * cardId: string 集体名片音讯必传 * linkInfo: object 卡片音讯必传 * description: string 形容 * thumbnailUrl: string 缩略图地址 * title: string 题目 * url: string 跳转地址 */async function say({ messageType, sender, messageInfo }) { // console.log(messageType); // console.log(sender); // console.log(messageInfo); try { return new Promise(async (resolve, reject) => { // 机器人信息 const { bot } = globalData // 枚举音讯类型 const MessageType = { text: 7, // 文本 fromFile: 1, // 文件 fromUrl: 6, // 图片 contactCard: 3, // 集体名片 urlLink: 14, // 卡片链接 miniProgram: 9, // 小程序 } // 内容不存在 if (!messageInfo) { return } // 要发送的音讯内容 let content switch (messageType) { // 文本 7 case MessageType.text: content = messageInfo.text break; // 文件 1 case MessageType.fromFile: content = FileBox.fromFile(messageInfo.fromFile) break; // 图片 6 case MessageType.fromUrl: content = FileBox.fromUrl(messageInfo.fromUrl) break; // 集体名片 3 case MessageType.contactCard: content = await bot.Contact.load('1688853777824721') break; // 链接 14 case MessageType.urlLink: content = new UrlLink({ description: 'WeChat Bot SDK for Individual Account, Powered by TypeScript, Docker, and Love', thumbnailUrl: 'https://avatars0.githubusercontent.com/u/25162437?s=200&v=4', title: 'Welcome to Wechaty', url: 'https://github.com/wechaty/wechaty', }) break; // 小程序 9 case MessageType.miniProgram: content = new MiniProgram({ appid: 'wx60090841b63b6250', title: '我正在应用Authing认证身份,你也来试试吧', pagePath: 'pages/home/home.html', description: '身份管家', thumbUrl: '30590201000452305002010002041092541302033d0af802040b30feb602045df0c2c5042b777875706c6f61645f31373533353339353230344063686174726f6f6d3131355f313537363035393538390204010400030201000400', thumbKey: '42f8609e62817ae45cf7d8fefb532e83', }); break; default: break; } delay.execute(async () => { sender.say(content) .then(value => { console.log(`========================???? 机器人回复 ????========================nn`) resolve() }) .catch(reason => { console.log(`========================???? 机器人发送音讯失败 ????========================nn`, reason) }) }) }) } catch (error) { console.log('error in say', error); }}module.exports = { say}对了,对于onMessage事件中音讯格局的判断我也做了一层封装,这里给大家提供参考。/** * @method messageProcessing 解决音讯内容 * @param {*} message */async function messageProcessing(message) { try { return new Promise(async (resolve, reject) => { console.log(`========================???? messageProcessing ????========================nn`) // 音讯详情 const messagePayload = message.payload // 获取音讯的文本内容。 let text = message.text() /** * Unknown: 0, Attachment: 1, Audio: 2, Contact: 3, ChatHistory: 4, Emoticon: 5, Image: 6, Text: 7, Location: 8, MiniProgram: 9, GroupNote: 10, Transfer: 11, RedEnvelope: 12, Recalled: 13, Url: 14, Video: 15 */ // 音讯类型 switch (messagePayload.type) { // 附件 0 case Message.Type.Unknown: console.log(`========================???? 音讯类型为未知音讯:${messagePayload.type} ????========================nn`) text = '[你收到一个未知音讯,请在手机上查看]' break; // 附件 1 case Message.Type.Attachment: console.log(`========================???? 音讯类型为附件:${messagePayload.type} ????========================nn`) // 临时不晓得怎么解决 text = '[你收到一个附件,请在手机上查看]' break; // 音频 2 case Message.Type.Audio: console.log(`========================???? 音讯类型为音频:${messagePayload.type} ????========================nn`) text = '[你收到一条语音音讯,请在手机上查看]' break; // 集体名片 3 case Message.Type.Contact: console.log(`========================???? 音讯类型为集体名片:${messagePayload.type} ????========================nn`) text = '[你收到一张集体名片,请在手机上查看]' break; // 聊天记录 4 case Message.Type.ChatHistory: console.log(`========================???? 音讯类型为聊天记录:${messagePayload.type} ????========================nn`) text = '[你收到聊天记录,请在手机上查看]' break; // 表情符号 5 case Message.Type.Emoticon: console.log(`========================???? 音讯类型为表情符号:${messagePayload.type} ????========================nn`) text = '[你收到表情符号,请在手机上查看]' // 临时不晓得怎么解决 break; // 图片 6 case Message.Type.Image: console.log(`========================???? 音讯类型为图片:${messagePayload.type} ????========================nn`) // 上传图片至阿里云获取图片地址 text = await addImageOss(message) break; // 文本 7 case Message.Type.Text: console.log(`========================???? 音讯类型为文本:${messagePayload.type} ????========================nn`) // 去空格换行 text = text.replace(/s+/g, '') break; // 地位 8 case Message.Type.Location: console.log(`========================???? 音讯类型为地位:${messagePayload.type} ????========================nn`) text = '[你收到一条图片音讯,请在手机上查看]' break; // 小程序 9 case Message.Type.MiniProgram: console.log(`========================???? 音讯类型为小程序:${messagePayload.type} ????========================nn`) text = '[你收到一个小程序音讯,请在手机上查看]' break; // GroupNote 10 case Message.Type.GroupNote: console.log(`========================???? 音讯类型为GroupNote:${messagePayload.type} ????========================nn`) text = '[你收到一个GroupNote,请在手机上查看]' break; // Transfer 11 case Message.Type.Transfer: console.log(`========================???? 音讯类型为Transfer:${messagePayload.type} ????========================nn`) text = '[你收到一个Transfer,请在手机上查看]' break; // 红包 12 case Message.Type.RedEnvelope: console.log(`========================???? 音讯类型为红包:${messagePayload.type} ????========================nn`) text = '[你收到一个红包,请在手机上查看]' break; // Recalled 13 case Message.Type.Recalled: console.log(`========================???? 音讯类型为Recalled:${messagePayload.type} ????========================nn`) text = '[你收到一个Recalled,请在手机上查看]' break; // 链接地址 14 case Message.Type.Url: console.log(`========================???? 音讯类型为链接地址:${messagePayload.type} ????========================nn`) // 临时不晓得怎么解决 text = '[你收到一条链接音讯,请在手机上查看]' break; // 视频 15 case Message.Type.Video: console.log(`========================???? 音讯类型为视频:${messagePayload.type} ????========================nn`) text = '[你收到一个视频音讯,请在手机上查看]' break; default: text = '' break; } resolve(text) }) } catch (error) { console.log('error in messageProcessing', error); }}
为什么这样做一层封装解决,是因为咱们的业务需要要将聊天内容进行redis和mysql数据存储。不便当前数据勘误和查问应用。
实现的性能
基于wechaty咱们实现的性能有那些呢?
— 依据关键词,输出车辆 VIN 对应反馈出车型配件信息,并且将公司所在群区域的店铺配件库存信息反馈进去
- 依据图片辨认车辆 VIN,而后辨认 VIN 对应反馈出车型配件信息,并且将公司所在群区域的店铺配件库存信息反馈进去,图片解释接口采纳的百度的接口
- 关键词指令绑定群信息。依据不同指令进行群配置。
- redis 存储机器人信息。将群信息存储并同步在 redis 和 mysql 中。后盾配置对应群是否开启某些性能等等。
- 每月月初定时发送每个群的洽购信息。销量信息等等。
- 机器人登录调用钉钉接口,在钉钉群内公布机器人登录或者退出的揭示信息
- 群邀请主动通过,入群当前做出相应数据存储逻辑判断性能设置等
- 好友申请主动通过,关键字申请主动邀请入不同的群,性能笼罩等等
- 等等性能。 以上性能反对还在一直开发和摸索中。但曾经满足目前咱们的业务需要。
最初
你如果想用我这些货色,拉下代码config.js里换下token和一些配置信息就能够,当然我在不停更新,性能会越来越多,所以仓库中代码和文中会有些不一样,应用时简略看下代码,都写了具体正文,也很简略,然而因为代码中很多中央波及到来企业敏感信息。我只好从新写来一份最小可执行的demo,大家仅供参考。
❤️ 看完帮个忙
如果你感觉这篇内容对你挺有启发,我想邀请你帮我个小忙:
- 点赞,让更多的人也能看到这篇内容(珍藏不点赞,都是耍流氓 -_-)
- 关注公众号「番茄学前端」,我会定时更新和公布前端相干信息和我的项目案例教训供你参考。
- 加个好友, 尽管帮不上你大忙,然而一些业务问题大家能够探讨交换。