剛剛創建這個公眾號的時候,我的一個同事就找我的公眾號聊天,但是那個時候我的公眾號還是僅支持根據關鍵詞,如果要做到支持智能回復,那基本上就是不可能。然后我結合我之前做的微信自動回復機器人的經歷,我首先就想到了圖靈機器人。是不是可以把圖靈機器人和微信公眾號進行連接呢?於是我開始查看
圖靈機器人的接口文檔:https://www.kancloud.cn/turing/www-tuling123-com/718227
微信公眾號:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html
發現其實只要我們擁有一個公網的web服務器地址,微信公眾號和web服務器進行通信,我們對接收的微信公眾號消息進行解析轉發給圖靈機器人,圖靈機器人根據我們請求的內容返回對應的回復,我們再將回復返回給微信公眾號即可。整個流程如下:
微信公眾號服務器的配置
首先我們需要搭建一個web服務器用於接收微信公眾號的請求,我們可以通過flask進行搭建。安裝flask庫的方法可以參考我們之前文章中的安裝方法python學習三——庫安裝。
在pycharm中中新建一個工程和main.py文件,輸入如下內容:
from flask import Flask
from flask import request
app = Flask(__name__)
def index():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0')
運行成功后,你可以在瀏覽器上訪問自己的服務器
接下來我們需要將這個服務器映射到公網上獲取一個公網url,我這邊使用的ngrok,將下載的exe文件打開后,輸入“ngrok http 80”,就出現一個公網映射地址如下圖:
將紅色框標注的地址拷貝到微信公眾號的開發-基本配置-服務器配置的服務器地址(此時不要點擊保存,因為我們需要對字段信息進行處理,否者是不會校驗通過的)
查看微信公眾號的開發手冊,可以了解到信息處理流程。
# -*- coding:utf-8 -*-
from flask import Flask
from flask import request
import hashlib
app = Flask(__name__)
def index():
return "Hello World!"
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()
# 拼接成字符串,進行hash加密時需要為字符串類型
temp = ''.join(data)
#創建一個hash對象
s = hashlib.sha1()
#對創建的hash對象更新需要加密的字符串
s.update(data.encode("utf-8"))
#加密處理
mysignature = s.hexdigest()
# 加密后的字符串可與signature對比,標識該請求來源於微信
if my_signature == mysignature:
return my_echostr
else:
return ""
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
再次運行程序,此時再在微信公眾號的配置頁面點擊提交可以看到提交成功的提示信息。然后再我們的ngrok上可以看到200 OK的GET連接信息
這樣我們的完成了一步——服務器的配置,將微信公眾號和我們搭建的web服務器進行通信。
接入圖靈機器人
剛剛我們在程序中判斷了一個GET的連接信息就是進行通信認證的程序,若連接信息是一個POST請求那便是我們公眾號的轉發信息了。接下來我們需要對這個POST信息進行處理,提取出消息內容轉發給圖靈機器人即可。
# -*- coding:utf-8 -*-
from flask import Flask
from flask import request
import hashlib
import tyuling_replay
import time
import re
import ReplayFromExcel
import xml.etree.ElementTree as ET
app = Flask(__name__)
def index():
return "Hello World!"
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參數
# my_token = request.args.get('token')
print(my_signature)
print(my_timestamp)
print(my_nonce)
print(my_echostr)
# print(my_token)
token = '123456' # 一定要跟剛剛填寫的token一致
# 進行字典排序
data = [token,my_timestamp ,my_nonce ]
data.sort()
# 拼接成字符串,進行hash加密時需為字符串
data = ''.join(data)
#創建一個hash對象
s = hashlib.sha1()
#對創建的hash對象更新需要加密的字符串
s.update(data.encode("utf-8"))
#加密處理
mysignature = s.hexdigest()
print("handle/GET func: mysignature, my_signature: ", mysignature, my_signature)
# 加密后的字符串可與signature對比,標識該請求來源於微信
if my_signature == mysignature:
return my_echostr
else:
return ""
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
#根據公眾號粉絲的ID生成符合要求的圖靈機器人userid
if len(fromUser)>31:
tuling_userid = str(fromUser[0:30])
else:
tuling_userid = str(fromUser)
tuling_userid=re.sub(r'[^A-Za-z0-9]+', '', tuling_userid)
#調用圖靈機器人API返回圖靈機器人返回的結果
tuling_replay_text = tyuling_replay.get_message(content,tuling_userid)
return reply_text(fromUser, toUser, tuling_replay_text)
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)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
我們將圖靈機器人的調用封裝在一個tyuling_replay模塊中,具體內容如下:
import json
import urllib.request
tuling_key='圖靈機器人的APIkey'
api_url = "http://openapi.tuling123.com/openapi/api/v2"
def get_message(message,userid):
req = {
"perception":
{
"inputText":
{
"text": message
},
"selfInfo":
{
"location":
{
"city": "",
"province": "",
"street": ""
}
}
},
"userInfo":
{
"apiKey": tuling_key,
"userId": userid
}
}
req = json.dumps(req).encode('utf8')
http_post = urllib.request.Request(api_url, data=req, headers={'content-type': 'application/json'})
response = urllib.request.urlopen(http_post)
response_str = response.read().decode('utf8')
response_dic = json.loads(response_str)
results_code = response_dic['intent']['code']
print(results_code)
if results_code == 4003:
results_text = "4003:%s"%response_dic['results'][0]['values']['text']
else:
results_text = response_dic['results'][0]['values']['text']
return results_text
詳細的內容可以參考圖靈機器人的API接入文檔。
至此,我們的微信公眾號自動回復機器人就做好了,但是免費版的圖靈機器人每天的調用次數也是有限,如何徹底解決這個問題呢?我們后續再講我們的方法。