1. 程式人生 > >手把手教你用圖靈機器人做微信公眾號自動回覆助手

手把手教你用圖靈機器人做微信公眾號自動回覆助手

本文首發於我的個人部落格:尾尾部落

閱讀這篇文章,你將會學會以下內容:

  1. 如何用flask搭建微信公眾平臺服務
  2. 如何將在微信公眾平臺呼叫圖靈機器人
  3. 如何用uwsgi+supervisor+nginx部署flask應用

實驗前提

  • 一個可供外網訪問的主機(比如雲伺服器)
  • 一個微信公眾號
  • 一個圖靈機器人賬號

一、建立圖靈機器人

登陸圖靈機器人後,在個人主麵點擊建立機器人

填寫相關資訊:

建立成功後,會自動跳轉到機器人設定介面,在這裡你可以對機器人進行個性化定製。其實,圖靈機器人提供簡單的方法,快速接入微信公眾號,這太沒有挑戰性了,對於喜歡搞事情的我們,肯定不能選擇這種方法。


我們將滑鼠往下滑,會出現api接入,這個apikey就是我們等等用來接入微信公眾號的金鑰。

至此,圖靈機器人準備完畢。

二、接入微信公眾號

跟著微信公眾平臺開發文件一步一步往下走即可,只不過,我們這裡使用Flask代替web.py。為什麼使用Flask?

喜歡。任性。

主要步驟:

1. 搭建服務

這裡以Ubuntu 16.04.2 LTS的雲伺服器為例進行說明。
準備環境:

# 建立專案目錄
mkdir -p /var/www/weixin
# 進入專案目錄
cd /var/www/weixin
# 安裝virtualenv包管理工具
apt install virtualenv
# 建立專案虛擬環境
virtualenv venv # 啟用環境 source venv/bin/activate

成功啟用環境後,會出現(venv)

# 安裝Flask包
pip install flask
pip install requests

使用如下程式碼建立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'
)

執行python run.py,這樣服務就啟動起來了。

你可以通過瀏覽器,輸入x.x.x.x:5000來訪問你的服務。

這裡的x.x.x.x是你雲主機的ip地址,比如100.39.101.123,下同。

如果成功,就會看到如下介面:

接下來,進入微信公眾平臺,點選基本配置

點選修改配置,填寫伺服器基本配置:

這時候,你還沒有配置伺服器資訊,還不能提交。
先放著,我們回到雲伺服器,開啟run.py檔案,
新增驗證所需要的程式碼:

# -*- 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":     # 判斷請求方式是GET請求
        my_signature = request.args.get('signature')     # 獲取攜帶的signature引數
        my_timestamp = request.args.get('timestamp')     # 獲取攜帶的timestamp引數
        my_nonce = request.args.get('nonce')        # 獲取攜帶的nonce引數
        my_echostr = request.args.get('echostr')         # 獲取攜帶的echostr引數

        token = 'Your token'     # 一定要跟剛剛填寫的token一致

        # 進行字典排序
        data = [token,my_timestamp ,my_nonce ]
        data.sort()

        # 拼接成字串
        temp = ''.join(data)

        # 進行sha1加密
        mysignature = hashlib.sha1(temp).hexdigest()

        # 加密後的字串可與signature對比,標識該請求來源於微信
        if my_signature == mysignature:
            return my_echostr

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

儲存,再執行python run.py
回到微信公眾平臺,點選提交確定,收到提交成功的提示,表明配置成功。

回到雲伺服器,可以看到微信公眾平臺往我們的伺服器發了一個GET請求,並且我們成功地返回了驗證資訊。

再回到公眾平臺,點選啟用,可以看到伺服器配置(已啟用)的字樣。

至此,我們已經成功將我們的服務與微信公眾平臺連線上了。

2. 接入圖靈機器人

開啟run.py檔案,新增程式碼引入圖靈機器人:

# -*- 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":     # 判斷請求方式是GET請求
        my_signature = request.args.get('signature')     # 獲取攜帶的signature引數
        my_timestamp = request.args.get('timestamp')     # 獲取攜帶的timestamp引數
        my_nonce = request.args.get('nonce')        # 獲取攜帶的nonce引數
        my_echostr = request.args.get('echostr')         # 獲取攜帶的echostr引數

        token = 'Your token'     # 一定要跟剛剛填寫的token一致

        # 進行字典排序
        data = [token,my_timestamp ,my_nonce ]
        data.sort()

        # 拼接成字串
        temp = ''.join(data)

        # 進行sha1加密
        mysignature = hashlib.sha1(temp).hexdigest()

        # 加密後的字串可與signature對比,標識該請求來源於微信
        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")
        # 判斷型別並回復
        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):
    """
    以文字型別的方式回覆請求
    """
    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):
    '''
    使用圖靈機器人
    '''
    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)



儲存後,執行python run.py
這時候,你就可以在你的手機微信公眾號視窗調戲圖靈機器人了:

到這裡,你以為結束了嗎?還早著呢。

三、部署flask服務


正如你所看到了,當你執行python run.py,服務就執行起來了,但是當你按下ctrl+c或者斷開與雲伺服器的連線,服務就自動掉線了,這時候,你再呼喚圖靈機器人,它就無應答了。因此,直接執行python run.py這種方法只適合本地開發除錯,線上用這種方法不穩定,我們需要使用uwsgi

安裝uwsgisupervisoruwsgi

apt-get install nginx
apt-get install supervisor
pip install uwsgi

安裝完成後,我們來測試一下uwsgi。我們先將run.py中的port去掉,保留host:

儲存。
python2執行:

uwsgi --socket 0.0.0.0:5000 --protocol=http -w run:app

python3執行:

uwsgi --socket 0.0.0.0:5000 -w run:app

然後再在瀏覽器上輸入http://x.x.x.x:5000,看到正確輸出Hello World!,就表示uwsgi安裝正確,我們就可以使用uwsgi來啟動flask服務了。同時,我們可以看到伺服器上輸出如下資訊:

但是這種方法還是每次需要從命令列啟動,太麻煩了。下面我們來做一些配置。在/var/www/weixin/目錄下建立配置檔案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

配置完成後執行:

uwsgi --ini weixin_uwsgi.ini


就會在專案目錄下生成weixin_uwsgi.sock檔案,這個檔案一般大小為0,它是用來和Nginx通訊的。
這時候,我們不能ctrl+c殺掉這個程序,重新開一個連線視窗

# 進入專案目錄
cd /var/www/weixin
# 啟用虛擬環境
source venv/bin/activate
# 檢視當前目錄下的檔案
ll


接下來,我們開始配置Nginx
刪除nginx的預設配置檔案:

rm /etc/nginx/sites-enabled/default

然後在我們的專案目錄下建立nginx配置檔案vim /var/www/weixin/weixin_nginx.conf:

server {
    listen  80;
    server_name x.x.x.x; #公網地址
    location / {
        include      uwsgi_params;
        uwsgi_pass unix:/var/www/weixin/weixin_uwsgi.sock;
    }
}


儲存退出。將weixin_nginx.conf軟連結到nginx的conf.d目錄下:

sudo ln -s /var/www/weixin/weixin_nginx.conf  /etc/nginx/conf.d/

重啟nginx服務:

/etc/init.d/nginx restart


看到ok就表示nginx正常啟動。這時不出意外,你在瀏覽器中輸入http://x.x.x.x,就可以看到Hello World!

這樣我們就不用再加5000的埠號,直接用ip地址和預設的80埠就可以訪問了。

使用supervisor引導uwsgi


這時候我們再回到前一個執行uwsgi的視窗,uwsgi保持執行的狀態,我們不能斷開它,也不能做其他任何事情,一旦伺服器斷開連線,,uwsgi服務就會關閉,weixin_uwsgi.sock檔案就會消失,這時再訪問網站,nginx就會報錯:

所以supervisor就派上用場了。我們在專案目錄下建立supervisor配置檔案vim /var/www/weixin/weixin_supervisor.conf:

[program:weixin]
# 啟動命令入口
command=/var/www/weixin/venv/bin/uwsgi /var/www/weixin/weixin_uwsgi.ini
# 命令程式所在目錄
directory=/var/www/weixin
#執行命令的使用者名稱
user=root
autostart=true
autorestart=true
#日誌地址
stdout_logfile=/var/www/weixin/weixin_supervisor.log

儲存退出後,啟動supervisor服務

service supervisor start

至此,flask就可以穩定運行了。