温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

微信开发之如何使用消息接口

发布时间:2021-03-12 10:02:54 来源:亿速云 阅读:147 作者:小新 栏目:移动开发

这篇文章主要介绍了微信开发之如何使用消息接口,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

                                                       承启

因为之前设计了要实现一个微信机器人,以向用户响应响应的文章,这个app十分地简单,并不需要特别深入的设计,而且我的想法是:拿来主义, 反正github上面那么多的用python写的博客系统,我只需要实现微信响应的部分,也就是从数据库中获取文章的数据,然后将文章的标题,url,图片等信息打包成xml格式返回给微信服务器,服务器再返回给用户。而且我发现,有菜单的会好很多,就像一个完整的app,可以直接点击察看某篇文章,而不是硬邦邦的回复。我是用别人写的一个博客系统进行改造——saepy-log.而这个博客系统又是基于tornado框架的,本来不打算染指tornado的,但是不得不硬着头皮钻研。其中遇到了很多困难,在sql语句的like写法,察看文档方面有了比较大的收获。

部署与开发

事先说明,由于我是各种折腾,所以可能照本篇文章做是做不成的。下载了saepy-log的源码后,按照这里的操作进行上传后,就可以将博客系统安装在sae平台上了,然后用svn把代码同步下来到本地工作目录,一切准备就绪。

我们要修改的是blog.py是博客的核心功能所在,还有modle.py是数据模型的关键所在,我们将要扩展数据模型功能,使之完成我们的微信功能。

在blog.py里面添加我们的微信功能类 weixin.py(由于是用tornado框架,所以方法与在django里面略有不同):

导入需要用到的包

# weixin used package import xml.etree.ElementTree as ET import urllib,urllib2,time,hashlib                                                 import tornado.wsgi import tornado.escape

主要是xml的解析和一些处理字符串的包,接下来我们定义weixin类的主体:

# 添加微信推送帐号 class WeiXinPoster(BaseHandler):     #-----------------------------------------------------------------------     # 处理get方法 对应check_signature     def get(self):         global TOKEN         signature = self.get_argument("signature")         timestamp = self.get_argument("timestamp")         nonce = self.get_argument("nonce")         echoStr = self.get_argument("echostr")         token = TOKEN         tmpList = [token,timestamp,nonce]         tmpList.sort()         tmpstr = "%s%s%s" % tuple(tmpList)         tmpstr = hashlib.sha1(tmpstr).hexdigest()                                                        if tmpstr == signature:             self.write(echoStr)             #return echoStr         else:             self.write(None);             #return None                                                                # 处理post方法,对应response_msg     def post(self):         global SORRY         # 从request中获取请求文本         rawStr = self.request.body         # 将文本进行解析,得到请求的数据         msg = self.parse_request_xml(ET.fromstring(rawStr))         # 根据请求消息来处理内容返回         query_str = msg.get("Content")         query_str = tornado.escape.utf8(query_str)         # TODO 用户发来的数据类型可能多样,所以需要判别         response_msg = ""         return_data = ""         # 使用简单的处理逻辑,有待扩展         if query_str[0] == "h":     # send help menu to user             response_msg = self.get_help_menu()     # 返回消息             # 包括post_msg,和对应的 response_msg             if response_msg:                 return_data = self.pack_text_xml(msg, response_msg)             else:                 response_msg = SORRY                 return_data = self.pack_text_xml(msg, response_msg)             self.write(return_data)         # 分类         elif query_str[0] =="c":             category = query_str[1:]             response_msg = self.get_category_articles(category)             if response_msg:                 return_data = self.pack_news_xml(msg, response_msg)             else:                 response_msg = SORRY                 return_data = self.pack_text_xml(msg, response_msg)             self.write(return_data)         # 列出文章列表         elif query_str[0] =="l":             response_msg = self.get_article_list()             if response_msg:                 return_data = self.pack_text_xml(msg, response_msg)             else:                 response_msg = SORRY                 return_data = self.pack_text_xml(msg, response_msg)             self.write(return_data)         # 直接获取某篇文章         elif query_str[0] == "a":             # 直接获取文章的id,然后在数据库中查询             article_id = int(query_str[1:])             # 进行操作             response_msg = self.get_response_article_by_id(article_id)             if response_msg:                 return_data = self.pack_news_xml(msg, response_msg)             else:                 response_msg = SORRY                 return_data = self.pack_text_xml(msg, response_msg)             self.write(return_data)                                                                    # 还要考虑其他         elif query_str[0] == "s":             keyword = str(query_str[1:])             # 搜索关键词,返回相关文章             response_msg = self.get_response_article(keyword)             # 返回图文信息             if response_msg:                 return_data = self.pack_news_xml(msg, response_msg)             else:                 response_msg = SORRY                 return_data = self.pack_text_xml(msg, response_msg)             self.write(return_data)                                                                    elif query_str[0] == "n":             response_msg = self.get_latest_articles()             # 返回图文信息             if response_msg:                 return_data = self.pack_news_xml(msg, response_msg)             else:                 response_msg = SORRY                 return_data = self.pack_text_xml(msg, response_msg)             self.write(return_data)         # 如果找不到,返回帮助信息         else:             response_msg = get_help_menu()             if response_msg:                 return_data = response_msg             else:                 return_data = SORRY             self.write(return_data)     # n for 获取最新的文章     def get_latest_articles(self):         global MAX_ARTICLE         global PIC_URL         article_list = Article.get_articles_by_latest()         article_list_length = len(article_list)         count = (article_list_length < MAX_ARTICLE) and article_list_length or MAX_ARTICLE         if article_list:             # 构造图文消息             articles_msg = {'articles':[]}             for i in range(0,count):                 article = {                         'title': article_list[i].slug,                         'description':article_list[i].description,                         'picUrl':PIC_URL,                         'url':article_list[i].absolute_url                     }                 # 插入文章                 articles_msg['articles'].append(article)                 article = {}             # 返回文章             return articles_msg                                                        #-----------------------------------------------------------------------     # 解析请求,拆解到一个字典里         def parse_request_xml(self,root_elem):         msg = {}         if root_elem.tag == 'xml':             for child in root_elem:                 msg[child.tag] = child.text  # 获得内容             return msg                                                    #-----------------------------------------------------------------------     def get_help_menu(self):         menu_msg = '''欢迎关注南苑随笔,在这里你能获得关于校园的资讯和故事。回复如下按键则可以完成得到相应的回应         h :帮助(help)         l :文章列表(article list)         f : 获得分类列表         n : 获取最新文章         a + 数字 :察看某篇文章 a2 察看第2篇文章         s + 关键字 : 搜索相关文章 s科研 察看科研相关         c + 分类名 : 获取分类文章 c校园生活 察看校园生活分类         其他 : 功能有待丰富'''         return menu_msg     #-----------------------------------------------------------------------     # 获取文章列表     def get_article_list(self):         # 查询数据库获取文章列表         article_list = Article.get_all_article_list()         article_list_str = "最新文章列表供您点阅,回复a+数字即可阅读: \n"         for i in range(len(article_list)):             art_id = str(article_list[i].id)             art_id = tornado.escape.native_str(art_id)                                                                        art_title = article_list[i].title             art_title = tornado.escape.native_str(art_title)                                                                        art_category = article_list[i].category             art_category = tornado.escape.native_str(art_category)                                                                                                                                   article_list_str +=  art_id + ' ' + art_title + ' ' + art_category + '\n'         return article_list_str                                                            # 按照分类查找     def get_category_articles(self, category):         global MAX_ARTICLE         global PIC_URL         article_list = Article.get_articles_by_category(category)         article_list_length = len(article_list)         count = (article_list_length < MAX_ARTICLE) and article_list_length or MAX_ARTICLE         if article_list:             # 构造图文消息             articles_msg = {'articles':[]}             for i in range(0,count):                 article = {                         'title': article_list[i].slug,                         'description':article_list[i].description,                         'picUrl':PIC_URL,                         'url':article_list[i].absolute_url                     }                 # 插入文章                 articles_msg['articles'].append(article)                 article = {}             # 返回文章             return articles_msg     #-----------------------------------------------------------------------     # 获取用于返回的msg     def get_response_article(self, keyword):         global PIC_URL         keyword = str(keyword)         # 从数据库查询得到若干文章         article = Article.get_article_by_keyword(keyword)         # 这里先用测试数据         if article:             title = article.slug             description = article.description             picUrl = PIC_URL             url = article.absolute_url             count = 1             # 也有可能是若干篇             # 这里实现相关逻辑,从数据库中获取内容                                                                        # 构造图文消息             articles_msg = {'articles':[]}             for i in range(0,count):                 article = {                         'title':title,                         'description':description,                         'picUrl':picUrl,                         'url':url                     }                 # 插入文章                 articles_msg['articles'].append(article)                 article = {}             # 返回文章             return articles_msg         else:             return                                                        def get_response_article_by_id(self, post_id):         global PIC_URL         # 从数据库查询得到若干文章         article = Article.get_article_by_id_detail(post_id)         # postId为文章id         if article:             title = article.slug             description = article.description             picUrl = PIC_URL             url = article.absolute_url             count = 1             # 这里实现相关逻辑,从数据库中获取内容                                                                        # 构造图文消息             articles_msg = {'articles':[]}             for i in range(0,count):                 article = {                         'title':title,                         'description':description,                         'picUrl':picUrl,                         'url':url                     }                 # 插入文章                 articles_msg['articles'].append(article)                 article = {}             # 返回文章             return articles_msg         else:             return

可见app的难度并不大,还是和上次使用微信API里面的和接近,需要用到的几个全局变量,需要自己定义,如token,如PIC_URL等。程序原理其实就是解析用户请求,h开头,则提供帮助菜单,a开头加数字的,就提供某篇文章,等等,然后提供相应的函数进行处理,这里面说明起来比较复杂,就以获取分类文章来讲吧:

需要用到分析用户请求字符串:

# 分类         elif query_str[0] =="c":             category = query_str[1:]             response_msg = self.get_category_articles(category)             if response_msg:                 return_data = self.pack_news_xml(msg, response_msg)             else:                 response_msg = SORRY                 return_data = self.pack_text_xml(msg, response_msg)             self.write(return_data)

这里要提供get_category_articles(category)的功能,所以需要在weixin类里面实现一个这样的函数:

# 按照分类查找     def get_category_articles(self, category):         global MAX_ARTICLE         global PIC_URL         article_list = Article.get_articles_by_category(category)         article_list_length = len(article_list)         count = (article_list_length < MAX_ARTICLE) and article_list_length or MAX_ARTICLE         if article_list:             # 构造图文消息             articles_msg = {'articles':[]}             for i in range(0,count):                 article = {                         'title': article_list[i].slug,                         'description':article_list[i].description,                         'picUrl':PIC_URL,                         'url':article_list[i].absolute_url                     }                 # 插入文章                 articles_msg['articles'].append(article)                 article = {}             # 返回文章             return articles_msg

很显然,这里需要和数据库模型Article打交道,看看Article是否实现了该功能,很遗憾没有,那么我们只好卷起袖子自己干——扩展Article,所以我们转战到modle.py文件里面了,写下了如下的代码:

# 返回一个包含若干篇文章的数组 limit 5     def get_articles_by_category(self, category):         sdb._ensure_connected()         article_list = sdb.query('SELECT * FROM `sp_posts` WHERE `category` = %s LIMIT 5', str(category))         for i in range(len(article_list)):             article_list[i] = post_detail_formate(article_list[i])         return article_list

这里进行了数据库查询,将category参数传递进去,选择category为参数的5篇文章,打包返回。post_detail_formate是博客系统已经写好的,我们只要拿来用就行了。在python里面,写sql语句要很小心,遇到要传入参数的,最好是用逗号分割开,而不是使用%来填充参数。特别是使用like的时候,我们往往需要写这样的sql语句:

SELECT * FROM `sp_posts` WHERE `category` LIKE '%study%'

但是python里面又是用%s做参数占位符的,故而会引起很多不必要的错误,比如这里。总之要安全使用,最好是作为参数传递,python会为他们与原字符串里的%等分开。

感谢你能够认真阅读完这篇文章,希望小编分享的“微信开发之如何使用消息接口”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI