手把手教你用圖靈機(jī)器人做微信公眾號(hào)自動(dòng)回復(fù)助手
本文首發(fā)于我的個(gè)人博客:尾尾部落
閱讀這篇文章,你將會(huì)學(xué)會(huì)以下內(nèi)容:
- 如何用flask搭建微信公眾平臺(tái)服務(wù)
- 如何將在微信公眾平臺(tái)調(diào)用圖靈機(jī)器人
- 如何用uwsgi+supervisor+nginx部署flask應(yīng)用
實(shí)驗(yàn)前提
- 一個(gè)可供外網(wǎng)訪問的主機(jī)(比如云服務(wù)器)
- 一個(gè)微信公眾號(hào)
- 一個(gè)圖靈機(jī)器人賬號(hào)
一、創(chuàng)建圖靈機(jī)器人
登陸圖靈機(jī)器人后,在個(gè)人主面點(diǎn)擊創(chuàng)建機(jī)器人
:
填寫相關(guān)信息:
[圖片上傳失敗...(image-f1a704-1531208389290)]
創(chuàng)建成功后,會(huì)自動(dòng)跳轉(zhuǎn)到
機(jī)器人設(shè)置
界面疚顷,在這里你可以對(duì)機(jī)器人進(jìn)行個(gè)性化定制。其實(shí),圖靈機(jī)器人提供簡(jiǎn)單的方法薯酝,快速接入微信公眾號(hào),這太沒有挑戰(zhàn)性了爽柒,對(duì)于喜歡搞事情的我們吴菠,肯定不能選擇這種方法。我們將鼠標(biāo)往下滑浩村,會(huì)出現(xiàn)
api接入
做葵,這個(gè)apikey就是我們等等用來接入微信公眾號(hào)的密鑰。至此心墅,圖靈機(jī)器人準(zhǔn)備完畢酿矢。
二、接入微信公眾號(hào)
跟著微信公眾平臺(tái)開發(fā)文檔一步一步往下走即可怎燥,只不過瘫筐,我們這里使用Flask
代替web.py
。為什么使用Flask
?
喜歡铐姚。任性策肝。
主要步驟:
1. 搭建服務(wù)
這里以Ubuntu 16.04.2 LTS的云服務(wù)器為例進(jìn)行說明。
準(zhǔn)備環(huán)境:
# 創(chuàng)建項(xiàng)目目錄
mkdir -p /var/www/weixin
# 進(jìn)入項(xiàng)目目錄
cd /var/www/weixin
# 安裝virtualenv包管理工具
apt install virtualenv
# 創(chuàng)建項(xiàng)目虛擬環(huán)境
virtualenv venv
# 激活環(huán)境
source venv/bin/activate
成功激活環(huán)境后,會(huì)出現(xiàn)(venv)
# 安裝Flask包
pip install flask
pip install requests
使用如下代碼創(chuàng)建run.py
文件
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0')
運(yùn)行python run.py
之众,這樣服務(wù)就啟動(dòng)起來了篇梭。
[圖片上傳失敗...(image-df9b44-1531208389290)]
你可以通過瀏覽器,輸入x.x.x.x:5000
來訪問你的服務(wù)酝枢。
這里的
x.x.x.x
是你云主機(jī)的ip地址恬偷,比如100.39.101.123
,下同帘睦。
如果成功袍患,就會(huì)看到如下界面:
接下來,進(jìn)入微信公眾平臺(tái)竣付,點(diǎn)擊
基本配置
點(diǎn)擊
修改配置
诡延,填寫服務(wù)器基本配置:這時(shí)候,你還沒有配置服務(wù)器信息古胆,還不能提交肆良。
先放著,我們回到云服務(wù)器逸绎,打開
run.py
文件惹恃,添加驗(yàn)證所需要的代碼:
# -*- coding:utf-8 -*-
from flask import Flask
from flask import request
import hashlib
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World!"
@app.route("/wechat", methods=["GET","POST"])
def weixin():
if request.method == "GET": # 判斷請(qǐng)求方式是GET請(qǐng)求
my_signature = request.args.get('signature') # 獲取攜帶的signature參數(shù)
my_timestamp = request.args.get('timestamp') # 獲取攜帶的timestamp參數(shù)
my_nonce = request.args.get('nonce') # 獲取攜帶的nonce參數(shù)
my_echostr = request.args.get('echostr') # 獲取攜帶的echostr參數(shù)
token = 'Your token' # 一定要跟剛剛填寫的token一致
# 進(jìn)行字典排序
data = [token,my_timestamp ,my_nonce ]
data.sort()
# 拼接成字符串
temp = ''.join(data)
# 進(jìn)行sha1加密
mysignature = hashlib.sha1(temp).hexdigest()
# 加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來源于微信
if my_signature == mysignature:
return my_echostr
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
保存棺牧,再運(yùn)行python run.py
回到微信公眾平臺(tái)巫糙,點(diǎn)擊提交
,確定
颊乘,收到提交成功
的提示参淹,表明配置成功。
回到云服務(wù)器乏悄,可以看到微信公眾平臺(tái)往我們的服務(wù)器發(fā)了一個(gè)GET請(qǐng)求浙值,并且我們成功地返回了驗(yàn)證信息。
再回到公眾平臺(tái)檩小,點(diǎn)擊啟用
开呐,可以看到服務(wù)器配置(已啟用)
的字樣。
至此识啦,我們已經(jīng)成功將我們的服務(wù)與微信公眾平臺(tái)連接上了负蚊。
2. 接入圖靈機(jī)器人
打開run.py
文件,添加代碼引入圖靈機(jī)器人:
# -*- coding:utf-8 -*-
from flask import Flask
from flask import request
import hashlib
import requests
import json
import time
import re
import xml.etree.ElementTree as ET
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World!"
@app.route("/wechat", methods=["GET","POST"])
def weixin():
if request.method == "GET": # 判斷請(qǐng)求方式是GET請(qǐng)求
my_signature = request.args.get('signature') # 獲取攜帶的signature參數(shù)
my_timestamp = request.args.get('timestamp') # 獲取攜帶的timestamp參數(shù)
my_nonce = request.args.get('nonce') # 獲取攜帶的nonce參數(shù)
my_echostr = request.args.get('echostr') # 獲取攜帶的echostr參數(shù)
token = 'Your token' # 一定要跟剛剛填寫的token一致
# 進(jìn)行字典排序
data = [token,my_timestamp ,my_nonce ]
data.sort()
# 拼接成字符串
temp = ''.join(data)
# 進(jìn)行sha1加密
mysignature = hashlib.sha1(temp).hexdigest()
# 加密后的字符串可與signature對(duì)比颓哮,標(biāo)識(shí)該請(qǐng)求來源于微信
if my_signature == mysignature:
return my_echostr
else:
# 解析xml
xml = ET.fromstring(request.data)
toUser = xml.find('ToUserName').text
fromUser = xml.find('FromUserName').text
msgType = xml.find("MsgType").text
createTime = xml.find("CreateTime")
# 判斷類型并回復(fù)
if msgType == "text":
content = xml.find('Content').text
return reply_text(fromUser, toUser, reply(fromUser, content))
else:
return reply_text(fromUser, toUser, "我只懂文字")
def reply_text(to_user, from_user, content):
"""
以文本類型的方式回復(fù)請(qǐng)求
"""
return """
<xml>
<ToUserName><![CDATA[{}]]></ToUserName>
<FromUserName><![CDATA[{}]]></FromUserName>
<CreateTime>{}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{}]]></Content>
</xml>
""".format(to_user, from_user, int(time.time() * 1000), content)
def reply(openid, msg):
'''
使用圖靈機(jī)器人
'''
data = {"key": "Your tuling apikey", "info": msg, "userid": openid}# 使用自己的key
r = requests.post('http://openapi.tuling123.com/openapi/api', data)
text = json.loads(r.text)
return text['text'].encode('utf-8')
if __name__ == "__main__":
app.run(host='0.0.0.0',port=80)
保存后家妆,運(yùn)行
python run.py
這時(shí)候,你就可以在你的手機(jī)微信公眾號(hào)窗口調(diào)戲圖靈機(jī)器人了:
到這里冕茅,你以為結(jié)束了嗎伤极?還早著呢蛹找。
三、部署flask服務(wù)
正如你所看到了哨坪,當(dāng)你運(yùn)行
python run.py
庸疾,服務(wù)就運(yùn)行起來了,但是當(dāng)你按下ctrl+c
或者斷開與云服務(wù)器的連接当编,服務(wù)就自動(dòng)掉線了届慈,這時(shí)候,你再呼喚圖靈機(jī)器人忿偷,它就無(wú)應(yīng)答了金顿。因此,直接運(yùn)行python run.py
這種方法只適合本地開發(fā)調(diào)試鲤桥,線上用這種方法不穩(wěn)定揍拆,我們需要使用uwsgi
。
安裝uwsgi
茶凳,supervisor
和uwsgi
apt-get install nginx
apt-get install supervisor
pip install uwsgi
安裝完成后嫂拴,我們來測(cè)試一下uwsgi
。我們先將run.py
中的port
去掉贮喧,保留host
:
保存筒狠。
python2運(yùn)行:
uwsgi --socket 0.0.0.0:5000 --protocol=http -w run:app
python3運(yùn)行:
uwsgi --socket 0.0.0.0:5000 -w run:app
然后再在瀏覽器上輸入http://x.x.x.x:5000
,看到正確輸出Hello World!
塞淹,就表示uwsgi安裝正確窟蓝,我們就可以使用uwsgi來啟動(dòng)flask服務(wù)了罪裹。同時(shí)饱普,我們可以看到服務(wù)器上輸出如下信息:
但是這種方法還是每次需要從命令行啟動(dòng),太麻煩了状共。下面我們來做一些配置套耕。在
/var/www/weixin/
目錄下創(chuàng)建配置文件weixin_uwsgi.ini
:
[uwsgi]
module = run:app
master = true
processes = 4
chdir = /var/www/weixin
socket = /var/www/weixin/weixin_uwsgi.sock
logto = /var/www/weixin/%n.log
chmod-socket = 777
vacuum = true
配置完成后運(yùn)行:
uwsgi --ini weixin_uwsgi.ini
就會(huì)在項(xiàng)目目錄下生成
weixin_uwsgi.sock
文件,這個(gè)文件一般大小為0峡继,它是用來和Nginx
通信的冯袍。這時(shí)候,我們不能
ctrl+c
殺掉這個(gè)進(jìn)程碾牌,重新開一個(gè)連接窗口
# 進(jìn)入項(xiàng)目目錄
cd /var/www/weixin
# 激活虛擬環(huán)境
source venv/bin/activate
# 查看當(dāng)前目錄下的文件
ll
[圖片上傳失敗...(image-305b8a-1531208389290)]
接下來康愤,我們開始配置Nginx
。
刪除nginx的默認(rèn)配置文件:
rm /etc/nginx/sites-enabled/default
然后在我們的項(xiàng)目目錄下創(chuàng)建nginx配置文件vim /var/www/weixin/weixin_nginx.conf
:
server {
listen 80;
server_name x.x.x.x; #公網(wǎng)地址
location / {
include uwsgi_params;
uwsgi_pass unix:/var/www/weixin/weixin_uwsgi.sock;
}
}
[圖片上傳失敗...(image-aa0c39-1531208389291)]
保存退出舶吗。將weixin_nginx.conf
軟鏈接到nginx的conf.d
目錄下:
sudo ln -s /var/www/weixin/weixin_nginx.conf /etc/nginx/conf.d/
重啟nginx服務(wù):
/etc/init.d/nginx restart
[圖片上傳失敗...(image-66f57-1531208389291)]
看到ok就表示nginx正常啟動(dòng)征冷。這時(shí)不出意外,你在瀏覽器中輸入http://x.x.x.x
誓琼,就可以看到Hello World!
检激。
[圖片上傳失敗...(image-a221af-1531208389291)]
這樣我們就不用再加5000的端口號(hào)肴捉,直接用ip地址和默認(rèn)的80端口就可以訪問了。
使用supervisor引導(dǎo)uwsgi
這時(shí)候我們?cè)倩氐角耙粋€(gè)運(yùn)行
uwsgi
的窗口叔收,uwsgi
保持運(yùn)行的狀態(tài)齿穗,我們不能斷開它,也不能做其他任何事情饺律,一旦服務(wù)器斷開連接窃页,,uwsgi
服務(wù)就會(huì)關(guān)閉复濒,weixin_uwsgi.sock
文件就會(huì)消失腮出,這時(shí)再訪問網(wǎng)站,nginx就會(huì)報(bào)錯(cuò):[圖片上傳失敗...(image-d88d2-1531208389291)]
所以
supervisor
就派上用場(chǎng)了芝薇。我們?cè)陧?xiàng)目目錄下創(chuàng)建supervisor配置文件vim /var/www/weixin/weixin_supervisor.conf
:
[program:weixin]
# 啟動(dòng)命令入口
command=/var/www/weixin/venv/bin/uwsgi /var/www/weixin/weixin_uwsgi.ini
# 命令程序所在目錄
directory=/var/www/weixin
#運(yùn)行命令的用戶名
user=root
autostart=true
autorestart=true
#日志地址
stdout_logfile=/var/www/weixin/weixin_supervisor.log
保存退出后胚嘲,啟動(dòng)supervisor服務(wù)
service supervisor start
至此,flask就可以穩(wěn)定運(yùn)行了洛二。