Artigo Diretório
Prefácio
Este blog usa a estrutura Django, combinada com uWsgi e Nginx, combinada com a ferramenta de depuração Postman API, para realizar a função de resposta automática de mensagens de usuários de contas públicas do WeChat, e implementada com sucesso no servidor Tencent Cloud.
No blog anterior , configuramos o servidor Tencent Cloud e podemos realizar interações simples.
1. Configure a conta oficial do WeChat
- Faça login na plataforma oficial de conta pública WeChat , role até a parte inferior da página e clique em Configuração básica
- Clique em modificar configuração à direita e preencha as informações correspondentes
URL: http://服务器公网IP/wx
Token: 自己设置一条字符串
EncodingAESKey: 随机生成就可
消息加解密方式: 为方便调试,暂时选择明文模式
2. Verifique a fonte das informações
Após o preenchimento das informações acima, a opção de enviar acionará uma GET
solicitação de verificação do token. O diagrama lógico da verificação é o seguinte:
A seguir views.py
implementamos essa lógica em um arquivo no diretório do projeto , o código é o seguinte:
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
Há um fosso aqui. Os exemplos oficiais são escritos em Python2, mas a criptografia hashlib de Python2 é diferente daquela em Python3
utf-8
. Python3 precisa ser codificado primeiro .
Depois que a configuração acima estiver correta, a verificação será bem-sucedida se você enviá-la novamente. Se ainda não tiver êxito, verifique se o resultado da criptografia está errado. Se a verificação do token for bem-sucedida, ele retornará automaticamente à página principal da configuração básica e clique no botão Iniciar.
3. Teste de recepção-resposta de mensagem
Os fãs enviam uma mensagem de texto para a conta oficial: "olá". No back-end do desenvolvedor, eles recebem o xml
seguinte da plataforma oficial :
<xml>
<ToUserName><![CDATA[公众号]]></ToUserName>
<FromUserName><![CDATA[粉丝号]]></FromUserName>
<CreateTime>1460537339</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[hello]]></Content>
<MsgId>6272960105994287618</MsgId>
</xml>
As descrições dos campos são as seguintes:
Campo | efeito |
---|---|
ToUserName |
o público |
FromUserName |
Número de fã |
CreateTime |
A plataforma pública WeChat registra o momento específico em que o fã enviou a mensagem |
MsgType |
Tipo de mensagem, há text , image , voice etc. |
Content |
Conteúdo da mensagem |
MsgId |
A plataforma pública registra um valor de tag que identifica a mensagem e o sistema de segundo plano do WeChat o gera automaticamente |
A conta oficial quer responder a um fã com uma mensagem de texto com o conteúdo "teste", então o xml
conteúdo enviado pelo desenvolvedor para o backend da plataforma oficial é o seguinte:
<xml>
<ToUserName><![CDATA[粉丝号]]></ToUserName>
<FromUserName><![CDATA[公众号]]></FromUserName>
<CreateTime>1460541339</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[test]]></Content>
</xml>
Se o servidor não puder garantir o processamento da resposta em cinco segundos, ele deve responder com "sucesso" ou "" (string vazia), caso contrário, o fundo do WeChat exibirá "A conta oficial está temporariamente indisponível, tente novamente mais tarde".
O fluxograma de recebimento de mensagens é o seguinte:
Vamos continuar views.py
a implementar esse processo nos arquivos do diretório do projeto , adicionando o seguinte 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)
Também é necessário elif
adicionar o seguinte código na instrução:
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. Depuração do Postman
Para facilitar a depuração, podemos iniciar o projeto localmente e, em seguida, enviar e receber mensagens por meio do Postmanxml
e fazer o upload para o servidor após a depuração.
- Comece primeiro o projeto localmente
# 在启动之前,先注释掉settings.py文件中的一行代码,关闭CSRF验证
# 否则POST时会触发CSRF验证失败
# 'django.middleware.csrf.CsrfViewMiddleware'
python manage.py runserver
- Abra o Postman, use o
POST
pedido eBody
preencha axml
mensagem que precisamos enviar na barra de menu . As informações específicas de configuração são mostradas na figura abaixo
- Após o preenchimento, clique em
Send
enviar, receberemos as informações retornadas na coluna de informações de resposta abaixo
A mensagem enviada é "hello" e a mensagem recebida é "test", indicando que está tudo bem, e então carregue o código para o servidor.
Lembre-se de reiniciar após fazer o upload do servidor
uWsgi
eNginx
oh!
5. Depuração de interface oficial
A plataforma pública WeChat fornece uma plataforma de teste online através da qual a interação entre os fãs e a conta pública pode ser simulada.
FromUserName
Ao configurar a conta oficial do WeChat, você pode vê-lo na barra de menu de configuração básica.
Após a configuração estar correta, clique no 检查问题
botão abaixo , caso nada aconteça, você obterá as seguintes informações:
Enviando uma mensagem para a conta oficial do WeChat, parece que o emoji também é do text
tipo:
ESTÁ BEM! Muito agradável! ! !