When the official account was just created, a colleague of mine chatted with my official account. But at that time, my official account only supported keyword based response. If you want to support intelligent response, it is basically impossible. Then I thought of Turing robot in combination with my previous experience of wechat automatic reply robot. Is it possible to connect Turing robot with wechat official account? So I started checking
Interface document of Turing robot: https://www.kancloud.cn/turing/www-tuling123-com/718227 Wechat official account: https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html
It is found that as long as we have a public web server address, wechat official account communicates with the web server, we analyze the received wechat official account messages and forward them to Turing robot. Turing robot returns the corresponding reply according to our request, and then we return the reply to wechat official account. The whole process is as follows:
Configuration of wechat official account server
First, we need to build a web server to receive requests from wechat official account. We can build it through flask. For the method of installing the flask library, please refer to the installation method in our previous article python learning III - library installation.
Create a new project and main Py file, enter the following:
from flask import Flaskfrom flask import requestapp = Flask(__name__)@app.route("/")def index(): return "Hello World!"if __name__ == "__main__": app.run(host='0.0.0.0')
After running successfully, you can access your own server on the browser
Next, we need to map the server to the public network to obtain a public url. For the ngrok I use, open the downloaded exe file and enter "ngrok http 80", and a public network mapping address will appear, as shown in the following figure:
Copy the address marked in the red box to the server address of wechat official account development - basic configuration - server configuration (do not click save at this time, because we need to process the field information, otherwise it will not pass the verification)
Check the development manual of wechat official account to learn about the information processing process.
# -*- coding:utf-8 -*-from flask import Flaskfrom flask import requestimport hashlibapp = Flask(__name__)@app.route("/")def index(): return "Hello World!"@app.route("/wechat", methods=["GET","POST"])def weixin(): if request.method == "GET": # Judge whether the request method is GET request my_signature = request.args.get('signature') # Get carried signature parameter my_timestamp = request.args.get('timestamp') # Get carried timestamp parameter my_nonce = request.args.get('nonce') # Get carried nonce parameter my_echostr = request.args.get('echostr') # Get carried echostr parameter token = 'Your token' # Be sure to follow the token unanimous # Sort dictionary data = [token,my_timestamp ,my_nonce ] data.sort() # Concatenate into strings for hash String type is required for encryption temp = ''.join(data) #Create a hash object s = hashlib.sha1() #For created hash Object update requires encrypted strings s.update(data.encode("utf-8")) #Encryption processing mysignature = s.hexdigest() # The encrypted string can be compared with signature to identify that the request comes from wechat if my_ Signature = = mysignature: return my_ Echostr else: return "" if__ Name_== "\u main\u": App Run (host='0.0.0.0', port=80)
Run the program again, and then click submit on the configuration page of wechat official account to see the prompt of successful submission. Then we can see the 200 OK GET connection information on our ngrok
In this way, we have completed one step - the configuration of the server, and communicated the wechat official account with the web server we built.
Access to Turing robot
Just now we judged in the program that a GET connection information is the program for communication authentication. If the connection information is a POST request, it is the forwarding information of our official account. Next, we need to process the POST information, extract the message content and forward it to Turing robot.
# -*- coding:utf-8 -*-from flask import Flaskfrom flask import requestimport hashlibimport tyuling_replayimport timeimport reimport ReplayFromExcelimport xml.etree.ElementTree as ETapp = Flask(__name__)@app.route("/")def index(): return "Hello World!"@app.route("/wechat", methods=["GET","POST"])def weixin(): if request.method == "GET": # Judge whether the request method is GET request my_signature = request.args.get('signature') # Get carried signature parameter my_timestamp = request.args.get('timestamp') # Get carried timestamp parameter my_nonce = request.args.get('nonce') # Get carried nonce parameter my_echostr = request.args.get('echostr') # Get carried echostr parameter # my_token = request.args.get('token') print(my_signature) print(my_timestamp) print(my_nonce) print(my_echostr) # print(my_token) token = '123456' # Be sure to follow the token unanimous # Sort dictionary data = [token,my_timestamp ,my_nonce ] data.sort() # Concatenate into string,carry out hash String required for encryption data = ''.join(data) #Create a hash object s = hashlib.sha1() #For created hash Object update requires encrypted strings s.update(data.encode("utf-8")) #Encryption processing mysignature = s.hexdigest() print("handle/GET func: mysignature, my_signature: ", mysignature, my_signature) # The encrypted string can be signature Compare and identify that the request comes from wechat if my_signature == mysignature: return my_echostr else: return "" else: # analysis 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") # Judge the type and reply if msgType == "text": content = xml.find('Content').text #According to the fans of official account ID Generate a Turing robot that meets the requirements 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) #Calling the Turing robot API to return the results returned by the Turing robot Turing_ Replay_ Text = tyuling_ Replay Get_ Message (content, turing_userid) return reply_text(fromUser, toUser, turing_replay_text) else: return reply_text(fromUser, toUser, "I only know text") def reply_text(to_user, from_user, content): "" "reply to request in the form of text type" "" 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_== "\u main\u": App Run (host='0.0.0.0', port=80)
We encapsulate the call of Turing robot in a tyuling_ In the replay module, the details are as follows:
import jsonimport urllib.requesttuling_key='Turing robot 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
For details, please refer to the API access document of Turing robot.
So far, our wechat official account automatic reply robot has been completed, but the free version of Turing robot is also limited in the number of calls per day. How can we completely solve this problem? We will talk about our method later.