通过前三篇的教程,相信大家基本上了解了微信开发的基本流程,先判断用户传入数据的类型MsgType,然后再获取用户输入的内容content,再对content进行处理,再返回给用户
现在我们来加点料,在完成了前三篇的基础上,我们把小黄鸡的自动回复功能整合到我们的微信中,我们最终实现的目的是这样的,当用户输入xhj指令后,进行和小黄鸡的对话中,这时候用户每输入的内容都将传给小黄鸡,然后小黄鸡进行回复,我们得到小黄鸡的回复内容后再返回给用户。
主要的问题,比如当用户输入“你好”,因为微信之前有翻译功能,那么我们的微信是如何判断你想要发送的是和小黄鸡的对话还是想要翻译“你好”这个单词?
解决这个问题就需要我们这次教程中所要用到的memcache,我们使用memcache来记录一个状态,比如mc.set(‘xhj’,' true’),那么当用户发送“你好”时,程序先从memcache中获取一个’xhj’ 这个key的值,如果是true 那么说明用户发送“你好”是为了和小黄鸡对话,当memcache中没有’xhj’ 这个key的时候,说明用户是想要翻译“你好”这个单词
这样问题看似就可以解决了,但是会有另外一个问题,当有两个用户同时发送“你好”时,A用户想要和小黄鸡对话,B用户想要翻译“你好”,那么此时,当memcache中有xhj且值为true,那么两个人得到的回复将都会是小黄鸡的回复,当没有xhj的key时,两个用户将都会得到“你好”这个词的翻译。
这样看,问题似乎又更复杂了,其实解决起来只要将memcache中的key设置为唯一,就是说A用户对应一个key,B用户对应另外一个key,那么问题就得到了解决,程序收到A用户的消息后,会在memcache中获取A用户的key,B用户获取B用户的key,这样就做到的相互不影响的效果,而要做到唯一,用户的fromUser值就是独一无二的,所以我们在memcache中可以这样设计key mc.set(fromUser+’_xhj’,'xhj’)
1. 小黄鸡有对外的接口,但是是收费的,我们屌丝就只能用另外的方法,使用抓包来看下数据的调用
可以看出,它的返回值是一个json格式的,response为小黄鸡返回的话,另外查看Params,还有一个ft=0.0这么个参数,一开始我都没有注意到,网上的别的帖子也没有提到它,所以一开始我一直调用不成功,写一个函数来调用小黄鸡,得到返回值
def xiaohuangji(ask):
ask = ask.encode('UTF-8')
enask = urllib2.quote(ask)
baseurl = r'http://www.simsimi.com/func/req?msg='
url = baseurl+enask+'&lc=ch&ft=0.0'
resp = urllib2.urlopen(url)
reson = json.loads(resp.read())
return reson
2. 使用memcache时先要在头上引入import pylibmc
使用memcache之前要先在SAE上启用memcache
根据自已的需要输入容量,这个应用比较小,5M就足够了
pylibmc的基本操作也很简单
2.1初始化一个memcache
mc = pylibmc.Client()Python代码
2.2添加key
mc.set(key,value)
2.3查找key
mc.get(key)
3.4删除key
mc.delete(key)
有了上面的memcache操作,那么就能实现小黄鸡的操作了
# -*- coding: utf-8 -*-
import hashlib
import web
import lxml
import time
import os
import urllib2,json,urllib
from lxml import etree
import pylibmc
import random
class WeixinInterface:
def __init__(self):
self.app_root = os.path.dirname(__file__)
self.templates_root = os.path.join(self.app_root, 'templates')
self.render = web.template.render(self.templates_root)
def GET(self):
#获取输入参数
data = web.input()
signature=data.signature
timestamp=data.timestamp
nonce=data.nonce
echostr=data.echostr
#自己的token
token="你的token"
#字典序排序
list=[token,timestamp,nonce]
list.sort()
sha1=hashlib.sha1()
map(sha1.update,list)
hashcode=sha1.hexdigest()
#sha1加密算法
#如果是来自微信的请求,则回复echostr
if hashcode == signature:
#print "true"
return echostr
#return '欢迎光临'
def POST(self):
str_xml = web.data()
xml = etree.fromstring(str_xml)
#xml = urllib.unquote(xml)
mstype=xml.find("MsgType").text
fromUser=xml.find("FromUserName").text
toUser=xml.find("ToUserName").text
mc = pylibmc.Client() #初始化一个memcache实例用来保存用户的操作
#下面创建一个欢迎消息,通过判断Event类型
if mstype == "event":
mscontent = xml.find("Event").text
if mscontent == "subscribe":
replayText = u'''欢迎关注本微信,这个微信是本人业余爱好所建立,也是想一边学习Python一边玩的东西,
现在还没有什么功能,只是弄了个翻译与豆瓣图书查询的小工具,你们有什么好的文章也欢迎反馈给我,我会不定期的分享给大家,输入help查看操作指令'''
return self.render.reply_text(fromUser,toUser,int(time.time()),replayText)
if mscontent == "unsubscribe":
replayText = u'我现在功能还很简单,知道满足不了您的需求,但是我会慢慢改进,欢迎您以后再来'
return self.render.reply_text(fromUser,toUser,int(time.time()),replayText)
if mstype == 'text':
content=xml.find("Content").text
if content.lower() == 'bye':
mc.delete(fromUser+'_xhj')
return self.render.reply_text(fromUser,toUser,int(time.time()),u'您已经跳出了和小黄鸡的交谈中,输入help来显示操作指令')
if content.lower() == 'xhj':
mc.set(fromUser+'_xhj','xhj')
return self.render.reply_text(fromUser,toUser,int(time.time()),u'您已经进入与小黄鸡的交谈中,请尽情的蹂躏它吧!输入bye跳出与小黄鸡的交谈')
if content.lower() == 'm':
musicList = [
[r'http://bcs.duapp.com/yangyanxingblog3/music/destiny.mp3','Destiny',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/5days.mp3','5 Days',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/Far%20Away%20%28Album%20Version%29.mp3','Far Away (Album Version)',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/%E5%B0%91%E5%B9%B4%E6%B8%B8.mp3',u'少年游',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/%E8%8F%8A.mp3',u'菊--关喆',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/%E7%A6%BB%E4%B8%8D%E5%BC%80%E4%BD%A0.mp3',u'离不开你',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/%E9%99%8C%E7%94%9F%E4%BA%BA.mp3',u'陌生人',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/%E8%8A%B1%E5%AE%B9%E7%98%A6.mp3',u'花容瘦',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/%E4%B9%98%E5%AE%A2.mp3',u'乘客',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/If%20My%20Heart%20Was%20A%20House.mp3',u'If My Heart Was A House',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/Hello%20Seattle%EF%BC%88Remix%E7%89%88%EF%BC%89.mp3',u'Hello Seattle(Remix版',u'献给我的宝贝晶晶'],
[r'http://bcs.duapp.com/yangyanxingblog3/music/Everybody%20Hurts.mp3',u'Everybody Hurts',u'献给我的宝贝晶晶']
]
music = random.choice(musicList)
musicurl = music[0]
musictitle = music[1]
musicdes =music[2]
return self.render.reply_music(fromUser,toUser,int(time.time()),musictitle,musicdes,musicurl)
#读取memcache中的缓存数据
mcxhj = mc.get(fromUser+'_xhj')
if mcxhj =='xhj':
res = xiaohuangji(content)
reply_text = res['response']
if u'微信' in reply_text:
reply_text = u"小黄鸡脑袋出问题了,请换个问题吧~" #这里小黄鸡会有广告,我索性就全给屏蔽了
return self.render.reply_text(fromUser,toUser,int(time.time()),reply_text)
if content == 'help':
replayText = u'''1.输入中文或者英文返回对应的英中翻译
2.输入m随机听一首音乐
3.输入xhj进入调戏小黄鸡模式'''
return self.render.reply_text(fromUser,toUser,int(time.time()),replayText)
elif type(content).__name__ == "unicode":
content = content.encode('UTF-8')
Nword = youdao(content)
return self.render.fanyi(fromUser,toUser,int(time.time()),Nword)
def youdao(word):
qword = urllib2.quote(word)
baseurl = r'http://fanyi.youdao.com/openapi.do?keyfrom=yyxweixintranslate&key=1581042900&type=data&doctype=json&version=1.1&q='
url = baseurl+qword
resp = urllib2.urlopen(url)
fanyi = json.loads(resp.read())
if fanyi['errorCode'] == 0:
if 'basic' in fanyi.keys():
trans = u'%s:\n%s\n%s\n网络释义:\n%s'%(fanyi['query'],''.join(fanyi['translation']),' '.join(fanyi['basic']['explains']),'\n'.join(fanyi['web'][0]['value']))
return trans
else:
trans = u'%s:\n基本翻译:%s\n'%(fanyi['query'],''.join(fanyi['translation']))
return trans
elif fanyi['errorCode'] == 20:
return u'对不起,要翻译的文本过长'
elif fanyi['errorCode'] == 30:
return u'对不起,无法进行有效的翻译'
elif fanyi['errorCode'] == 40:
return u'对不起,不支持的语言类型'
else:
return u'对不起,您输入的单词%s无法翻译,请检查拼写'% word
def xiaohuangji(ask):
ask = ask.encode('UTF-8')
enask = urllib2.quote(ask)
baseurl = r'http://www.simsimi.com/func/req?msg='
url = baseurl+enask+'&lc=ch&ft=0.0'
resp = urllib2.urlopen(url)
reson = json.loads(resp.read())
return reson
最终的效果如下
查看效果请扫描添加以下微信公众账号,有什么好的想法创意请输入“fk 内容”发送给我
4月8日更新,下面评论中有网友指出小黄鸡更改的地址,并需要cookies才可以,感谢@416548283
于是改了下代码
if mcxhj =='xhj':
res = xiaohuangji(content)
reply_text = res['sentence_resp']
if u'微信' in reply_text or u'微 信' in reply_text:
reply_text = u"小黄鸡脑袋出问题了,请换个问题吧~"
return self.render.reply_text(fromUser,toUser,int(time.time()),reply_text)
def xiaohuangji(ask):
ask = ask.encode('UTF-8')
enask = urllib2.quote(ask)
send_headers = {
'Cookie':'Filtering=0.0; Filtering=0.0; isFirst=1; isFirst=1; simsimi_uid=50840753; simsimi_uid=50840753; teach_btn_url=talk; teach_btn_url=talk; sid=s%3AzwUdofEDCGbrhxyE0sxhKEkF.1wDJhD%2BASBfDiZdvI%2F16VvgTJO7xJb3ZZYT8yLIHVxw; selected_nc=zh; selected_nc=zh; menuType=web; menuType=web; __utma=119922954.2139724797.1396516513.1396516513.1396703679.3; __utmc=119922954; __utmz=119922954.1396516513.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)'
}
baseurl = r'http://www.simsimi.com/func/reqN?lc=zh&ft=0.0&req='
url = baseurl+enask
req = urllib2.Request(url,headers=send_headers)
resp = urllib2.urlopen(req)
reson = json.loads(resp.read())
return reson
回顾之前的文章
使用python一步一步搭建微信公众平台(一)----基本的验证与鹦鹉学舌功能
使用python一步一步搭建微信公众平台(二)----搭建一个中英互译的翻译工具
使用python一步一步搭建微信公众平台(三)----添加用户关注后的欢迎信息与听音乐功能
使用python一步一步搭建微信公众平台(五)----使用mysql服务来记录用户的反馈
来源:oschina
链接:https://my.oschina.net/u/614988/blog/197998