Directorio de artículos
Prefacio
Este blog utiliza el marco Django, combinado con uWsgi y Nginx, combinado con la herramienta de depuración de la API Postman, para realizar la función de respuesta automática de los mensajes de los usuarios de cuentas públicas de WeChat, y se implementa con éxito en el servidor Tencent Cloud.
En el blog anterior , hemos configurado el servidor Tencent Cloud y podemos realizar interacciones simples.
1. Configurar la cuenta oficial de WeChat
- Inicie sesión en la plataforma oficial de cuentas públicas de WeChat , desplácese hasta la parte inferior de la página y haga clic en Configuración básica
- Haga clic en modificar configuración a la derecha y complete la información correspondiente
URL: http://服务器公网IP/wx
Token: 自己设置一条字符串
EncodingAESKey: 随机生成就可
消息加解密方式: 为方便调试,暂时选择明文模式
2. Verificar la fuente de la información
Después de completar la información anterior, si elige enviar, se activará una GET
solicitud para verificar el Token. El diagrama lógico de la verificación es el siguiente:
A continuación views.py
implementamos esta lógica en un archivo en el directorio del proyecto , el código es el siguiente:
from django.http import HttpResponse
import hashlib
# Create your views here.
def TencentView(request):
if request.method == 'GET':
# 解析参数
data = request.GET
if len(data) == 0:
return HttpResponse(content="hello, this is WeChat view")
signature = data.get(key='signature', default='')
timestamp = data.get(key='timestamp', default='')
nonce = data.get(key='nonce', default='')
echostr = data.get(key='echostr', default='')
# 请按照公众平台官网\基本配置中信息填写
token = "xxxxxxxxxxxxxxxxxx"
list_para = [token, timestamp, nonce]
list_para.sort()
list_str = ''.join(list_para).encode('utf-8')
sha1 = hashlib.sha1()
sha1.update(list_str)
# map(sha1.update, list_para)
# 加密
hashcode = sha1.hexdigest()
print("/GET func: hashcode: {0}, signature: {1}".format(hashcode, signature))
if hashcode == signature:
return HttpResponse(content=echostr)
else:
return HttpResponse(content='验证失败')
elif request.method == 'POST':
pass
Aquí hay un hoyo. Los ejemplos oficiales están escritos en Python2, pero el cifrado hashlib de Python2 es diferente al de Python3
utf-8
. Python3 necesita codificarse primero .
Una vez que la configuración anterior sea correcta, la verificación se realizará correctamente si la vuelve a enviar. Si aún no lo es, verifique si el resultado de la encriptación es incorrecto. Si la verificación del token es correcta, volverá automáticamente a la página principal de la configuración básica y haga clic en el botón de inicio.
3. Prueba de recepción-respuesta de mensajes
Los fans envían un mensaje de texto a la cuenta oficial: "hola". En el backend del desarrollador, reciben lo xml
siguiente de la plataforma oficial :
<xml>
<ToUserName><![CDATA[公众号]]></ToUserName>
<FromUserName><![CDATA[粉丝号]]></FromUserName>
<CreateTime>1460537339</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[hello]]></Content>
<MsgId>6272960105994287618</MsgId>
</xml>
Las descripciones de los campos son las siguientes:
Campo | efecto |
---|---|
ToUserName |
el público |
FromUserName |
Número de ventilador |
CreateTime |
La plataforma pública WeChat registra la hora específica en la que el fan envió el mensaje |
MsgType |
Tipo de mensaje, hay text , image , voice etc. |
Content |
Contenido del mensaje |
MsgId |
La plataforma pública registra un valor de etiqueta que identifica el mensaje y el sistema de fondo WeChat lo genera automáticamente |
La cuenta oficial quiere responder a un fan con un mensaje de texto con el contenido "prueba", luego el xml
contenido enviado por el desarrollador al backend de la plataforma oficial es el siguiente:
<xml>
<ToUserName><![CDATA[粉丝号]]></ToUserName>
<FromUserName><![CDATA[公众号]]></FromUserName>
<CreateTime>1460541339</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[test]]></Content>
</xml>
Si el servidor no puede garantizar el procesamiento de la respuesta en cinco segundos, debe responder con "éxito" o "" (cadena vacía); de lo contrario, el fondo de WeChat indicará "La cuenta oficial no está disponible temporalmente, inténtelo de nuevo más tarde".
El diagrama de flujo de recepción-respuesta de mensajes es el siguiente:
Continuemos views.py
implementando este proceso en los archivos en el directorio del proyecto , agregando el siguiente código:
from xml.etree import ElementTree
import time
class ParseXmlMsg(object):
def __init__(self, xmlData):
self.ToUserName = xmlData.find('ToUserName').text
self.FromUserName = xmlData.find('FromUserName').text
self.CreateTime = xmlData.find('CreateTime').text
self.MsgType = xmlData.find('MsgType').text
self.MsgId = xmlData.find('MsgId').text
if self.MsgType == 'text':
self.Content = xmlData.find('Content').text.encode('utf-8')
elif self.MsgType == 'image':
self.PicUrl = xmlData.find('PicUrl').text
self.MediaId = xmlData.find('MediaId').text
class TextMsg(object):
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['Content'] = content
def send(self):
XmlForm = """
<xml>
<ToUserName><![CDATA[{ToUserName}]]></ToUserName>
<FromUserName><![CDATA[{FromUserName}]]></FromUserName>
<CreateTime>{CreateTime}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{Content}]]></Content>
</xml>
"""
return XmlForm.format(**self.__dict)
class ImageMsg(object):
def __init__(self, toUserName, fromUserName, mediaId):
self.__dict = dict()
self.__dict['ToUserName'] = toUserName
self.__dict['FromUserName'] = fromUserName
self.__dict['CreateTime'] = int(time.time())
self.__dict['MediaId'] = mediaId
def send(self):
XmlForm = """
<xml>
<ToUserName><![CDATA[{ToUserName}]]></ToUserName>
<FromUserName><![CDATA[{FromUserName}]]></FromUserName>
<CreateTime>{CreateTime}</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[{MediaId}]]></MediaId>
</Image>
</xml>
"""
return XmlForm.format(**self.__dict)
También es necesario elif
agregar el siguiente código en la declaración:
elif request.method == 'POST':
# 解析发送过来的body
webData = request.body
# print("Post webdata is ", webData)
xmlData = ElementTree.fromstring(webData)
recMsg = ParseXmlMsg(xmlData)
if recMsg.MsgType == 'text':
toUser = recMsg.FromUserName
fromUser = recMsg.ToUserName
content = 'test'
replyMsg = TextMsg(toUser, fromUser, content)
return HttpResponse(content=replyMsg.send())
elif recMsg.MsgType == 'image':
print('暂时不做处理')
return HttpResponse(content='success')
4. Depuración del cartero
Para facilitar la depuración, podemos iniciar el proyecto localmente y luego enviar y recibir mensajes a través de Postmanxml
y subirlos al servidor después de la depuración.
- Primero inicie el proyecto localmente
# 在启动之前,先注释掉settings.py文件中的一行代码,关闭CSRF验证
# 否则POST时会触发CSRF验证失败
# 'django.middleware.csrf.CsrfViewMiddleware'
python manage.py runserver
- Abra Postman, use la
POST
solicitud yBody
complete elxml
mensaje que necesitamos enviar en la barra de menú . La información de configuración específica se muestra en la figura siguiente
- Después de completar, haga clic en
Send
enviar, recibiremos la información devuelta en la columna de información de respuesta a continuación
El mensaje enviado es "hola" y el mensaje recibido es "prueba", indicando que está bien, y luego sube el código al servidor.
Recuerda reiniciar después de cargar el servidor
uWsgi
yNginx
¡oh!
5. Depuración de interfaz oficial
La plataforma pública WeChat proporciona una plataforma de prueba en línea a través de la cual se puede simular la interacción entre los fanáticos y la cuenta pública.
FromUserName
Al configurar la cuenta oficial de WeChat, puede verla en la barra de menú de configuración básica.
Una vez que la configuración sea correcta, haga clic en el 检查问题
botón de abajo , si no sucede nada, obtendrá la siguiente información:
Al enviar un mensaje a la cuenta oficial de WeChat, parece que el emoji también es del text
tipo:
¡OKAY! ¡Muy agradable! ! !