圖靈機器人接口調用限制的解決? ??
????昨天我們的文章中說到:使用圖靈機器人作為應答機器人可以滿足要求,但是每天的回復條數在不花錢的情況下只能有100條。對于我這樣貧困線人口怎么可能每個月花費99元就為了自動回復呢。于是我就在想還有沒有其它的方式能夠快速做一個請求和應答表呢?
????結合我之前工作上的經驗,那我理解就是直接將請求語句的關鍵詞和需要的回復放在一個Excel表格中,然后直接通過查詢Excel表格這樣也能做到自動回復,說干就干。整個流程如下圖:
????從流程圖上看我們還是在昨天的整體框架上新增后續的容錯處理,一旦檢測到圖靈機器人API請求已用完之后,我們便啟動我們的容錯機制,在我們的Excel表格中去查找我們需要返回的內容,若沒有找到的話,我們就直接返回一個固定語句告訴粉絲朋友,我們現在可能沒有聽懂。
????整體已經說完了,接下來我們就開始實干了。首先我們需要去讀取一個Excel表格,我使用的是xlrd這個庫(一樣啊,安裝方法參考之前的python學習三——庫安裝),由于之前我們已經整理了一個Excel表格的讀寫模塊——ReadAndWriteExcel.py,所以在這里我直接將這個模塊拿過來調用就好了,具體代碼見下:
# _*_coding=utf-8_*_
import xlwt
import xlrdclass WriteExcel:def __init__(self, sheet_name=None):"""初始化寫表格對象:param sheet_name: 寫表格的sheet名,默認為1"""if sheet_name:self.sheetname = sheet_nameelse:self.sheetname = "1"self.workbook = xlwt.Workbook()self.worksheet = self.workbook.add_sheet(sheetname=self.sheetname)def write_values(self, row, col, values):"""向目標sheet的某個行列寫入值:param row: 目標行:param col: 目標列:param values: 想要寫入的值"""self.worksheet.write(row, col, values)def save_file(self, filename=None):"""保存表格:param filename: 保存的文件名"""if filename:self.filename = filenameelse:self.filename = "test.xls"self.workbook.save(self.filename)class OpenExcel:def __init__(self, file_name=None, sheet_id=None):"""初始化讀取Excel表格:param file_name: 需要讀取的表格名:param sheet_id: 需要讀取的表格sheet"""if file_name:self.file_name = file_nameself.sheet_id = sheet_idelse:self.file_name = 'example.xlsx'self.sheet_id = 0self.data = self.get_data()def get_data(self):"""讀取表格數據:return: 返回讀取的表格數據"""data = xlrd.open_workbook(self.file_name)tables = data.sheets()[self.sheet_id]return tablesdef get_lines(self):"""讀取表格總行數:return: 返回表格總行數"""tables = self.datareturn tables.nrowsdef get_cols(self):"""讀取表格總行數:return: 返回表格總列數"""tables = self.datareturn tables.ncolsdef get_value(self, row, col):"""讀取表格中具體的行、列對應的值:param row: 目標行:param col: 目標列:return: 返回目標行、列的值"""return self.data.cell_value(row, col)if __name__ == '__main__':openexcel = OpenExcel(file_name="work.xls",sheet_id=0)print (openexcel.get_lines())write_excel = WriteExcel()for j in range(0,openexcel.get_cols()):for i in range(0,openexcel.get_lines()):write_excel.write_values(i,j,openexcel.get_value(i,j))write_excel.write_values(100,100,"我是誰")write_excel.save_file()
????接下來我們如下弄一個調用程序來調用ReadAndWriteExcel.py,實現我們根據第一列的關鍵詞返回第二列的回復內容。代碼如下:
import ReadAndWriteExceldef excel_reply(msg):"""關鍵字回復"""keyword_read = ReadAndWriteExcel.OpenExcel(file_name="KeyWord.xlsx",sheet_id=0)for i in range(0,keyword_read.get_lines()):if msg in keyword_read.get_value(i,0):return keyword_read.get_value(i,1)if '你叫啥' in msg or '你叫啥名字' in msg:return '沃德天·維森莫·拉莫帥·帥德布耀'elif '我愛你' in msg:return "我也愛你"elif '早安'in msg:return "早安啊,朋友"else:return '我沒有聽懂你在說什么,\n或許我休息一天,\n明天就能智商上線了~'pass
????這里我們不僅僅是通過讀取Excel,也將一些固定的回復放在代碼中進行調試了。接下來我們來看看主程序的代碼。
# -*- 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 ETapp = 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參數# 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_echostrelse:return ""else:# 解析xmlxml = ET.fromstring(request.data)toUser = xml.find('ToUserName').textfromUser = xml.find('FromUserName').textmsgType = xml.find("MsgType").textcreateTime = xml.find("CreateTime")# 判斷類型并回復if msgType == "text":content = xml.find('Content').text#根據公眾號粉絲的ID生成符合要求的圖靈機器人useridif 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)#將圖靈機器人返回的內容發送給粉絲if '4003' in tuling_replay_text:return reply_text(fromUser, toUser,ReplayFromExcel.excel_reply(content))else: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)
????我們在查看圖靈機器人的API文檔發現返回碼為4003時為API接口調用次數已用完,所以我們之前判斷4003是否在API接口的返回信息中,若存在,則圖靈機器人API調用已用完,需要使用Excel備選方案進行答復。
????這樣我們的微信公眾號就再也不會出現服務器異常的報錯了。
圖片和關注的自動回復
????這樣配置了之后,我們還發現了一些問題,如:由于使用了API開發接口,導致公眾號默認的自動化回復無法使用了。一、同樣的關注的自動回復也不能同時使用了;二、上面我們的回復也一直都是針對的文字,對于圖片消息無法進行應答。針對這兩個問題,我們再次對我們的程序進行了優化,新增了關注自動回復和圖片回復原圖的情況。先上代碼:
if msgType == "text":content = xml.find('Content').text#根據公眾號粉絲的ID生成符合要求的圖靈機器人useridif 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)#將圖靈機器人返回的內容發送給粉絲if '4003' in tuling_replay_text:return reply_text(fromUser, toUser,ReplayFromExcel.excel_reply(content))else:return reply_text(fromUser, toUser, tuling_replay_text)#關注公眾號的自動答復elif msgType == "event":Event = xml.find('Event').textif Event == "subscribe":subscribe_reply = "菜鳥小白終于等到你~\n" \"我們可以一起學習打卡,\n" \"一起努力成長。\n" \"你煩悶時,我還可以陪你聊天解悶哦~"return reply_text(fromUser, toUser, subscribe_reply)elif msgType == "image":mediaId = xml.find('MediaId').textreturn reply_image(fromUser, toUser, mediaId)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_image(to_user, from_user, mediaId):"""以圖片類型的方式回復請求,返回原圖片"""return """<xml><ToUserName><![CDATA[{}]]></ToUserName><FromUserName><![CDATA[{}]]></FromUserName><CreateTime>{}</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[{}]]></MediaId></Image></xml>""".format(to_user, from_user, int(time.time() * 1000), mediaId)
????通過對微信公眾號開發文檔的閱讀,我們發現文字類消息和圖片類消息的區分在于msgType,文字類型消息為text,圖片類消息為image。對于圖片類的消息圖片是保存在MediaId字段中,我們只需要將這個在返回給粉絲就好了,就是原圖返給粉絲。
????我們也發現新增粉絲關注時,我們收到的是一個msgType是event,當event中的包含的內容是subscribe時為粉絲關注,我們判斷收到這樣的消息,就返回需要回復粉絲的內容即可。
????當然這樣還會有一些其他的問題,如怎么回復音頻、視頻。這個方法都是類似的,你們可以參考微信公眾號的開發手冊,自己想想該如何解決。
關注微信公眾號——菜鳥小白的學習分享
媽媽再也不用擔心我找不到路了
總結
以上是生活随笔 為你收集整理的教你搭建微信公众号自动答复机器人 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。