需求背景目前所在企業(yè)是一家創(chuàng)新型汽車后市場(chǎng)互聯(lián)網(wǎng)科技有限公司,拓展汽車后市場(chǎng)B2C、B2B和O2O業(yè)務(wù)。

前期打造鏈接線下6家自營(yíng)大型汽車專業(yè)維修中心,12家自營(yíng)汽車配件、汽保設(shè)備" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > Wechaty | 企業(yè)級(jí)微信機(jī)器人助手

Wechaty | 企業(yè)級(jí)微信機(jī)器人助手

時(shí)間:2023-05-20 10:20:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-05-20 10:20:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

Wechaty | 企業(yè)級(jí)微信機(jī)器人助手:




需求背景

目前所在企業(yè)是一家創(chuàng)新型汽車后市場(chǎng)互聯(lián)網(wǎng)科技有限公司,拓展汽車后市場(chǎng)B2C、B2B和O2O業(yè)務(wù)。

前期打造鏈接線下6家自營(yíng)大型汽車專業(yè)維修中心,12家自營(yíng)汽車配件、汽保設(shè)備銷售中心,3000余家加盟汽修、汽配企業(yè)及10余萬(wàn)個(gè)人客戶的服務(wù)平臺(tái);

由于客戶維系和供應(yīng)商咨詢等都是基于微信群聊的。每天要在成百上千的群聊中提供服務(wù)。需要實(shí)時(shí)在群內(nèi)產(chǎn)品報(bào)價(jià),車架號(hào)識(shí)別,圖片識(shí)別,關(guān)鍵字反饋。數(shù)據(jù)推送等等功能。這樣的需求情況下,人力成本是巨大的。

而我作為一名前端開(kāi)發(fā)工程師,平時(shí)也喜歡寫技術(shù)博客和交朋友,為此我也創(chuàng)建了微信技術(shù)交流群和微信公眾號(hào),一般我都會(huì)在文章下面貼出公眾號(hào)和我的個(gè)人二維碼,給有興趣的小伙伴們添加微信然后我再拉他們進(jìn)群這些,但是不停的同意微信好友驗(yàn)證,再發(fā)送群邀請(qǐng)真的是太痛苦了,相信很多做公眾號(hào)的小伙伴都和我一樣,作為一名開(kāi)發(fā),這種重復(fù)勞動(dòng)是絕對(duì)不能忍受的基于這種情況和公司業(yè)務(wù)情況,調(diào)研發(fā)現(xiàn)了并了解到了wechaty,發(fā)現(xiàn)其提供的功能能夠覆蓋到企業(yè)和個(gè)人微信,并且能夠自己定制化開(kāi)發(fā)符合自己需求的功能。

介紹

Wechaty 是什么

微信個(gè)人號(hào)功能非常強(qiáng)大和靈活,是一個(gè)非常適合用來(lái)做ChatBot的載體。它可以靈活不受限制的發(fā)送語(yǔ)音短信、視頻、圖片和文字,支持多人群聊。但是使用微信個(gè)人微信號(hào)作為ChatBot,需要通過(guò)非官方的第三方庫(kù)接入微信。因?yàn)榻刂?018年底,微信尚無(wú)任何官方的ChatBot API發(fā)布。

Wechaty 是一個(gè)開(kāi)源的的對(duì)話機(jī)器人 SDK,支持 個(gè)人號(hào) 微信。它是一個(gè)使用Typescript 構(gòu)建的Node.js 應(yīng)用。支持多種微信接入方案,包括網(wǎng)頁(yè),ipad,ios,windows, android 等。同時(shí)支持Linux, Windows, Darwin(OSX/Mac) 和 Docker 多個(gè)平臺(tái)。

在GitHub上可以找到很多支持微信個(gè)人號(hào)接入的第三方類庫(kù),其中大多都是基于Web Wechat的API來(lái)實(shí)現(xiàn)的,如基于Python的WeixinBot,基于Node.js的Wechaty等。少數(shù)支持非Web協(xié)議的庫(kù),大多是商業(yè)私有閉源的,Wechaty是少有的開(kāi)源項(xiàng)目支持非Web協(xié)議的類庫(kù)。

只需要6行代碼,你就可以 通過(guò)個(gè)人號(hào) 搭建一個(gè) 微信機(jī)器人功能 ,用來(lái)自動(dòng)管理微信消息。

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('收到好友請(qǐng)求:' + friendship)).on('room-invite', invitation => console.log('收到入群邀請(qǐng):' + invitation)).start()

更多功能包括

每日定時(shí)拉取天氣預(yù)報(bào)。

每天給你心愛(ài)的人發(fā)送早安和晚安信息。

什么成語(yǔ)接龍啦??靻?wèn)快答等等功能

當(dāng)然wechaty的功能服務(wù)并不是免費(fèi)的

200/月的費(fèi)用,如果你是個(gè)人開(kāi)發(fā)可能會(huì)斟酌一二。但是你可以通過(guò)社區(qū)申請(qǐng)一個(gè)長(zhǎng)達(dá)15天的免費(fèi)token來(lái)嘗試使用和開(kāi)發(fā)一個(gè)小型機(jī)器人,從而決定你是否需要購(gòu)買使用。

關(guān)于申請(qǐng)的地址我放在了這里Wechaty Token 申請(qǐng)及使用文檔和常見(jiàn)問(wèn)題

基于wechaty-puppet-hostie開(kāi)發(fā)企業(yè)級(jí)微信機(jī)器人

目錄結(jié)構(gòu)

├── 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 // 全局存儲(chǔ)對(duì)象├── utils ├── oss.js // 阿里云oss認(rèn)證 └── redis.js // redis認(rèn)證登錄└── yarn.locksrc/main.js

const { Wechaty } = require('wechaty') // 機(jī)器人木偶const { onScan } = require("../service/bot-service/scan-service") // 當(dāng)機(jī)器人需要掃碼登陸的時(shí)候會(huì)觸發(fā)這個(gè)事件。const { onLogin } = require("../service/bot-service/login-service") // 當(dāng)機(jī)器人成功登陸后,會(huì)觸發(fā)事件,并會(huì)在事件中傳遞當(dāng)前登陸機(jī)器人的信息const { onLogout } = require("../service/bot-service/logout-service") // 當(dāng)機(jī)器人檢測(cè)到登出的時(shí)候,會(huì)觸發(fā)事件,并會(huì)在事件中傳遞機(jī)器人的信息。const { onReady } = require("../service/bot-service/ready-service") // 當(dāng)所有數(shù)據(jù)加載完成后,會(huì)觸發(fā)這個(gè)事件。在wechaty-puppet-padchat 中,它意味著已經(jīng)加載完成Contact 和Room 的信息。const { onMessage } = require("../service/bot-service/message-service") // 當(dāng)機(jī)器人收到消息的時(shí)候會(huì)觸發(fā)這個(gè)事件。const { onRoomInvite } = require("../service/bot-service/room-invite-service") // 當(dāng)收到群邀請(qǐng)的時(shí)候,會(huì)觸發(fā)這個(gè)事件。const { onRoomTopic } = require("../service/bot-service/room-topic-service") // 當(dāng)有人修改群名稱的時(shí)候會(huì)觸發(fā)這個(gè)事件。const { onRoomJoin } = require("../service/bot-service/room-join-service") // 當(dāng)有人進(jìn)入微信群的時(shí)候會(huì)觸發(fā)這個(gè)事件。機(jī)器人主動(dòng)進(jìn)入某個(gè)微信群,那個(gè)樣會(huì)觸發(fā)這個(gè)事件。const { onRoomleave } = require("../service/bot-service/room-leave-service") // 當(dāng)機(jī)器人把群里某個(gè)用戶移出群聊的時(shí)候會(huì)觸發(fā)這個(gè)時(shí)間。用戶主動(dòng)退群是無(wú)法檢測(cè)到的。const { onFriendship } = require("../service/bot-service/friendship-service") // 當(dāng)有人給機(jī)器人發(fā)好友請(qǐng)求的時(shí)候會(huì)觸發(fā)這個(gè)事件。const { onHeartbeat } = require('../service/bot-service/heartbeat-service') // 獲取機(jī)器人的心跳。const { onError } = require('../service/bot-service/error-service') // 當(dāng)機(jī)器人內(nèi)部出錯(cuò)的時(shí)候會(huì)觸發(fā)error 事件。const { wechatyToken } = require('../config/index') // 機(jī)器人tokenconst { globalData } = require('../store/index') // 全局對(duì)象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()

具體功能實(shí)現(xiàn)及代碼

const QrcodeTerminal = require('qrcode-terminal');const { ScanStatus } = require('wechaty-puppet')/** * @method onScan 當(dāng)機(jī)器人需要掃碼登陸的時(shí)候會(huì)觸發(fā)這個(gè)事件。 建議你安裝 qrcode-terminal(運(yùn)行 npm install qrcode-terminal) 這個(gè)包,這樣你可以在命令行中直接看到二維碼。 * @param {*} qrcode * @param {*} status */const onScan = async (qrcode, status) => { try { if (status === ScanStatus.Waiting) { console.log(`======================== 二維碼狀態(tài):${status} ========================/n/n`) QrcodeTerminal.generate(qrcode, { small: true }) } } catch (error) { console.log('onScan', error) }}module.exports = { onScan }const { notificationLoginInformation } = require('../../common-service/ding-service')const { updateBotInfo } = require('./function-service')const { globalData } = require('../../../store/index')/** * @method onLogin 當(dāng)機(jī)器人成功登陸后,會(huì)觸發(fā)事件,并會(huì)在事件中傳遞當(dāng)前登陸機(jī)器人的信息 * @param {*} botInfo */const onLogin = async botInfo => { try { console.log('======================== onLogin ========================/n/n') console.log(`機(jī)器人信息:${JSON.stringify(botInfo)}/n/n`) console.log(` // // // // // ##DDDDDDDDDDDDDDDDDDDDDD## ## DDDDDDDDDDDDDDDDDDDD ## ## DDDDDDDDDDDDDDDDDDDD ## ## hh hh ## ## ## ## ## ## ## ## ## ### ## #### ## ## hh // // hh ## ## ## ## ## ## ## ## ## ## hh // // hh ## ## ## ## ## ## ## ## ## ## hh hh ## ## ## ## ## ## ## ## ## ## ## hh wwww hh ## ## ## ## ## ## ## ## #### ## hh hh ## ## ## ## ## ## ## ## ## ## ## ### ## ## ### ## MMMMMMMMMMMMMMMMMMMM ## ##MMMMMMMMMMMMMMMMMMMMMM## 微信機(jī)器人名為: [${botInfo.payload.name}] 已經(jīng)掃碼登錄成功了。/n/n `) // 全局存儲(chǔ)機(jī)器人信息 globalData.botPayload = botInfo.payload // 更新機(jī)器人列表 updateBotInfo() // 機(jī)器人登錄登出提醒/通知釘釘接口 notificationLoginInformation(true) } catch (error) { console.log(`onLogin: ${error}`) }}module.exports = { onLogin }— 機(jī)器人異常退出 當(dāng)node服務(wù)異常終端,或者手機(jī)上退出機(jī)器人登錄后會(huì)觸發(fā)onLogout事件,同樣釘釘群內(nèi)通知信息,并且銷毀程序中運(yùn)行的一些定時(shí)器等

const { notificationLoginInformation } = require('../common-service//ding-service')const { globalData } = require('../../store/index')/** * @method onLogout 當(dāng)機(jī)器人檢測(cè)到登出的時(shí)候,會(huì)觸發(fā)事件,并會(huì)在事件中傳遞機(jī)器人的信息。 * @param {*} botInfo */const onLogout = async botInfo => { try { console.log('======================== onLogout ========================') console.log(`當(dāng)bot檢測(cè)到注銷時(shí),將與當(dāng)前登錄用戶的聯(lián)系人發(fā)出注銷。`) // 全局存儲(chǔ)機(jī)器人信息 globalData.botPayload = botInfo.payload const { updateRoomInfoTimer, chatbotSayQueueTimer } = globalData // 機(jī)器人退出清空定時(shí)器 if (updateRoomInfoTimer) { clearTimeout(updateRoomInfoTimer) } if (chatbotSayQueueTimer) { clearInterval(chatbotSayQueueTimer) } // 機(jī)器人登錄登出提醒/通知釘釘接口 notificationLoginInformation(false) } catch (error) { console.log(`error in onLogout:${error}`) }}module.exports = { onLogout }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 當(dāng)機(jī)器人收到消息的時(shí)候會(huì)觸發(fā)這個(gè)事件。 * @param {*} message */const onMessage = async message => { try { console.log('======================== onMessage ========================/n/n') // 機(jī)器人信息 const { botPayload } = globalData // 獲取發(fā)送消息的聯(lián)系人 const contact = message.from() // 獲取消息所在的微信群,如果這條消息不在微信群中,會(huì)返回null const room = message.room() // 查看這條消息是否為機(jī)器人發(fā)送的 const isSelf = message.self() // 處理消息內(nèi)容 const text = await messageProcessing(message) // console.log(`======================== 處理消息后內(nèi)容為:${text} ========================/n/n`) // 消息為空不處理 if (!text) return // 消息詳情 const messagePayload = message.payload // console.log(`======================== 消息詳情:${JSON.stringify(messagePayload)} ========================/n/n`) // 消息聯(lián)系人詳情 const contactPayload = contact.payload // console.log(`======================== 消息聯(lián)系人詳情:${JSON.stringify(contactPayload)} ========================/n/n`) // 群消息 if (room) { console.log(`======================== 群聊消息 ========================/n/n`) // 房間詳情 const roomPayload = room.payload // console.log(`======================== 房間詳情:${JSON.stringify(roomPayload)} ========================/n/n`) console.log(`消息時(shí)間:${dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss')}/n/n群聊名稱:${roomPayload.topic}/n/n微信名稱:${contactPayload.name}/n/n微信類型:${contactPayload.type}/n/n備注昵稱:${contactPayload.alias}/n/n消息內(nèi)容:${text}/n/n消息類型:${messagePayload.type}/n/n`); // 存儲(chǔ)消息內(nèi)容 const storeMessage = { category: 'room', // 消息類別,room為群聊消息, contact為個(gè)人消息。 isSelf: isSelf, // 是否自己發(fā)送的消息 messageId: messagePayload.id, // 消息id messageToId: messagePayload.toId, // 消息接收者id messageType: messagePayload.type, // 消息類型 messageText: text, // 消息內(nèi)容 messageTimestamp: messagePayload.timestamp, // 消息時(shí)間戳 messageTime: dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss'), // 消息時(shí)間 roomOwnerId: roomPayload.ownerId, // 群聊群主id roomTopic: roomPayload.topic, // 群聊名稱 roomId: roomPayload.id, // 群聊名稱 contactId: contactPayload.id, // 消息發(fā)送者id contactName: contactPayload.name, // 消息發(fā)送者昵稱 contactType: contactPayload.type, // 消息發(fā)送者類型 contactAvatar: contactPayload.avatar, // 消息發(fā)送者頭像 contactAlias: contactPayload.alias, // 消息發(fā)送者備注 } // redis中存儲(chǔ)群聊消息內(nèi)容 storageRoomMessage(roomPayload, storeMessage) // 消息是機(jī)器人自己發(fā)的 或者 消息發(fā)送到wechaty接收間隔大于半個(gè)小時(shí) if (isSelf || message.age() > 1800) return // 判斷當(dāng)前機(jī)器人在群中是否可以說(shuō)話 if (!await isCanSay(roomPayload)) return // 有人@我 const isMentionSelf = await message.mentionSelf() // 如果有人@我 if (isMentionSelf) { console.log('this message were mentioned me! [You were mentioned] tip ([有人@我]的提示)') // 獲取消息內(nèi)容,拿到整個(gè)消息文本,去掉 @名字 const sendText = text.replace("@" + botPayload.name, "") if (sendText == '圖片') { // 通過(guò)不同的關(guān)鍵字進(jìn)行業(yè)務(wù)處理邏輯 say({ messageType: 6, sender: room, messageInfo: { fromUrl: 'https://wework.qpic.cn/wwhead/nMl9ssowtibVGyrmvBiaibzDqfABIxIv4ic0FyQRxgQVpUIaqlePxrDW8L2qPB3WnHSZclgQ1D1QhDs/0' } }) return } if (sendText == '分享') { // 通過(guò)不同的關(guān)鍵字進(jìn)行業(yè)務(wù)處理邏輯 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認(rèn)證身份,你也來(lái)試試吧', pagePath: 'pages/home/home.html', description: '身份管家', thumbUrl: '30590201000452305002010002041092541302033d0af802040b30feb602045df0c2c5042b777875706c6f61645f31373533353339353230344063686174726f6f6d3131355f313537363035393538390204010400030201000400', thumbKey: '42f8609e62817ae45cf7d8fefb532e83', } } }) return } // 群里正常說(shuō)話 } else { // 重構(gòu)機(jī)器人功能測(cè)試群 if (roomPayload.id !== 'R:10696051737544800') { console.log(`======================== 不是測(cè)試群消息,不處理群內(nèi)業(yè)務(wù)邏輯 ========================/n/n`) return } if (/^[a-zA-Z0-9]{17}$/.test(text)) { // 群聊識(shí)別vin反饋 roomIdentifyVin(room, contact, message, text) return } // 群內(nèi)消息以[弱]開(kāi)頭的信息為反饋信息。反饋給后臺(tái) if (text.indexOf('[弱]') === 0) { // 群消息反饋 roomMessageFeedback(room, contact, text) return } // 如果是圖片,則圖片解析vin if (messagePayload.type === Message.Type.Image) { // 群聊圖片識(shí)別vin反饋 rooImageIdentifyVin(room, contact, message) } } // 私聊消息 } else { console.log(`======================== 私聊消息 ========================/n/n`) console.log(`消息時(shí)間:${dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss')}/n/n微信名稱:${contactPayload.name}/n/n微信類型:${contactPayload.type}/n/n備注昵稱:${contactPayload.alias}/n/n消息內(nèi)容:${text}/n/n消息類型:${messagePayload.type}/n/n`); // 存儲(chǔ)消息內(nèi)容 const storeMessage = { category: 'contact', // 消息類別,room為群聊消息, contact為個(gè)人消息。 isSelf: isSelf, // 是否自己發(fā)送的消息 messageId: messagePayload.id, // 消息id messageToId: messagePayload.toId, // 消息接收者id messageType: messagePayload.type, // 消息類型 messageText: text, // 消息內(nèi)容 messageTimestamp: messagePayload.timestamp, // 消息時(shí)間戳 messageTime: dayjs(messagePayload.timestamp).format('YYYY-MM-DD HH:mm:ss'), // 消息時(shí)間 contactId: contactPayload.id, // 消息發(fā)送者id contactName: contactPayload.name, // 消息發(fā)送者昵稱 contactType: contactPayload.type, // 消息發(fā)送者類型 contactAvatar: contactPayload.avatar, // 消息發(fā)送者頭像 contactAlias: contactPayload.alias, // 消息發(fā)送者備注 } // redis中存儲(chǔ)私聊消息內(nèi)容 storageContactMessage(contact, storeMessage) // 消息是機(jī)器人自己發(fā)的 或者 消息發(fā)送到wechaty接收間隔大于半個(gè)小時(shí) if (isSelf || message.age() > 1800) return if (/^[a-zA-Z0-9]{17}$/.test(text)) { // 私聊識(shí)別vin反饋 contactIdentifyVin(contact, message, text) return } // 私聊消息以[弱]開(kāi)頭的信息為反饋信息。反饋給后臺(tái) 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 }至于其他的一些生命周期以及鉤子函數(shù)。大家可以參考文檔做出屬于自己的應(yīng)用機(jī)器人

封裝say方法

因?yàn)閟ay()方法會(huì)在多處調(diào)用,并且要根據(jù)不同的消息類型發(fā)送的內(nèi)容做出不同的數(shù)據(jù)處理。大家以后也會(huì)遇到,因此這里將我封裝的一個(gè)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 機(jī)器人發(fā)送消息 * @param {*} messageType 消息類型 7文本,1文件,6圖片,3個(gè)人名片,14卡片鏈接 9小程序 * @param {*} sender 來(lái)源 房間 || 個(gè)人 實(shí)例對(duì)象 * @param {*} messageInfo 內(nèi)容 *//** * messageInfo 數(shù)據(jù)結(jié)構(gòu) * tetx: string 文本消息必傳 * fileUrl: string 文件消息必傳 * imageUr: string 圖片消息必傳 * cardId: string 個(gè)人名片消息必傳 * linkInfo: object 卡片消息必傳 * description: string 描述 * thumbnailUrl: string 縮略圖地址 * title: string 標(biāo)題 * url: string 跳轉(zhuǎn)地址 */async function say({ messageType, sender, messageInfo }) { // console.log(messageType); // console.log(sender); // console.log(messageInfo); try { return new Promise(async (resolve, reject) => { // 機(jī)器人信息 const { bot } = globalData // 枚舉消息類型 const MessageType = { text: 7, // 文本 fromFile: 1, // 文件 fromUrl: 6, // 圖片 contactCard: 3, // 個(gè)人名片 urlLink: 14, // 卡片鏈接 miniProgram: 9, // 小程序 } // 內(nèi)容不存在 if (!messageInfo) { return } // 要發(fā)送的消息內(nèi)容 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; // 個(gè)人名片 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認(rèn)證身份,你也來(lái)試試吧', pagePath: 'pages/home/home.html', description: '身份管家', thumbUrl: '30590201000452305002010002041092541302033d0af802040b30feb602045df0c2c5042b777875706c6f61645f31373533353339353230344063686174726f6f6d3131355f313537363035393538390204010400030201000400', thumbKey: '42f8609e62817ae45cf7d8fefb532e83', }); break; default: break; } delay.execute(async () => { sender.say(content) .then(value => { console.log(`======================== 機(jī)器人回復(fù) ========================/n/n`) resolve() }) .catch(reason => { console.log(`======================== 機(jī)器人發(fā)送消息失敗 ========================/n/n`, reason) }) }) }) } catch (error) { console.log('error in say', error); }}module.exports = { say}對(duì)了,對(duì)于onMessage事件中消息格式的判斷我也做了一層封裝,這里給大家提供參考。

/** * @method messageProcessing 處理消息內(nèi)容 * @param {*} message */async function messageProcessing(message) { try { return new Promise(async (resolve, reject) => { console.log(`======================== messageProcessing ========================/n/n`) // 消息詳情 const messagePayload = message.payload // 獲取消息的文本內(nèi)容。 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} ========================/n/n`) text = '[你收到一個(gè)未知消息,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 附件 1 case Message.Type.Attachment: console.log(`======================== 消息類型為附件:${messagePayload.type} ========================/n/n`) // 暫時(shí)不知道怎么處理 text = '[你收到一個(gè)附件,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 音頻 2 case Message.Type.Audio: console.log(`======================== 消息類型為音頻:${messagePayload.type} ========================/n/n`) text = '[你收到一條語(yǔ)音消息,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 個(gè)人名片 3 case Message.Type.Contact: console.log(`======================== 消息類型為個(gè)人名片:${messagePayload.type} ========================/n/n`) text = '[你收到一張個(gè)人名片,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 聊天記錄 4 case Message.Type.ChatHistory: console.log(`======================== 消息類型為聊天記錄:${messagePayload.type} ========================/n/n`) text = '[你收到聊天記錄,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 表情符號(hào) 5 case Message.Type.Emoticon: console.log(`======================== 消息類型為表情符號(hào):${messagePayload.type} ========================/n/n`) text = '[你收到表情符號(hào),請(qǐng)?jiān)谑謾C(jī)上查看]' // 暫時(shí)不知道怎么處理 break; // 圖片 6 case Message.Type.Image: console.log(`======================== 消息類型為圖片:${messagePayload.type} ========================/n/n`) // 上傳圖片至阿里云獲取圖片地址 text = await addImageOss(message) break; // 文本 7 case Message.Type.Text: console.log(`======================== 消息類型為文本:${messagePayload.type} ========================/n/n`) // 去空格換行 text = text.replace(//s+/g, '') break; // 位置 8 case Message.Type.Location: console.log(`======================== 消息類型為位置:${messagePayload.type} ========================/n/n`) text = '[你收到一條圖片消息,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 小程序 9 case Message.Type.MiniProgram: console.log(`======================== 消息類型為小程序:${messagePayload.type} ========================/n/n`) text = '[你收到一個(gè)小程序消息,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // GroupNote 10 case Message.Type.GroupNote: console.log(`======================== 消息類型為GroupNote:${messagePayload.type} ========================/n/n`) text = '[你收到一個(gè)GroupNote,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // Transfer 11 case Message.Type.Transfer: console.log(`======================== 消息類型為Transfer:${messagePayload.type} ========================/n/n`) text = '[你收到一個(gè)Transfer,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 紅包 12 case Message.Type.RedEnvelope: console.log(`======================== 消息類型為紅包:${messagePayload.type} ========================/n/n`) text = '[你收到一個(gè)紅包,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // Recalled 13 case Message.Type.Recalled: console.log(`======================== 消息類型為Recalled:${messagePayload.type} ========================/n/n`) text = '[你收到一個(gè)Recalled,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 鏈接地址 14 case Message.Type.Url: console.log(`======================== 消息類型為鏈接地址:${messagePayload.type} ========================/n/n`) // 暫時(shí)不知道怎么處理 text = '[你收到一條鏈接消息,請(qǐng)?jiān)谑謾C(jī)上查看]' break; // 視頻 15 case Message.Type.Video: console.log(`======================== 消息類型為視頻:${messagePayload.type} ========================/n/n`) text = '[你收到一個(gè)視頻消息,請(qǐng)?jiān)谑謾C(jī)上查看]' break; default: text = '' break; } resolve(text) }) } catch (error) { console.log('error in messageProcessing', error); }}為什么這樣做一層封裝處理,是因?yàn)槲覀兊臉I(yè)務(wù)需求要將聊天內(nèi)容進(jìn)行redis和mysql數(shù)據(jù)存儲(chǔ)。方便以后數(shù)據(jù)訂正和查詢使用。

實(shí)現(xiàn)的功能

基于wechaty我們實(shí)現(xiàn)的功能有那些呢?

— 根據(jù)關(guān)鍵詞,輸入車輛 VIN 對(duì)應(yīng)反饋出車型配件信息,并且將公司所在群區(qū)域的店鋪配件庫(kù)存信息反饋出來(lái) - 根據(jù)圖片識(shí)別車輛 VIN,然后識(shí)別 VIN 對(duì)應(yīng)反饋出車型配件信息,并且將公司所在群區(qū)域的店鋪配件庫(kù)存信息反饋出來(lái),圖片解釋接口采用的百度的接口 - 關(guān)鍵詞指令綁定群信息。根據(jù)不同指令進(jìn)行群配置。 - redis 存儲(chǔ)機(jī)器人信息。將群信息存儲(chǔ)并同步在 redis 和 mysql 中。后臺(tái)配置對(duì)應(yīng)群是否開(kāi)啟某些功能等等。 - 每月月初定時(shí)發(fā)送每個(gè)群的采購(gòu)信息。銷量信息等等。 - 機(jī)器人登錄調(diào)用釘釘接口,在釘釘群內(nèi)發(fā)布機(jī)器人登錄或者退出的提醒信息 - 群邀請(qǐng)自動(dòng)通過(guò),入群以后做出相應(yīng)數(shù)據(jù)存儲(chǔ)邏輯判斷功能設(shè)置等 - 好友申請(qǐng)自動(dòng)通過(guò),關(guān)鍵字申請(qǐng)自動(dòng)邀請(qǐng)入不同的群,功能覆蓋等等 - 等等功能。 以上功能支持還在不斷開(kāi)發(fā)和摸索中。但已經(jīng)滿足目前我們的業(yè)務(wù)需求。

最后

你如果想用我這些東西,拉下代碼config.js里換下token和一些配置信息就可以,當(dāng)然我在不停更新,功能會(huì)越來(lái)越多,所以倉(cāng)庫(kù)中代碼和文中會(huì)有些不一樣,使用時(shí)簡(jiǎn)單看下代碼,都寫了詳細(xì)注釋,也很簡(jiǎn)單,但是因?yàn)榇a中很多地方涉及到來(lái)企業(yè)敏感信息。我只好重新寫來(lái)一份最小可執(zhí)行的demo,大家僅供參考。

?? 看完幫個(gè)忙

如果你覺(jué)得這篇內(nèi)容對(duì)你挺有啟發(fā),我想邀請(qǐng)你幫我個(gè)小忙:

  1. 點(diǎn)贊,讓更多的人也能看到這篇內(nèi)容(收藏不點(diǎn)贊,都是耍流氓 -_-)
  2. 關(guān)注公眾號(hào)「番茄學(xué)前端」,我會(huì)定時(shí)更新和發(fā)布前端相關(guān)信息和項(xiàng)目案例經(jīng)驗(yàn)供你參考。
  3. 加個(gè)好友, 雖然幫不上你大忙,但是一些業(yè)務(wù)問(wèn)題大家可以探討交流。



關(guān)鍵詞:機(jī)器,助手,企業(yè)

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉