测试号收不到图文消息_我的公众号开发(第四步)图文消息回复

5cc18c489904fe37f1dd8db7dff5888d.png

作者:JiawuZhang 出品:JiawuLab(ID:jiawulab)

实验记录系列是JiawuLab原创栏目,通过真实项目的操作,记录整个实验过程。
旨在通过一步步过程,无基础的朋友都能直接上手。

大家好,我是JiawuZhang,本次实验记录的项目是——微信公众号开发。

我的公众号开发的第四篇文章,如果您没看过前三篇文章,这里是传送门:

JiawuZhang:我的公众号开发(第一步)简单功能实现​zhuanlan.zhihu.com
f60a7057702971ae3245e0d52615dd7b.png
JiawuZhang:我的公众号开发(第二步)智能AI对接​zhuanlan.zhihu.com
6c074257254a938e49678d46c72d1533.png
JiawuZhang:我的公众号开发(第三步)数据库实现关键字回复​zhuanlan.zhihu.com
2e7f2adea1e7ba7f7594c645548ce2f9.png

希望您多多关注。

上期回顾

首先对智能AI机器人进行优化,让机器人更聪明。

然后通过pymysql库,对MySQL数据库进行了基础操作学习。

最后通过改造代码,实现了关键字回复的功能并上线。

细心的你,可能会发现,粉丝每发一条信息,都会查询一次数据库,有些信息根本不需要查询,同时对数据库压力太大,

而且最后截图演示中,关键字回复的不只是文字,是像卡片一样的样式,

本期,我将进行代码再改造,让数据库轻松点,同时引入一个新的消息回复类型-图文回复

本期知识点

1、图文消息回复

2、数据库轻松点

3、日志功能

关键字回复体验

上期我们使用数据库实现了关键字回复的功能,不知道你有没有试过,好不好用

反正我使用下来非常好用,可以在服务器不重新启动的情况下,增加多组新的关键字

比如原先我设置的关键字,只有下面两组,有朋友也测试过

5a2105672bb3cd52c5a783d071452d5e.png

然后我昨天将前三篇文章也加入进去,现在是这样的

ef71fc2dba513ebe5f640293d9893c0f.png

只需要回复第一步第二步第三步,就能得到下面的回复

2323145900d842341276713f201636b7.png

是不是很方便呢,一旦有新的关键字需要增加,都可以马上增加,你也可以上手试试看。

图文消息回复

大家从上面图片可看到,我用到的是一种卡片型的回复,不再是纯文字的

这就是本期将要学到的一种新的类型——图文消息回复

官方文档中也有提及这种类型,如下截图:

ba9eceb74f8b08104b6ae98af0f7bf48.png

消息管理-被动回复用户消息-回复图文消息,有对该类型进行表述

从截图可以看到,图文消息体,我们单独拿出来研究一下

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[news]]></MsgType>
  <ArticleCount>1</ArticleCount>
  <Articles>
    <item>
      <Title><![CDATA[title1]]></Title>
      <Description><![CDATA[description1]]></Description>
      <PicUrl><![CDATA[picurl]]></PicUrl>
      <Url><![CDATA[url]]></Url>
    </item>
  </Articles>
</xml>

消息体分析:

MsgType的消息类型为news,一种新的类型,还记得前面我们分析消息回复原理讲到的吗?

如果你不记得了,请查看——我的公众号开发(第二步)智能AI对接

087727db9e46b6ca0f109410ecd49318.png

上面表格中写明了,消息体的各项参数说明,我们从中可以得到如下结论

1、ArticleCount,我们是发送文本、图文,所以只能回复1条图文消息,所以我们只能设置为1

2、发送图文消息,我们需要有四条内容,分别是TitleDescriptionPicUrlUrl,对应着标题、描述、图片地址、链接

所以需要按照上期文章——数据库实现关键字回复——来改造数据库

综合上述,本期需要解决两个问题,才能实现图文消息回复,分别是新类型news数据库改造,我们来实现吧

新回复类型news

当收到粉丝发来的一条文本关键字,服务器根据关键字返回类型为news的图文消息给粉丝

对于接收程序receive来说,还是文本消息,不用改造

我们需要改造的是回复程序reply,增加新类型news,如下

...
# 上面代码不变,只需新增下面代码
class NewsMsg(Msg):

    def __init__(self, toUserName, fromUserName, content):
        self.__dict = dict()
        self.__dict['ToUserName'] = toUserName
        self.__dict['FromUserName'] = fromUserName
        self.__dict['CreateTime'] = int(time.time())
        self.__dict['title'] = content[0]
        self.__dict['description'] = content[1]
        self.__dict['picurl'] = content[2]
        self.__dict['url'] = content[3]


    def send(self):
        XmlForm = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[news]]></MsgType>
        <ArticleCount>1</ArticleCount>
        <Articles>
            <item>
              <Title><![CDATA[{title}]]></Title>
              <Description><![CDATA[{description}]]></Description>
              <PicUrl><![CDATA[{picurl}]]></PicUrl>
              <Url><![CDATA[{url}]]></Url>
            </item>
        </Articles>
        </xml>
        """
        return XmlForm.format(**self.__dict)

这里我说明一点:回复程序从Handle程序传递参数content,这是一个包含标题、描述、图片地址、链接的元组

所以需要在参数content的创建中,也按照这个顺序来,否则会出现错误

完成了回复程序reply的改造后,我们来对Handle程序中POST方法进行改造

...
if recMsg.MsgType == 'text':
    key = recMsg.Content.decode('utf-8')  
    if mydb.mycontent(key):
        content = mydb.mycontent(key)  # 关键字回复
        replyMsg = reply.NewsMsg(toUser, fromUser, content)  #只改了这里
        return replyMsg.send()
    else:
        content = robot(key)  # 正常聊天
        replyMsg = reply.TextMsg(toUser, fromUser, content)
        return replyMsg.send()
...

本次更改很简单,只需要将备注点前面的TextMsg改为NewsMsg即可

这样就能调用图文消息回复,不过有个问题产生,mydb文件中mycontent()函数返回的并不是包含标题、描述、图片地址、链接的元组

所以我们需要对mydb中的mycontent()函数进行改造

数据库改造

改造mycontent()函数前,需要改造数据库,

原先我们创建的数据表中,只有keywordreply两项内容

而图文回复需要五项内容,keywordTitleDescriptionPicUrlUrl,所以我们需要重新创建一个数据表

创建数据表还记得吗,我这里将SQL语句给出来

# 创建新数据表newcontent,包含图文回复五项内容
sql = """
CREATE TABLE newcontent (
id INT auto_increment PRIMARY KEY ,
keyword VARCHAR(50) NOT NULL ,
title VARCHAR(100) NOT NULL ,
description VARCHAR(200) NOT NULL ,
picurl VARCHAR(200) NOT NULL ,
url VARCHAR(200) NOT NULL 
)ENGINE=InnoDB DEFAULT CHARSET=utf8;  #注意:charset='utf8' 不能写成utf-8
"""

后续操作按照上期文章介绍的执行即可,你可以动手试试

数据表有了,添加数据的两种方式,

一是代码添加,如下

# SQL插入语句
sql = 'insert into newcontent(keyword, title, description, picurl, url) values(%s, %s, %s, %s, %s);'

# 三组关键字回复
data = [
    ('关键字', '标题', '描述', '图片地址', '链接'),
    ('关键字2', '标题2', '描述2', '图片地址2', '链接2'),
    ('关键字3', '标题3', '描述3', '图片地址3', '链接3'),
]

# 拼接并执行sql语句
cursor.executemany(sql, data)

二是使用mySQL可视化软件直接添加,如下图:

ef71fc2dba513ebe5f640293d9893c0f.png

两种方法各有优势,你可以选择自己合适的方式进行

关于图片地址,我的方法是,先将图片上传到素材中,再将图片地址复制出来

数据表有了,添加数据的方式也说了,我们进行代码改造mycontent()函数

def mycontent(key):
    conn = pool.connection()
    cursor = conn.cursor()
    cursor.execute('select title,description,picurl,url from newcontent where keyword=%s', key)
    data = cursor.fetchone()  # 将数据库的数据(元组嵌套)赋值给datas
    cursor.close()
    conn.close()
    return data

前面提到的,按照'标题'、'描述'、'图片地址'、'链接'的顺序返回data数据

保存文件后,重新启动服务器,就可以实现图文消息回复了,你也动手试试看,是不是很有成就感。

让数据库轻松点

上期结尾处,我们提到,粉丝每发一条消息,都要查询一次数据库,而且本期又改造成了图文回复

查询数据库的次数和耗时,都有所增加,那我们应该怎么减轻数据库的压力呢?

这里我的方法是,将数据表中关键字全部提出来,然后先用粉丝的消息与关键字列表做判断

如果在关键字列表中,再从数据库中将'标题'、'描述'、'图片地址'、'链接'等信息都取出来,发给粉丝

当然,如果你有更好的办法,自己进行实现,也可以分享在留言处,让大家都学习一下

这里按照我的方法进行,在mydb文件中新建一个mykeyword函数

def mykeyword():
    conn = pool.connection()
    cursor = conn.cursor()
    # 提取所有keyword
    cursor.execute('select keyword from newcontent')
    data = cursor.fetchall()
    cursor.close()
    conn.close()
    # data是元组嵌套,转换为列表
    key = [j for i in data for j in i]
    return key

然后将mykeyword函数加到Handle类中

...
if recMsg.MsgType == 'text':
    key = recMsg.Content.decode('utf-8')  
    if key in mydb.mykeyword():
        content = mydb.mycontent(key)  # 关键字回复
        replyMsg = reply.NewsMsg(toUser, fromUser, content)  
        return replyMsg.send()
    else:
        content = robot(key)  # 正常聊天
        replyMsg = reply.TextMsg(toUser, fromUser, content)
        return replyMsg.send()
...

保存文件后,重启服务器就好了,这样数据库会轻松点,同时因为有数据池的存在,多人同时消息回复也能轻松解决。

日志功能

前面三期,我们每保存完改造后的代码,都是使用的python3 main.py 80进行服务器启动

这会造成一个问题,当退出后,服务就不再继续了,而且没有日志,不方便查看问题

所以本期,我们只用一条命令,就可以解决上述问题

我们在服务器命令行界面,先cd到main.py所在的文件夹

输入这条命令:

nohup python3 main.py 80 > wx.log 2>&1 &

服务就启动了,并且常驻在后台运行,我们退出服务器,程序也会一直运行

然后将服务器的日志保存在wx.log文件中

我们打开wx.log文件看看,命令是:

vi wx.log

就能查看到wx.log中的日志信息了

里面会根据你在程序中设置的print信息,以及各IP访问你的服务器的信息,你可以试试

现在日志功能有了,而且服务在后台静默运行,我们只要多增加相应的关键字回复就好。

如果你有不明白的,请关注公众号:JiawuLab,给我留言,我会一一解答。

下一步预告

本期我们新增图文消息回复,并且让数据库更轻松,最后也拥有了日志功能。

现在已经拥有了很完整的功能,只需要日后根据运营情况,进行完善相关功能就行。

那下一步做什么呢?还记得我们最开始选择的开发基础配置吗?

对了,明文模式,也就是说,所有粉丝发来的信息和我们回复的消息,都是明文的

如果有人进行数据包拦截,不用解密,就能全部看到,这样很危险。

所以下一步,我们将实现最重要,也是必须为安全着想的功能——消息加密

本期记录到此结束,感谢您的阅读。如果您喜欢这期文章,请点赞,支持一下。

欢迎您关注公众号:JiawuLab,提前体验完整功能,或者给我留言,说说你遇到的问题,我们一起探讨。

478e0b6aae06f7768a0c806594e9bb3b.png

文中资源:

1、官方文档: https:// developers.weixin.qq.com /doc/offiaccount/Message_Management/Passive_user_reply_message.html#5

推荐阅读

我的公众号开发(第三步)数据库实现关键字回复

我的公众号开发(第二步)智能AI对接

我的公众号开发(第一步)简单功能实现

d236e5cc343ec2c5e15b60d1daed3f4c.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值