本站文章一览:

企业微信 java 配置 使用接收消息 python企业微信接收消息_python


上篇文章我们将企业微信自建应用与我们自己的服务器连接起来了,下面进行第二步,接收用户消息处理,并回复。

文章目录

  • 0. 接收与被动回复消息的格式
  • 0.1 消息格式(以文本消息为例)
  • 0.1.1 接收消息格式
  • 0.1.2 回复消息格式
  • 1. 编写代码
  • 1.1 入口的处理
  • 1.2 解密接收到的消息内容
  • 1.3 对消息内容进行处理,并封装回复的消息体
  • 1.4 运行效果
  • 2. 完整代码
  • 3. 遇到的坑


还是采用Flask框架。

0. 接收与被动回复消息的格式

0.1 消息格式(以文本消息为例)

看下官方文档:https://developer.work.weixin.qq.com/document/path/96466

0.1.1 接收消息格式

企业微信 java 配置 使用接收消息 python企业微信接收消息_企业微信 java 配置 使用接收消息_02

0.1.2 回复消息格式

企业微信 java 配置 使用接收消息 python企业微信接收消息_企业微信_03

接收到的消息格式为xml格式,回复内容的格式也是xml格式。

这里接收到的xml格式的内容和发送出去的xml格式的内容都是需要加密的,所以在接收到之后和回复消息之前都应该进行解密和加密处理。

该功能的限制,与微信公众号一样,也是只有5s的响应时间,总共重试三次:

企业微信 java 配置 使用接收消息 python企业微信接收消息_微信_04

了解了基本内容之后,我们开始编写代码

1. 编写代码

1.1 入口的处理

@app.route('/company_wechat', methods=['GET', 'POST']) 
def company_wechat():
    if request.method == 'GET':
        return signature(request, 0)
    else:
        print("收到请求......")
        return handle_user_message(request, 0)

如果是GET请求,就去校验是否是微信消息。

如果是POST请求,就进行相应处理并给出回复。

1.2 解密接收到的消息内容

上面提到了,企业微信服务转发过来的消息是经过加密的,需要我们自己解密。

原始发过来的消息示例如下:

企业微信 java 配置 使用接收消息 python企业微信接收消息_笔记_05

解密代码:

user_message = request.data
msg_signature = request.args.get('msg_signature', '')
timestamp = request.args.get('timestamp', '')
nonce = request.args.get('nonce', '')
ret, sMsg = qy_api[i].DecryptMsg(user_message.decode('utf-8'), msg_signature, timestamp, nonce)
decrypt_data = {}
for node in list(fromstring(sMsg.decode('utf-8'))):
    decrypt_data[node.tag] = node.text
print(decrypt_data)

解密完之后的消息内容:

企业微信 java 配置 使用接收消息 python企业微信接收消息_微信_06

1.3 对消息内容进行处理,并封装回复的消息体

得到明文的消息内容之后,我们就可以对其进行相应的处理,并给出回复了。

示例代码如下,如果用户发过来一个“我帅吗”,就给用户回复一个“帅得一逼”

# 处理文本消息
if decrypt_data.get('Content', '') == '我帅吗':
    sRespData = """<xml>
        <ToUserName>{to_username}</ToUserName>
        <FromUserName>{from_username}</FromUserName> 
        <CreateTime>{create_time}</CreateTime>
        <MsgType>text</MsgType>
        <Content>{content}</Content>
        </xml>
        """.format(to_username=decrypt_data['ToUserName'],
                from_username=decrypt_data['FromUserName'],
                create_time=decrypt_data['CreateTime'],
                content="帅得一逼",)

最后,封装完之后不要忘了加密:

ret, send_msg = qy_api[i].EncryptMsg(sReplyMsg=sRespData, sNonce=nonce)
if ret == 0:
    return send_msg
else:
    print(send_msg)

1.4 运行效果

企业微信 java 配置 使用接收消息 python企业微信接收消息_笔记_07

成功!

2. 完整代码

参考:https://gist.github.com/GentleCP/5d02f4e84b8c8905bcf67643223cd499

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

from flask import Flask, request, make_response
from company_wechat_verify.WXBizMsgCrypt3 import WXBizMsgCrypt
from xml.etree.ElementTree import fromstring

app = Flask(__name__)

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'))

qy_api = [
    WXBizMsgCrypt("xxx", "xxx", "xxx"), 
] #对应接受消息回调模式中的token,EncodingAESKey 和 企业信息中的企业id

# 开启消息接受模式时验证接口连通性
def signature(request, i): 
    msg_signature = request.args.get('msg_signature', '')
    timestamp = request.args.get('timestamp', '')
    nonce = request.args.get('nonce', '')
    echo_str = request.args.get('echostr', '')
    ret,sEchoStr=qy_api[i].VerifyURL(msg_signature, timestamp, nonce, echo_str)
    if (ret != 0):
        print("ERR: VerifyURL ret: " + str(ret))
        return("failed")
    else:
        return(sEchoStr)

def handle_user_message(request, i):
    '''
    接收用户消息,可进行被动响应
    '''
    user_message = request.data
    printXML(user_message)
    msg_signature = request.args.get('msg_signature', '')
    timestamp = request.args.get('timestamp', '')
    nonce = request.args.get('nonce', '')
    ret, sMsg = qy_api[i].DecryptMsg(user_message.decode('utf-8'), msg_signature, timestamp, nonce)
    decrypt_data = {}
    for node in list(fromstring(sMsg.decode('utf-8'))):
        decrypt_data[node.tag] = node.text
    # 解析后得到的decrypt_data: {"ToUserName":"企业号", "FromUserName":"发送者用户名", "CreateTime":"发送时间", "Content":"用户发送的内容", "MsgId":"唯一id,需要针对此id做出响应", "AagentID": "应用id"}
    # 用户应根据Content的内容自定义要做出的行为,包括响应返回数据,如下例子,如果发送的是123,就返回hello world
    print(decrypt_data)
            
    # 处理文本消息
    if decrypt_data.get('Content', '') == '我帅吗':
        sRespData = """<xml>
            <ToUserName>{to_username}</ToUserName>
            <FromUserName>{from_username}</FromUserName> 
            <CreateTime>{create_time}</CreateTime>
            <MsgType>text</MsgType>
            <Content>{content}</Content>
            </xml>
            """.format(to_username=decrypt_data['ToUserName'],
                    from_username=decrypt_data['FromUserName'],
                    create_time=decrypt_data['CreateTime'],
                    content="帅得一逼",)
            
    ret, send_msg = qy_api[i].EncryptMsg(sReplyMsg=sRespData, sNonce=nonce)
    if ret == 0:
        return send_msg
    else:
        print(send_msg)

@app.route('/company_wechat', methods=['GET', 'POST']) 
def company_wechat():
    if request.method == 'GET':
        return signature(request, 0)
    else:
        print("收到请求......")
        return handle_user_message(request, 0)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

3. 遇到的坑

其实也不能算是坑,应该算是惊吓。

刚开始没看具体发来的消息是什么,只是在收到请求的时候打了一行日志,结果… 发现一直在收到请求,着实吓到我了,不得不关了服务… 。

企业微信 java 配置 使用接收消息 python企业微信接收消息_python_08


原本以为这是回复失败的尝试,但说明文档中说了只会重试3次,这里这么多请求,都是什么?

它其实是 Location 类型的消息,基本1s一次。

企业微信 java 配置 使用接收消息 python企业微信接收消息_企业微信_09

有这个消息的原因,是我在API接收消息是,勾选了 上报地理位置,并且在手机上,开启了位置权限。

企业微信 java 配置 使用接收消息 python企业微信接收消息_企业微信 java 配置 使用接收消息_10


本站文章一览:

企业微信 java 配置 使用接收消息 python企业微信接收消息_笔记_11