摘要:項目背景龐大的用戶安裝量和恐怖的用戶使用時間,微信已成為國內移動互聯網上基礎設施級的應用。以一周時間開發的微信天氣查詢助手,就是一次技術驗證性嘗試。但就針對微信來說,不是最好的解決方案。
項目背景
龐大的用戶安裝量和恐怖的用戶使用時間,微信已成為國內移動互聯網上基礎設施級的應用。
以微信為平臺的客服服務有很多方式,比如訂閱號,服務號,小程序,但受到微信官方的限制,如果想做一個聊天群的自助客服, 或者私人訂制的客服,那就沒有了官方的自動化方案。例如場景一:折扣商品導購群里,只要@客服+產品名,就可以馬上反饋一條產品折扣信息。場景二:徒步群里參加一個活動報名,只需要@客服+活動名稱 就可以自助報名參加活動。
以Electron-nightmare一周時間開發的微信天氣查詢助手 ,就是一次技術驗證性嘗試。
依賴項
-
技術選擇 python、phantomjs 對比 Electron-nightmarepython的優點,python是非常棒的語言,有著廣闊的舞臺,在可預見的未來,python的熱度還將大幅提升。python有大量的三方庫支持,各種重量級的應用框架、前瞻性產品基本上都提供python接口,有大量的社區。就微信機器人來說,有非常優秀的itchat。但就針對微信來說,python不是最好的解決方案。因為python需要從底層web通訊協議開始分析,需要用抓包、分解、組裝,完完全全的實現一個web協議的機器人,這其間的開發工作量過大。而且越陷入web底層,將來隨著官方協議變更,維護版本的工作量也不容忽視。這背離了我們的初衷:在松耦合基礎上盡可能的專注業務本身。而且python還面臨2與3的不兼容的坑,也是需要考慮的問題。
phantomjs 一個headless的瀏覽器框架,基于webkit。第一次了解到phantomjs是用來做爬蟲,phantomjs非常適合動態頁面的內容爬取,而且phantomjs可以很方便的運行在linux服務器上,相對于普通的瀏覽器,phantomjs消耗的內存要少太多。但phantomjs也有一些問題。最大的問題就是phantomjs的headless,無法很簡單的測試代碼片段。而這幾年瀏覽器前端發展迅速,各種js新的特性不斷涌現,但phantomjs兼容性問題也凸顯:例如phantomjs對set Object就不支持。而且就整體性能而言,沒有V8引擎的支持的js,在執行效率上也要打折扣。所以我們還是要盡可能站在巨人的肩膀上拓展業務。
站在巨人的肩上,Electron。Electron是基于Google的Chromium框架,本來是專注快速開發跨平臺桌面應用。但基于高性能瀏覽器的Electron是天生的web自動化框架。配合Node.js的express,可以很簡單的實現一個RESTFul服務。而瀏覽器的可視化調試工具也大大提高了測試、調試效率。在Electron上做微信網頁版自動化更像是做一個plugin,這將減少了大量的的開發工作。
python, phantomjs, Electron在微信自動化上的對比功能 | python | phantomjs | Electron | |
---|---|---|---|---|
三方庫 | ★★★★★ | ★★★★ | ★★★★☆ | |
學習容易 | ★★★☆ | ★★★☆ | ★★★☆ | |
開發效率 | ★★ | ★★★☆ | ★★★★☆ | |
方便測試 | ★★☆ | ★★☆ | ★★★★☆ | |
運行效率 | ★★★★☆ | ★★☆ | ★★★☆ | |
維護簡單 | ★★☆ | ★★★☆ | ★★★★☆ | |
硬件要求低 | ★★★★☆ | ★★★☆ | ★★☆ |
從模塊分離的原則,在設計上,將微信機器人作為服務提供出來,這樣即可以在以后按照其約定方式(RESTFul)提供新的對接方式,也隔離的本身業務與機器人服務之間的耦合性,而且分離后,基礎服務可以遠程部署。設計思路如下圖
系統分解圖
微信網頁版代碼分析(模塊分析)當前(2017-11-30日)微信網頁版是基于AngularJS v1.2.28開發的,采用MVC分離模式。通過分析最主要的index.js源碼我們可以大概知道各個功能模塊的組合方式。
模塊分解圖
在了解網頁版模式后,接下來就是獲取,并調用對應的功能模塊,具體實現位于 wxinjector.js
var injector = angular.element(document.body).injector(); var F = { chatFactory:injector.get("chatFactory"), contactFactory:injector.get("contactFactory"), confFactory:injector.get("confFactory"), loginFactory:injector.get("loginFactory"), accountFactory:injector.get("accountFactory"), utilFactory:injector.get("utilFactory"), } var CTRLS = { appController:angular.element(document.body).scope(), loginController:angular.element(document.querySelector("body > div.login.ng-scope")).scope(), chatSenderController:angular.element(document.querySelector("#chatArea > div.box_ft.ng-scope")).scope(), }編寫測試片段代碼
chrome的dev-tools是非常好用的可視化測試工具,我們可以將功能片段一點一點的在console中測試后,再添加到項目的代碼中
測試獲得聯系人列表
angular.element(document.body).injector().get("contactFactory").getAllContacts();
測試發送文本消息
function SendMessage(ToUserName, msg){ var a = angular.element(document.querySelector("#editArea")).scope(); var confFactory = angular.element(document.body).injector().get("confFactory") var chatFactory = angular.element(document.body).injector().get("chatFactory"); a.editAreaCtn = msg; var e = chatFactory.createMessage({ ToUserName:ToUserName, MsgType: confFactory.MSGTYPE_TEXT, Content: a.editAreaCtn }); chatFactory.appendMessage(e), chatFactory.sendMessage(e), // O[chatFactory.getCurrentUserName()] = "", a.editAreaCtn = ""; }項目代碼組織
|____conf # 程序配置文件 | |____service.json | |____wxconf.js | |____cities.json # 城市氣象編碼表 |____lib # 模塊代碼 | |____weather.js | |____inject | | |____wxinjector.js | |____wxbot.js |____test # 測試代碼目錄 |____.gitignore |____package.json |____README.md |____sy-cli.js # 天氣問答業務程序 |____syaya.js # 微信基礎服務程序運行項目
cnpm install
啟動微信基礎服務 node syaya.js
啟動天氣問答業務 node sy-cli.js
掃碼登錄微信賬號(業務賬號)
用另一個微信賬號給業務賬號發信息測試
ubuntu server上運行electron
$sudo apt-get install xvfb libgtk2.0-0 libnotify-bin libgconf-2-4 libnss3 libasound2 libcap2-bin libcups2 libxtst6 libxss1 $xvfb-run node --harmony syaya.js
window.reload后,重新加載注入腳本的時機: 在事件"dom-ready"中注入
page.engin.on("dom-ready", function () { console.log("DOM-READY for inject..."); page.engin.inject("js", WX_HELPER_JS); });
express下,讓curl的post正常工作
var bodyParser = require("body-parser"); var app = express(); app.use(bodyParser.json({ limit: "100kb", type: "application/x-www-form-urlencoded" }));
js的sleep等待
async function sleep(ms) { return new Promise(resolve => { var tm = setTimeout(() => { console.log("clear", tm); clearTimeout(tm); resolve(0); }, ms); }); } async function test_sleep(){ var r = await sleep(2000); console.log(r); } test_sleep();
js協程處理單條消息, 偽代碼
var co = require("co"); function process_one_message(msg){ co(function *(message) { var action = yield extract_action(message); var r = yield action.do_step1(); if(r.status == "success"){ r = yield action.do_step2(); } r = yield action.do_final(); r = yield make_response(action, message); }, msg); }參考
在線XML、JSON數據互轉
有哪些免費開放且收錄城市較完整的天氣 API 接口
http://itchat.readthedocs.io/...
https://github.com/Chatie/wec...
https://shields.io
問題和建議如果有什么問題或者建議都可以在這個Issue和我討論
或者也可以在微博上聯系我:rockee阿木
或者微信聯系:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90126.html
摘要:在我看來,很多人起床第一件事情就是看微信消息,既然這樣,我就勉為其難每天早晨給小姐姐發送一則天氣預報吧。聯想起之前看到的一個開源庫,一個非常強大的微信調用類庫,正好滿足我當前的需要,那話不多說,開干。 前言 事情是這樣的,最近認識的一位小姐姐有每天早晨看天氣預報的習慣。在我看來,很多人起床第...
摘要:背景介紹智能語音助手作為物聯網領域的一個重要生態成員,是一種全新的交互方式,它能夠解放雙手,隨時提供服務,無須借助任何按鍵。學完該案例讓你對智能語音助手有一個全新的認識。快來打造你的智能語音助手吧 1. 背景介紹 智能語音助手作為物聯網領域的一個重要生態成員,是一種全新的交互方式,它能夠解...
摘要:作為一名菜雞,時常瞻仰大佬們的開源項目是非常必要的。后臺部分在這地址動漫你的名字同款開源,原文效果圖簡詩地址一款優雅的中國風記錄,包括端和端原文相關博客如何在一天之內完成一款具備屬性的產品簡書地址一個基于豆瓣仿網易云音樂的開源項目。 作為一名菜雞Android,時常瞻仰大佬們的開源項目是非常必要的。這里我為大家收集整理了10個優秀的開源項目,方便我們日常開發中學習! 作者:Listen...
閱讀 3336·2021-11-22 15:22
閱讀 2860·2021-10-12 10:12
閱讀 2154·2021-08-21 14:10
閱讀 3820·2021-08-19 11:13
閱讀 2840·2019-08-30 15:43
閱讀 3221·2019-08-29 16:52
閱讀 437·2019-08-29 16:41
閱讀 1426·2019-08-29 12:53