微信管理系統
……
安裝MySQL、Redis,然後建立函式庫(預設是test):
❯ mysql -u root -p
mysql > drop database test ;
Query OK, 9 rows affected (0.32 sec)
mysql > create database test ;
Query OK, 1 row affected (0.01 sec)
mysql > ^DBye
下載原始碼並安裝依賴:
❯ git clone https://github.com/dongweiming/wechat-admin
❯ cd wechat-admin
❯ virtualenv venv # 只支持Python 3
❯ source venv/bin/activate # 推荐使用autoenv
❯ venv/bin/pip install -r requirements.txt # 如果已经激活虚拟环境,`venv/bin/`这样的前缀可不加,下同
設定說明:自訂配置應該存放在local_settings.py(需建立)中,可重載config.py中的設置
安裝外掛(可選):
❯ git clone --recursive https://github.com/dongweiming/wechat-plugins
# 如果有额外插件配置,需要修改PLUGIN_PATHS和PLUGINS
外掛開發請移步:Plugins Page
初始化資料庫:
❯ export FLASK_APP = manager . py
❯ venv / bin / flask initdb
啟動服務:
❯ venv/bin/gunicorn app:app --bind 0.0.0.0:8100 -w 6 -t 0
PS: 如果是本地運行,可以不使用gunicorn,直接使用Flask的多執行緒偵錯模式:
❯ python app.py
造訪WEB頁面http://localhost:8100 使用微信掃碼登錄
登入成功後,啟動Celery Beat和Worker:
❯ venv/bin/celery -A wechat worker -l info -B
注意:第一次會拉取全部的聯絡人和各群聊成員列表,需要一點時間。觀察終端輸出了解初始化任務的完成情況。
假設已經安裝了Docker,執行以下命令即可。
❯ pip install docker-compose
❯ git clone --recursive https://github.com/dongweiming/wechat-plugins
❯ venv/bin/docker-compose build
❯ venv/bin/docker-compose run init # 只有在第一次才需要执行这步
❯ venv/bin/docker-compose run --service-ports -d web # 启动Web,地址也是 http://localhost:8100
❯ venv/bin/docker-compose run -d celery # 同样是在扫码登录之后再启动
安裝cnpm提高包裝下載速度:
❯ npm install -g cnpm --registry=https://registry.npm.taobao.org
安裝需要的套件:
❯ cnpm i
啟動調試環境:
❯ npm run dev
啟動成功預設會開啟http://localhost:8080 ,後端API仍使用的是http://localhost:8100/j
本地開發完畢透過以下方式建構:
❯ npm run build
刷新http://localhost:8100 就可以看到最新的效果了。
要注意修改表結構,每次都要:
❯ venv/bin/flask db migrate
❯ venv/bin/flask db upgrade
puid not found
這種錯誤呢?由於微信的設計,不提供一種唯一且穩定的uid之類的數據,所以wxpy設計了一套登錄用戶和其相關聯繫人、群聊、公眾號的映射關係,另外我修改了wxpy的實現,可以更多的獲得caption (暱稱, 性別, 省份, 城市)相關的內容,讓對像中的puid更穩定。
由於其中某些人/群的設定的改變,它的puid可能改變,在每次掃碼登入之後都會觸發一個更新這個映射關係的任務,讓這個映射關係更新成最新的。你遇到這種錯誤說明你需要重新登錄,或者,手動觸發這個任務:
from wechat . tasks import retrieve_data
retrieve_data . delay ()
Issue: #9
感謝@zgjhust 的意見
這是一個小型項目,我沒有添加Nginx支援,直接使用了Gunicorn。在用Gunicorn的時候使用了-t 0
也就是不超時。
這樣用的原因是專案中的sse需要一個長連接,而且從用戶打開登錄頁面到掃碼完成這個時間不好控制,就索性不超時了,但是也造成了未響應的請求不能及時釋放。事實上應該把/stream拿出來特殊處理,其他的路由需要有超時時間設定的(這塊,我會擇機重構一下)。
現在的解決辦法是指定更多的Worker數量,以及經常的重啟gunicorn(使用supervisor管理會更方便):
gunicorn app:app --bind 0.0.0.0:8100 -w 10 -t 0
或不用gunicorn,直接使用Flask的threaded參數啟動:
❯ cat app.py
...
if __name__ == ' __main__ ' :
app.run(host= ' 0.0.0.0 ' , port=8100, debug=app.debug, threaded=True)
❯ python app.py
不工作了通常有2個原因:
儘管我在celery上設計的重啟任務的功能,但是由於下線後重新重新掃碼登錄,這一步無法自動化,造成系統不工作了。
如果希望這個系統盡量長的工作,我的建議是:
from celery . task import periodic_task
from celery . task . control import revoke
def restart_listener ( sender , ** kw ):
task_id = r . get ( LISTENER_TASK_KEY )
if task_id :
revoke ( str ( task_id , 'utf-8' ))
task_id = app . send_task ( 'wechat.tasks.listener' )
r . set ( LISTENER_TASK_KEY , task_id )
stopped . connect ( restart_listener )
要注意訂閱操作應該發生在import wxpy/itchat之前。
是的,這是一個封裝wxpy/itchat的項目,說到底還是使用網頁微信(wx.qq.com),所以它的API的功能決定了本系統的能力。
解密手機微信API,把這些未開放的API的整合進來不太好,還可能引起法律上的問題。
問題可以看這個issue,有不少人遇到了,被封鎖之後沒有辦法解決。但可以注意讓它盡量不被封。經過這幾天的研究,我找到三個經驗: