全面探索微信聊天機器人的實現
前言
有這樣一個需求,如何實現微信聊天的自動回覆,又如何實現微信群聊的多群同時回覆,調研了微信裡的功能,要實現多群回覆就要先發出訊息,然後長按可以多條轉發,但也只能實現最多九個群的轉發,這樣複雜的操作豈不是要把使用者累:hankey:。於是瞬間就想到了這樣一個功能,如圖:

微信群發
如果能這樣勾選群組後,直接輸入聊天內容呢,而且不管有多少群,照樣可以群發。那麼下面探索一下,目前網際網路裡能實現這種功能的所有方案,經過一段時間的調研,目前主要分為一下幾種方式實現:
- 微信Web端api封裝呼叫實現
- 基於Windows自動化技術,其實就是自動化Windows桌面版的微信,因為是客戶端,效率要比網頁端的快
- 網頁自動化技術,跟上一個技術有相似之處,這種方式就是對微信web端的自動化實現
- 微信Android端的自動化技術,這個需要一整套Android開發環境。
優缺點分析
這麼多的方案,各有優缺點,目前來看基於web端api封裝的方案是最合適,因為定製化更強,直接介面的呼叫相當穩定,windows桌面端的自動化和網頁自動化看似也很好,但實現難度上和穩定性上已經輸給了前者,然而Android端的自動化是同樣的,但它有一個不可替代的優點,就是可以實現自動傳送朋友圈,這點是前三者都實現不了的。
輪子的選擇
找到了方案,我們就要考慮有沒有輪子可以用,畢竟站在巨人的肩膀好乘涼,在github上找到如下幾種:
- ofollow,noindex">ItChat - Python
- wxpy - Python wxpy 在 itchat 的基礎上提供更豐富的擴充套件
- wechat - PHP 官方: 它可能是開發微信App的世界上最好的SDK
- wechaty - TypeScript Wechaty是一個用於微信個人賬戶的Bot SDK,可以幫助您在6行javascript中建立機器人,跨平臺支援包括Linux,Windows,Darwin(OSX / Mac)和Docker。
- WeChatAssist - JAVA 目前找到各個語言裡面最合適的幾個,選擇你最喜歡的一個,我選了wechaty - TypeScript ,因為它是目前為止最為活躍的一個,而且問題又是最少的一個。
輪子的部署
wechaty 是一個服務端,通過NodeJs實現,那我們只需要一個ubuntu伺服器,就可以完成部署
具體環境如下:
- node 環境
- pm2 對node服務管理
開發工具如下:
- webStorm 編碼工具
- express 用於介面的實現
輪子的昇華
wechaty官方給的例子只適合在服務終端直接使用,我們要實現的是在手機客戶端通過介面呼叫獲取登入二維碼,登入後獲取所有群組。下面是通過express框架寫的兩個介面。
如何通過介面獲取二維碼
router.get('/getScan', function (req, res, next) { const userKey = req.query.key; if (userKey) { const wechaty = new Wechaty(name: userKey}); Data.pushWechaty(userKey, wechaty); //快取Wechaty物件 wechaty.on('scan', (qrcode, status) => { const scanUrl = `https://api.qrserver.com/v1/create-qr-code/?data=${encodeURIComponent(qrcode)}`; console.log(`${userKey} Scan QR Code to login: ${status}\n ${scanUrl}`); try { res.send({ success: true, msg: "請掃描二維碼登入", data: { url: url } }) } catch (e) { } wechaty.start(); } }else { res.send({ success: false, msg: "使用者資訊不能為空" }) } }
如何獲取所有群組
router.get('/getRoomList', async function (req, res, next) { const userKey = req.query.key; if (userKey) { if (!Data.getWechatyStatus(userKey)) { res.send({ success: false, msg: "使用者未登入" }); return; } const wechaty = Data.getWechaty(userKey); if (!wechaty) { res.send({ success: false, msg: "使用者資訊快取異常,請重新登入" }); return; } const isOff = wechaty.logonoff(); console.log(JSON.stringify(isOff)); if (!isOff) { res.send({ success: false, msg: "使用者已退出,請重新登入" }); return; } const roomList = await wechaty.Room.findAll(); const topicList = await Promise.all( roomList.map(async room => await room.topic()), ); log.info('Bot', topicList); res.send({ success: true, data: roomList, msg: "獲取所有組資訊" }); } else { res.send({ success: false, msg: "使用者資訊不能為空" }) } });
這樣就實現了我們剛開始的需求,群組有了,發個訊息簡直不能再簡單了,只需要一句話:
const keyroom = await bot.Room.find({topic: '群名'}) keyroom.say("內容")
這樣手機端就可以只傳過來群名,我就可以這樣傳送訊息了。
總結
通過這次調研,可以跟那些收費的機器人平臺說拜拜了,最好是不用他們的平臺,因為你的聊天記錄都在他們的掌握之中,哪還有隱私可講。必須扼殺。