圖靈機(jī)器人接口調(diào)用限制的解決? ??
????昨天我們的文章中說(shuō)到:使用圖靈機(jī)器人作為應(yīng)答機(jī)器人可以滿(mǎn)足要求,但是每天的回復(fù)條數(shù)在不花錢(qián)的情況下只能有100條。對(duì)于我這樣貧困線人口怎么可能每個(gè)月花費(fèi)99元就為了自動(dòng)回復(fù)呢。于是我就在想還有沒(méi)有其它的方式能夠快速做一個(gè)請(qǐng)求和應(yīng)答表呢?
????結(jié)合我之前工作上的經(jīng)驗(yàn),那我理解就是直接將請(qǐng)求語(yǔ)句的關(guān)鍵詞和需要的回復(fù)放在一個(gè)Excel表格中,然后直接通過(guò)查詢(xún)Excel表格這樣也能做到自動(dòng)回復(fù),說(shuō)干就干。整個(gè)流程如下圖:
????從流程圖上看我們還是在昨天的整體框架上新增后續(xù)的容錯(cuò)處理,一旦檢測(cè)到圖靈機(jī)器人API請(qǐng)求已用完之后,我們便啟動(dòng)我們的容錯(cuò)機(jī)制,在我們的Excel表格中去查找我們需要返回的內(nèi)容,若沒(méi)有找到的話,我們就直接返回一個(gè)固定語(yǔ)句告訴粉絲朋友,我們現(xiàn)在可能沒(méi)有聽(tīng)懂。
????整體已經(jīng)說(shuō)完了,接下來(lái)我們就開(kāi)始實(shí)干了。首先我們需要去讀取一個(gè)Excel表格,我使用的是xlrd這個(gè)庫(kù)(一樣啊,安裝方法參考之前的python學(xué)習(xí)三——庫(kù)安裝),由于之前我們已經(jīng)整理了一個(gè)Excel表格的讀寫(xiě)模塊——ReadAndWriteExcel.py,所以在這里我直接將這個(gè)模塊拿過(guò)來(lái)調(diào)用就好了,具體代碼見(jiàn)下:
# _*_coding=utf-8_*_
import xlwt
import xlrdclass WriteExcel:def __init__(self, sheet_name=None):"""初始化寫(xiě)表格對(duì)象:param sheet_name: 寫(xiě)表格的sheet名,默認(rèn)為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):"""向目標(biāo)sheet的某個(gè)行列寫(xiě)入值:param row: 目標(biāo)行:param col: 目標(biāo)列:param values: 想要寫(xiě)入的值"""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):"""讀取表格數(shù)據(jù):return: 返回讀取的表格數(shù)據(jù)"""data = xlrd.open_workbook(self.file_name)tables = data.sheets()[self.sheet_id]return tablesdef get_lines(self):"""讀取表格總行數(shù):return: 返回表格總行數(shù)"""tables = self.datareturn tables.nrowsdef get_cols(self):"""讀取表格總行數(shù):return: 返回表格總列數(shù)"""tables = self.datareturn tables.ncolsdef get_value(self, row, col):"""讀取表格中具體的行、列對(duì)應(yīng)的值:param row: 目標(biāo)行:param col: 目標(biāo)列:return: 返回目標(biāo)行、列的值"""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,"我是誰(shuí)")write_excel.save_file()
????接下來(lái)我們?nèi)缦屡粋€(gè)調(diào)用程序來(lái)調(diào)用ReadAndWriteExcel.py,實(shí)現(xiàn)我們根據(jù)第一列的關(guān)鍵詞返回第二列的回復(fù)內(nèi)容。代碼如下:
import ReadAndWriteExceldef excel_reply(msg):"""關(guān)鍵字回復(fù)"""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 '我愛(ài)你' in msg:return "我也愛(ài)你"elif '早安'in msg:return "早安啊,朋友"else:return '我沒(méi)有聽(tīng)懂你在說(shuō)什么,\n或許我休息一天,\n明天就能智商上線了~'pass
????這里我們不僅僅是通過(guò)讀取Excel,也將一些固定的回復(fù)放在代碼中進(jìn)行調(diào)試了。接下來(lái)我們來(lái)看看主程序的代碼。
# -*- 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": # 判斷請(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ù)# my_token = request.args.get('token')print(my_signature)print(my_timestamp)print(my_nonce)print(my_echostr)# print(my_token)token = '123456' # 一定要跟剛剛填寫(xiě)的token一致# 進(jìn)行字典排序data = [token,my_timestamp ,my_nonce ]data.sort()# 拼接成字符串,進(jìn)行hash加密時(shí)需為字符串data = ''.join(data)#創(chuàng)建一個(gè)hash對(duì)象s = hashlib.sha1()#對(duì)創(chuàng)建的hash對(duì)象更新需要加密的字符串s.update(data.encode("utf-8"))#加密處理mysignature = s.hexdigest()print("handle/GET func: mysignature, my_signature: ", mysignature, my_signature)# 加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來(lái)源于微信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")# 判斷類(lèi)型并回復(fù)if msgType == "text":content = xml.find('Content').text#根據(jù)公眾號(hào)粉絲的ID生成符合要求的圖靈機(jī)器人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)#調(diào)用圖靈機(jī)器人API返回圖靈機(jī)器人返回的結(jié)果tuling_replay_text = tyuling_replay.get_message(content,tuling_userid)#將圖靈機(jī)器人返回的內(nèi)容發(fā)送給粉絲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):"""以文本類(lèi)型的方式回復(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)if __name__ == "__main__":app.run(host='0.0.0.0',?port=80)
????我們?cè)诓榭磮D靈機(jī)器人的API文檔發(fā)現(xiàn)返回碼為4003時(shí)為API接口調(diào)用次數(shù)已用完,所以我們之前判斷4003是否在API接口的返回信息中,若存在,則圖靈機(jī)器人API調(diào)用已用完,需要使用Excel備選方案進(jìn)行答復(fù)。
????這樣我們的微信公眾號(hào)就再也不會(huì)出現(xiàn)服務(wù)器異常的報(bào)錯(cuò)了。
圖片和關(guān)注的自動(dòng)回復(fù)
????這樣配置了之后,我們還發(fā)現(xiàn)了一些問(wèn)題,如:由于使用了API開(kāi)發(fā)接口,導(dǎo)致公眾號(hào)默認(rèn)的自動(dòng)化回復(fù)無(wú)法使用了。一、同樣的關(guān)注的自動(dòng)回復(fù)也不能同時(shí)使用了;二、上面我們的回復(fù)也一直都是針對(duì)的文字,對(duì)于圖片消息無(wú)法進(jìn)行應(yīng)答。針對(duì)這兩個(gè)問(wèn)題,我們?cè)俅螌?duì)我們的程序進(jìn)行了優(yōu)化,新增了關(guān)注自動(dòng)回復(fù)和圖片回復(fù)原圖的情況。先上代碼:
if msgType == "text":content = xml.find('Content').text#根據(jù)公眾號(hào)粉絲的ID生成符合要求的圖靈機(jī)器人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)#調(diào)用圖靈機(jī)器人API返回圖靈機(jī)器人返回的結(jié)果tuling_replay_text = tyuling_replay.get_message(content,tuling_userid)#將圖靈機(jī)器人返回的內(nèi)容發(fā)送給粉絲if '4003' in tuling_replay_text:return reply_text(fromUser, toUser,ReplayFromExcel.excel_reply(content))else:return reply_text(fromUser, toUser, tuling_replay_text)#關(guān)注公眾號(hào)的自動(dòng)答復(fù)elif msgType == "event":Event = xml.find('Event').textif Event == "subscribe":subscribe_reply = "菜鳥(niǎo)小白終于等到你~\n" \"我們可以一起學(xué)習(xí)打卡,\n" \"一起努力成長(zhǎng)。\n" \"你煩悶時(shí),我還可以陪你聊天解悶哦~"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):"""以文本類(lèi)型的方式回復(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_image(to_user, from_user, mediaId):"""以圖片類(lèi)型的方式回復(fù)請(qǐng)求,返回原圖片"""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)
????通過(guò)對(duì)微信公眾號(hào)開(kāi)發(fā)文檔的閱讀,我們發(fā)現(xiàn)文字類(lèi)消息和圖片類(lèi)消息的區(qū)分在于msgType,文字類(lèi)型消息為text,圖片類(lèi)消息為image。對(duì)于圖片類(lèi)的消息圖片是保存在MediaId字段中,我們只需要將這個(gè)在返回給粉絲就好了,就是原圖返給粉絲。
????我們也發(fā)現(xiàn)新增粉絲關(guān)注時(shí),我們收到的是一個(gè)msgType是event,當(dāng)event中的包含的內(nèi)容是subscribe時(shí)為粉絲關(guān)注,我們判斷收到這樣的消息,就返回需要回復(fù)粉絲的內(nèi)容即可。
????當(dāng)然這樣還會(huì)有一些其他的問(wèn)題,如怎么回復(fù)音頻、視頻。這個(gè)方法都是類(lèi)似的,你們可以參考微信公眾號(hào)的開(kāi)發(fā)手冊(cè),自己想想該如何解決。
關(guān)注微信公眾號(hào)——菜鳥(niǎo)小白的學(xué)習(xí)分享
媽媽再也不用擔(dān)心我找不到路了
總結(jié)
以上是生活随笔 為你收集整理的教你搭建微信公众号自动答复机器人 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。