新手,捣鼓了几天搞明白的,中间遇到了几个坑,

一个是需要现在服务器部署后才能在微信测试号的接口配置信息提交URL和Token。一个是服务器需要在阿里云后台的安全组那里也开启80端口。其他记不得了,好几天前了,只能记得这么多。

1. 前置条件

拥有一个服务器 我的是阿里云,用的弹性ip,没有域名注册微信测试号 具体自己搜索开放80和443端口 具体可以搜索你用的服务器怎么开启。

80和443可以都开启,也可以之开启80。80和443分别对应http和https。

安装fnginx、flask、uWSGI

需要先在服务器上配置好,运行后才能在微信测试号上提交接口配置信息。提交的时候微信会

2. 安装nginx

以下操作最好不要用root用户进行,使用有root权限的其他管理员用户即可。

服务器安装nginx

sudo apt install nginx

常用命令

# 关闭服务器

sudo nginx -s stop

# 测试nginx.conf是否能生效

sudo nginx -t

# 重新加载

sudo nginx -s reload

# 建立超链接

sudo ln -s /etc/nginx/sites-available/test.conf /etc/nginx/sites-enabled/test.conf

启动nginx

# 启动nginx

sudo systemctl start nginx

# 设置服务器开机自动启动nginx

sudo systemctl enable nginx

这两个代码可以验证启动状态,此时不需要用到这两个代码

sudo systemctl status nginx

sudo systemctl is-active nginx

在自己电脑的浏览器中输入域名或ip,如果是如下界面说明成功配置。

假如我ip是12.12.121.111,浏览器就输入这几个数字回车就行,不用输入其他的

Welcome to nginx!

If you see this page,the nginx web server is successfully installed and

working.Further configuration is required.

For online documentation and support please refer to nginx.org.

Commercial support is available at nginx.com.

Thank you for using nginx.

执行nginx -t 获取配置文件路径

nginx -t # /etc/nginx

# 不用修改nginx.conf,可以看到下面有两行

# include /etc/nginx/conf.d/*.conf;

# include /etc/nginx/sites-enabled/*;

# 我们只需要更改这两个文件夹里的内容就行

在 /etc/nginx/sites-available 目录下创建一个定义文件wechat.conf,包含以下内容

server {

listen 80;

server_name ;

root /home/xxx/pyVenv/flask_uwsgi/myscript;

location /WeChat {

include uwsgi_params;

uwsgi_pass 127.0.0.1:5664;

}

}

具体什么意思可以搜索nginx如何使用及配置,root指定了你的脚本文件的目录。include uwsgi_params和uwsgi_pass 127.0.0.1:5664是必须的,只需要改5664即可,这个是端口。location /WeChat 这个是设置网页的路径,之后需要ip/WeChat 才能访问这个界面。 这里location / {}或者location /WeChat {}都可以,第一个会把所有的网页都传给wusgi,第二个只会把网址为ip/WeChat的网页传过去

此时不会生效,需要创建软连接到sites-enabled.

sudo ln -s /etc/nginx/sites-available/wechat.conf /etc/nginx/sites-enabled/wechat.conf

sites-available和sites-enabled是两个Nginx配置目录,它们的区别在于配置文件的启用和禁用。

sites-available:

这个目录通常用于存放所有可用的Server Block(Virtual Host)配置文件。 - 配置文件放在这个目录中,但并不会自动生效,Nginx不会直接读取这个目录下的配置文件。 - 在这里创建配置文件是为了更好地组织和管理配置。 2. sites-enabled: - 这个目录用于存放要生效的Server Block配置文件的符号链接(软链接)。 - 配置文件的符号链接需要手动创建,通过将sites-available目录下的配置文件创建软链接到这里。 - Nginx在启动时会读取这个目录下的符号链接,从而启用相应的配置。 为什么要分成两个目录呢?这样的设计允许你更灵活地启用或禁用特定的Server Block,而无需直接编辑或删除配置文件。通过在sites-enabled目录中创建符号链接,你可以选择哪些配置文件要生效,哪些不要。 如果直接在sites-enabled目录下创建配置文件而不在sites-available创建,这样也是可行的,但这失去了一个集中管理可用配置的地方,并且不再能方便地禁用或启用某个配置文件。因此,建议按照约定的方式,将配置文件放在sites-available目录中,并通过软链接的方式启用。

修改完后需要重新加载nginx才行

sudo nginx -t

sudo nginx -s reload

# 或者

sudo systemctl reload nginx

报错可以查看错误日志

sudo cat /var/log/nginx/error.log

3. 安装uWSGI

首先新建个python的虚拟环境

python -m venv

# 启动环境

. .\env_name\Scripts\activate

# 安装flask、uWSGI

pip install flask uwsgi

4. 配置需要的flask脚本

用的Python 用 Flask 从零搭建微信公众号后台 菜鸟入门级 - 知乎 (zhihu.com) 这个里面的代码

服务器中新建verify.py脚本,内容如下:

# -*- coding: UTF-8 -*-

import hashlib

import time

from flask import make_response, Flask, request # 这些是本例中所有用到的库

from lxml import etree

class Message(object):

def __init__(self, req):

self.request = req

# 填写自己的微信token等内容

self.token = 'myWeChatTestALiYun'

self.AppID = 'xxx'

self.AppSecret = 'xxx'

# 验证来自微信的信息

class Get(Message):

def __init__(self, req):

super(Get, self).__init__(req)

self.signature = req.args.get('signature') # 这里分别获取传入的四个参数

self.timestamp = req.args.get('timestamp')

self.nonce = req.args.get('nonce')

self.echostr = req.args.get('echostr')

self.return_code = 'Invalid'

def verify(self):

data = sorted([self.token, self.timestamp, self.nonce]) # 字典排序

string = ''.join(data).encode('utf-8') # 拼接成字符串

hashcode = hashlib.sha1(string).hexdigest() # sha1加密

if self.signature == hashcode:

self.return_code = self.echostr

# 获取用户发来的信息

class Post(Message):

def __init__(self, req):

super(Post, self).__init__(req)

self.xml = etree.fromstring(req.stream.read())

self.MsgType = self.xml.find("MsgType").text

self.ToUserName = self.xml.find("ToUserName").text

self.FromUserName = self.xml.find("FromUserName").text

self.CreateTime = self.xml.find("CreateTime").text

self.MsgId = self.xml.find("MsgId").text

hash_table = {

'text': ['Content'],

'image': ['PicUrl', 'MediaId'],

'voice': ['MediaId', 'Format'],

'video': ['MediaId', 'ThumbMediaId'],

'shortvideo': ['MediaId', 'ThumbMediaId'],

'location': ['Location_X', 'Location_Y', 'Scale', 'Label'],

'link': ['Title', 'Description', 'Url'],

}

attributes = hash_table[self.MsgType]

self.Content = self.xml.find("Content").text if 'Content' in attributes else '抱歉,暂未支持此消息。'

self.PicUrl = self.xml.find("PicUrl").text if 'PicUrl' in attributes else '抱歉,暂未支持此消息。'

self.MediaId = self.xml.find("MediaId").text if 'MediaId' in attributes else '抱歉,暂未支持此消息。'

self.Format = self.xml.find("Format").text if 'Format' in attributes else '抱歉,暂未支持此消息。'

self.ThumbMediaId = self.xml.find("ThumbMediaId").text if 'ThumbMediaId' in attributes else '抱歉,暂未支持此消息。'

self.Location_X = self.xml.find("Location_X").text if 'Location_X' in attributes else '抱歉,暂未支持此消息。'

self.Location_Y = self.xml.find("Location_Y").text if 'Location_Y' in attributes else '抱歉,暂未支持此消息。'

self.Scale = self.xml.find("Scale").text if 'Scale' in attributes else '抱歉,暂未支持此消息。'

self.Label = self.xml.find("Label").text if 'Label' in attributes else '抱歉,暂未支持此消息。'

self.Title = self.xml.find("Title").text if 'Title' in attributes else '抱歉,暂未支持此消息。'

self.Description = self.xml.find("Description").text if 'Description' in attributes else '抱歉,暂未支持此消息。'

self.Url = self.xml.find("Url").text if 'Url' in attributes else '抱歉,暂未支持此消息。'

self.Recognition = self.xml.find("Recognition").text if 'Recognition' in attributes else '抱歉,暂未支持此消息。'

# 回复用户的信息

class Reply(Post):

def __init__(self, req):

super(Reply, self).__init__(req)

self.xml = f'' \

f'' \

f'{str(int(time.time()))}'

def text(self, Content):

self.xml += f'' \

f''

def image(self, MediaId):

pass

def voice(self, MediaId):

pass

def video(self, MediaId, Title, Description):

pass

def music(self, ThumbMediaId, Title='', Description='', MusicURL='', HQMusicUrl=''):

pass

def reply(self):

response = make_response(self.xml)

response.content_type = 'application/xml'

return response

app = Flask(__name__)

@app.route("/WeChat", methods=["GET", "POST"])

def index():

if request.method == "GET":

message = Get(request)

message.verify()

return message.return_code

elif request.method == "POST":

reply = Reply(request)

# 自己设置处理用户的信息的逻辑

reply.text("你好,我是微信机器人")

return reply.xml

if __name__ == "__main__":

app.run(port=5664)

将脚本放在某个目录下,我是在pyvenv创建的虚拟环境中创建了一个myscript文件夹,脚本等内容放在这里。

5. 开始部署

启用nginx(前面已经启动过,这里略过)新建uwsgi.ini文件,内容为

[uwsgi]

home = /home/dwl/pyVenv/flask_uwsgi/

master = true

wsgi-file = /home/dwl/pyVenv/flask_uwsgi/myscript/verify.py

callable = app

chdir = /home/dwl/pyVenv/flask_uwsgi/myscript

socket = 127.0.0.1:5664

logto = /home/dwl/pyVenv/flask_uwsgi/myscript/wechat.log

buffer-size = 65536

其中home是运行的虚拟环境的主目录 masker设置成true,表示启用 uWSGI 主进程 wsgi-file是需要运行的py脚本 callable是flask的实例,就等于app就行 chdir 指定运行目录,我设置的当前运行的脚本的文件夹 socket 设置成运行的ip:端口 logto 设置log文件 buffer-size 设置uwsgi内部缓存区大小

使用代码后台运行uwsgi(第一次运行可以先前台运行)

nohup uwsgi uwsgi.ini &

在微信公众号或测试号设置接口配置信息的URL和Token,此时才能成功提交。别忘修改py脚本里的appID、appsecret、Token

# 因为前面设置的位置是WeChat,所以这里填写WeChat

UPL: http://ip或域名/WeChat

至此大功告成!

6. 附

更改py文件后需要重启uwsgi,更改nginx的配置文件后需要重新加载nginx

如果想同时增加其他网址,例如我想实现其他功能,可以在nginx的配置文件中添加以下内容:

server {

listen 80;

server_name 11.11.111.111;

root /home/dwl/pyVenv/flask_uwsgi/myscript;

location /WeChat {

include uwsgi_params;

uwsgi_pass 127.0.0.1:5664;

}

# 新增

location /test {

include uwsgi_params;

uwsgi_pass 127.0.0.1:5664;

}

}

新增了一个location,网址是/test 同时我py文件中新增处理逻辑

@app.route('/test/aaa')

def hello():

return 'aaaaaaaaaaaaa'

@app.route('/test/')

def hello_name(name):

return 'Hello %s!' % name

这样我就能访问ip/test/aaa,和ip/test/xxx了

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: