当前位置:   article > 正文

【超详细!】Python微信公众号开发(2)_python 公众号开发

python 公众号开发

上次我们已经完成了微信公众号开发环境的搭建,并完成了服务器和微信公众号的校验。下面让我们来开始实际开发。

如果还没有微信公众号开发环境的,请参考我上一篇文章:

【超详细!超多图!】Python微信公众号开发(1)

本篇文章的内容为带领大家打通用户与服务器的信息交流通道:用户发的消息能在服务器收到,服务器能回复消息给用户。

0. 准备工作

0.1 代码修改

昨天的代码只是完成了微信公众号和服务器的校验,并没有地方处理用户的消息,下面我们来加上。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask import Flask, request
import hashlib

app = Flask(__name__)

##### 修改1:将昨天的校验代码封装成单独的函数 #####
def verify_wechat(request):
    # 设置token,开发者配置中心使用
    token = 'xxxxx'   # <------ 替换成你自定义的Token

    # 获取微信服务器发送过来的参数
    data = request.args
    signature = data.get('signature')
    timestamp = data.get('timestamp')
    nonce = data.get('nonce')
    echostr = data.get('echostr')

    # 对参数进行字典排序,拼接字符串
    temp = [timestamp, nonce, token]
    temp.sort()
    temp = ''.join(temp)

    # 加密
    if (hashlib.sha1(temp.encode('utf8')).hexdigest() == signature):
        return echostr
    else:
        return 'error', 403

##### 修改2:将服务访问路径由昨天的'/'换成'/wechatai' #####
#####       这里也可以不换路径,名字也可以你自己随意定 #####
@app.route('/wechatai', methods=['GET', 'POST'])
def wechatai():
	##### 修改3:当接受到的消息为GET请求时,执行校验,如果为POST请求,则认为是用户消息,处理用户消息
    if request.method == 'GET': 
        return verify_wechat(request)
    else:
        # 处理POST请求
        print("user request data: ", request.data)
        return "ok"  # <--------- 一定要加返回值!

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

如果你执行了上面的“修改2”,将访问路径改了,那需要到公众号里对服务器配置进行相应的修改,即在URL后面也加入这个路径,这样才能访问到。

0.2 启用服务器

  • 首先确保完成了上面的环境搭建和校验成功。
  • 确保你的程序已经开始运行

在配置服务器的公众号后台 —> “服务器配置” —> 点击“启用”
在这里插入图片描述

这样就相当于与咱们的服务器打通了,用户发的消息都会被微信服务器转发到咱们自己的服务上去,咱们就可以在自己的服务器上处理消息了。

1. 发个消息试试

首先你得关注这个公众号

1.1 发个消息试试

(1)打开这个公众号页面,发送消息“test”
在这里插入图片描述
(2)去服务器上查看你的程序收到的消息
如果正常,你应该能在你的程序运行后台看到下面的信息。这一坨数据下文我会解释其意思,这里你先能收到它就OK了。
在这里插入图片描述

1.2 可能遇到的坑(我遇到的)

(1)服务器收不到用户消息:校验成功,但是用户发的消息服务器看不到。

  • 网上的解决方案:

微信公众号可以验证后台服务器(get),但却接收不到微信用户的消息及事件通知的一个可能性

  • 我的解决方案:以上解决方案并不能解决我的问题,我是在启用服务器的状态下,重新配置了一下服务器配置,然后就神奇的好了…
    在这里插入图片描述

2. 用户消息处理

2.1 用户消息内容

下面我们来看下服务收到的用户消息内容:

b'<xml><ToUserName><![CDATA[gh_fa8fa31]]></ToUserName>\n<FromUserName><![CDATA[oNexy6R4Ubm8gUCr1U]]></FromUserName>\n<CreateTime>1704420739</CreateTime>\n<MsgType><![CDATA[text]]></MsgType>\n<Content><![CDATA[test]]></Content>\n<MsgId>244014308074</MsgId>\n</xml>'
  • 1

可以看到这是一个xml格式的字符串。用Python将以上xml字符串格式化打印出来,格式化打印xml字符串内容的代码如下:

import xml.etree.ElementTree as ET   
def printXML(xml_content):
    # 创建XML元素
    element = ET.XML(xml_content)

    # 使用indent()函数进行格式化打印
    ET.indent(element)
    print(ET.tostring(element, encoding='unicode'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

调用函数打印:

python printXML(request.data)
  • 1

打印如下:

<xml>
  <ToUserName>gh_fa8fa31e</ToUserName>
  <FromUserName>oNexy6R49UkCr1U</FromUserName>
  <CreateTime>1704424380</CreateTime>
  <MsgType>text</MsgType>
  <Content>test</Content>
  <MsgId>244099103</MsgId>
</xml>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这是一个text类型的消息,内容是test。知道用户消息的内容结构之后,现在我们就可以提取出里面的Content来做一些相应的处理了,比如回复用户消息。

2.2 用户消息解析

先来提取用户消息中的Content内容,也就是用户发过来的文字:

(1)定义提取函数

def getUserMessageContentFromXML(xml_content):
    # 解析XML字符串
    root = ET.fromstring(xml_content)

    # 提取数据
    content = root.find('Content').text
    from_user_name = root.find('FromUserName').text
    to_user_name = root.find('ToUserName').text
    return content, from_user_name, to_user_name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(2)调用提取函数

@app.route('/wechatai', methods=['GET', 'POST'])
def wechatai():
    if request.method == 'GET':
        return verify_wechat(request)
    else:
        # 处理POST请求
        print("user request data: ", request.data)
        printXML(request.data)
        user_message_content, from_user_name, to_user_name = getUserMessageContentFromXML(request.data)  # <--------- 这里这里这里
        print("user message content: ", user_message_content)
        return "ok"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

重新运行程序,用户发送过来消息后,应该能解析出结果如下:
在这里插入图片描述

3. 给用户回消息

上面我们能收到用户的消息,解析出用户发送的内容。但是如何给用户回消息呢?上面函数有一个 return "ok",但这只是给微信服务器回的消息,并不是给用户回的消息。

其实给用户回消息很简单,只需要将上面接收到的xml字符串,改一下里面的值即可。

(1)封装一个函数用来生成给回复的xml字符串

def generate_response_xml(from_user_name, to_user_name, output_content):
    # 1. 先准备好回复的xml格式,后面只需要填充里面的字段即可
    output_xml = '''
    <xml>
        <ToUserName><![CDATA[%s]]></ToUserName>
        <FromUserName><![CDATA[%s]]></FromUserName>
        <CreateTime>%s</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[%s]]></Content>
    </xml>'''
    
    # 2. 通过 make_response 函数封装网络返回结构体
    response = make_response(output_xml % (from_user_name, to_user_name, str(int(time.time())), output_content))
    response.content_type = 'application/xml'
    return response
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

可以看到,xml的内容与接收到的基本一致,我们只需要填充里面的ToUserNameFromUserNameCreateTimeContent即可。

  • ToUserNameFromUserName:与接收到的xml保持一致
  • CreateTime:当前时间戳
  • Content:要回复给用户的内容

(2)调用函数生成回复内容的结构

@app.route('/wechatai', methods=['GET', 'POST'])
def wechatai():
    if request.method == 'GET':
        return verify_wechat(request)
    else:
        # 处理POST请求
        print("user request data: ", request.data)
        printXML(request.data)
        user_message_content, from_user_name, to_user_name = getUserMessageContentFromXML(request.data)
        print("user message content: ", user_message_content)
        
        return generate_response_xml(from_user_name, to_user_name, "你好") # <------ 这一句代码!给用户回复一个“你好”
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

重新运行程序,用户发送过来消息后,在微信公众号用户对话界面,用户应该能收到“你好”的消息。
在这里插入图片描述

至此,我们已经打通了用户与服务器的信息交流通道,后面就是在服务器端加自己的业务逻辑了。


从今天开始,持续学习,开始搞事情。踩坑不易,欢迎关注我,围观我!
在这里插入图片描述
有任何问题,欢迎+vx:jasper_8017,一起讨论,共同进步!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/907189
推荐阅读
相关标签
  

闽ICP备14008679号