Python開發微信公衆號

一、微信瞭解

1、微信相關功能

2、公衆號

  • 公衆號類型
類型 功能 適用人羣
訂閱號 爲媒體和個人提供一種新的信息傳播方式,主要功能是在微信側給用戶傳達資訊;(功能類似報紙雜誌,提供新聞信息或娛樂趣事) 個人、媒體、企業、政府或其他組織
服務號 爲企業和組織提供更強大的業務服務與用戶管理能力,主要偏向服務類交互(功能類似12315,114,銀行,提供綁定信息,服務交互的) 媒體、企業、政府或其他組織
  • 區別:
區別 訂閱號 服務號
發送次數 每天多一次 每月最多一次
顯示位置 消息摺疊出現在訂閱號的文件夾中,不會收到微信提醒 消息出現在微信聊天列表中,會像收到消息一樣有微信提醒
支付功能 認證的服務號有支付功能

二、微信公衆號開發—準備工作

1、appID、appsecret

2、Ngrok獲得公網域名

3、測試驗證是否配置成功

  • 運行Ngrok(python sunny.py --clientid=*****)>運行python腳本>提交配置>顯示配置成功
    在這裏插入圖片描述
  • python腳本如下,常量部分需替換成自己的, 第一次接入微信服務器的驗證流程圖;
    在這裏插入圖片描述
from flask import Flask, request, abort, render_template
import hashlib


# 常量
WECHAT_TOKEN = "***"  # 微信的token令牌,可隨便寫,但和配置時的token要統一
WECHAT_APPID = "****"  # appID
WECHAT_APPSECRET = "*****"  # AppSecret

app = Flask(__name__)


@app.route("/wechat", methods=["GET", "POST"])
def wechat():
    """對接微信公衆號服務器"""
    # 1、提取微信服務器發送的參數
    signature = request.args.get("signature")
    timestamp = request.args.get("timestamp")
    nonce = request.args.get("nonce")

    # 2、校驗參數,確定數據源是不是微信後臺
    if not all([signature, timestamp, nonce]):
        abort(400)

    # 3、按照微信的流程進行計算簽名,進行sha1加密, 得到正確的簽名值
    li = [WECHAT_TOKEN, timestamp, nonce]
    li.sort()
    tmp_str = "".join(li)
    sign = hashlib.sha1(tmp_str.encode("utf-8")).hexdigest()

    # 4、判斷計算的簽名值與請求的簽名參數是否等,如果相同,則證明請求來自微信服務器
    if signature != sign:
        abort(403)
    else:
        # 5、表示是第一次接入微信服務器的驗證
        if request.method == "GET":
            echostr = request.args.get("echostr")
            if not echostr:
                abort(400)
            return echostr


if __name__ == '__main__':
    app.run(host="127.0.0.1", port=8080, debug=True)

三、微信公衆號開發—實現自動回覆文本/圖片

  • 接收普通消息,當普通微信用戶向公衆賬號發消息時,微信服務器將POST消息的XML數據包到開發者填寫的URL上

1、代碼流程圖

在這裏插入圖片描述

2、python腳本實現

  • 運行Ngrox,以及python腳本,在瀏覽器打開http://wecht.test.idce.com/wechat(wecht.test.idce.com替換成你自己的域名)
  • 手機掃描測試號二維碼,在手機端的公衆號發送消息,即可體驗自動回覆內容
    在這裏插入圖片描述
from flask import Flask, request, abort, render_template
import hashlib
import xmltodict
import time


# 常量
WECHAT_TOKEN = "*****"  # 微信的token令牌,可隨便寫,但和配置時的token要統一
WECHAT_APPID = "*****"  # appID
WECHAT_APPSECRET = "*****"  # AppSecret

app = Flask(__name__)


@app.route("/wechat", methods=["GET", "POST"])
def wechat():
    """對接微信公衆號服務器"""
    # 1、提取微信服務器發送的參數
    signature = request.args.get("signature")
    timestamp = request.args.get("timestamp")
    nonce = request.args.get("nonce")

    # 2、校驗參數,確定數據源是不是微信後臺
    if not all([signature, timestamp, nonce]):
        abort(400)

    # 3、按照微信的流程進行計算簽名,進行sha1加密, 得到正確的簽名值
    li = [WECHAT_TOKEN, timestamp, nonce]
    li.sort()
    tmp_str = "".join(li)
    sign = hashlib.sha1(tmp_str.encode("utf-8")).hexdigest()

    # 4、判斷計算的簽名值與請求的簽名參數是否等,如果相同,則證明請求來自微信服務器
    if signature != sign:
        abort(403)
    else:
        # 5、表示是第一次接入微信服務器的驗證
        if request.method == "GET":  
            echostr = request.args.get("echostr")
            if not echostr:
                abort(400)
            return echostr
        # 6、對微信服務器轉發粉絲發過來的消息,進行回覆
        elif request.method == "POST":  
            xml_data = request.data
            if not xml_data:
                abort(400)
            xml_dict = xmltodict.parse(xml_data)
            xml_dict = xml_dict.get("xml")
            msg_type = xml_dict.get("MsgType")  # 提取消息類型
            content = xml_dict.get("Content")
            if content == "hello":
                content = "hello,小可愛"
            resp_dict = {
                "xml": {
                    "ToUserName": xml_dict.get("FromUserName"),
                    "FromUserName": xml_dict.get("ToUserName"),
                    "CreateTime": int(time.time()),
                }
            }
            # 7、實現“你問我答”,構造返回值,由微信服務器回覆給粉絲髮來的文本內容
            if msg_type == "text":
                resp_dict['xml'].update({
                    "MsgType": "text",
                    "Content": content
                })
            # 8、實現“圖”尚往來,構造返回值,由微信服務器回覆給粉絲髮來的圖片內容
            elif msg_type == "image":
                resp_dict['xml'].update({
                    "MsgType": "image",
                    "Image": {
                        "MediaId": xml_dict.get("MediaId")
                    },
                })
            # 9、如果既不是文本,也不是圖片,比如語音,返回非文本、非圖片
            else:
                resp_dict['xml'].update({
                    "MsgType": "text",
                    "Content": "非文本,非圖片內容"
                })
            resp_xml_str = xmltodict.unparse(resp_dict)  # 將字典轉換爲xml字符串
            return resp_xml_str  # 返回消息數據給微信服務器


if __name__ == '__main__':
    app.run(host="127.0.0.1", port=8080, debug=True)

四、微信公衆號開發—獲取accessToken

1、python腳本實現

  • 運行Ngrox,以及python腳本;瀏覽器打開http://wecht.test.idce.com/accestoken(wecht.test.idce.com替換成你自己的域名),即可獲得accesstoken
    在這裏插入圖片描述
from flask import Flask
import requests


# 常量
WECHAT_TOKEN = "****"  # 微信的token令牌,可隨便寫,但和配置時的token要統一
WECHAT_APPID = "****"  # appID
WECHAT_APPSECRET = "****"  # AppSecret

app = Flask(__name__)


@app.route("/accestoken")
def acc():
    url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=" \
        f"client_credential&appid={WECHAT_APPID}&secret={WECHAT_APPSECRET}"
    resp = requests.get(url)
    text = resp.text
    return text


if __name__ == '__main__':
    app.run(host="127.0.0.1", port=8080, debug=True)

五、微信公衆號開發—網頁授權拉取用戶信息

1、操作步驟

  • 運行python腳本,並運行Ngrox(python sunny.py --clientid=你的clientid);
  • 接口權限區域:修改OAuth2.0授權回調頁面域名(你的公網域名,例如wecht.test.idce.com);
    在這裏插入圖片描述
  • 編寫授權url如下,APPID替換成你自己的,REDIRECT_URI替換成http%3A//wecht.test.idce.com/wechat/index(wecht.test.idce.com替換成你自己的域名)
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect 
  • 在微信裏打開上面的編好的授權url,即可顯示用戶信息
    在這裏插入圖片描述

2、python腳本實現

  • 運行Ngrox,以及python腳本;瀏覽器打開http://wecht.test.idce.com/wechat/index(wecht.test.idce.com替換成你自己的域名),會顯示無code;
from flask import Flask, request, render_template
import requests


# 常量
WECHAT_TOKEN = "****"  # 微信的token令牌,可隨便寫,但和配置時的token要統一
WECHAT_APPID = "****"  # appID
WECHAT_APPSECRET = "****"  # AppSecret

app = Flask(__name__)


@app.route("/wechat/index")
def index():
    # 從微信服務器中拿去用戶的資料數據
    # 1. 獲取code參數
    code = request.args.get("code")
    if not code:
        return "無code"

    # 2. 向微信服務器發送http請求,獲取access_token
    url = f"https://api.weixin.qq.com/sns/oauth2/access_token?" \
        f"appid={WECHAT_APPID}&secret={WECHAT_APPSECRET}&" \
        f"code={code}&grant_type=authorization_code"
    response = requests.get(url)
    resp_dict = response.json()
    if "errcode" in resp_dict:
        return "獲取access_token失敗"
    access_token = resp_dict.get("access_token")
    open_id = resp_dict.get("openid")

    # 3. 向微信服務器發送http請求,獲取用戶的資料數據
    url = f"https://api.weixin.qq.com/sns/userinfo?access_token={access_token}&openid={open_id}&lang=zh_CN"
    response = requests.get(url)
    user_resp_dict = response.json()
    if "errcode" in user_resp_dict:
        return "獲取用戶信息失敗"
    else:
        # 將用戶的資料數據填充到頁面中
        return render_template("index.html", user=user_resp_dict)


if __name__ == '__main__':
    app.run(host="127.0.0.1", port=8080, debug=True)

3、html模板

  • 在templates文件夾下新建index.html
    在這裏插入圖片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{user["nickname"]}}</title>
</head>
<body>
    <img alt="頭像" src="{{user['headimgurl']}}">
    <table>
        <tr>
            <th>openid</th>
            <td>{{user['openid']}}</td>
        </tr>
        <tr>
            <th>province</th>
            <td>{{user['province']}}</td>
        </tr>
        <tr>
            <th>city</th>
            <td>{{user['city']}}</td>
        </tr>
    </table>

</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章