1. 程式人生 > >微信小程序之模板消息推送

微信小程序之模板消息推送

默認 .json 定時刷新 lec pla 跳轉頁面 -a scp pscp

最近在用sanic框架寫微信小程序,其中寫了一個微信消息推送,還挺有意思的,寫了個小demo

具體見官方文檔:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/template-message/sendTemplateMessage.html

文檔其實寫的很詳細清除了,包括返回數據的類型,報錯信息

大致流程就是:調用微信小程序的接口,獲取access_token,然後再調用發送模板信息的接口,發送消息

獲取access_token

access_token的有效期目前為2個小時,需定時刷新,重復獲取將導致上次獲取的access_token失效。------>我們後臺可以用edis存儲,然後定時任務,2小時失效

獲取access_token調用接口:

#https請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
技術分享圖片
#參數說明

#參數    是否必須    說明
grant_type    是    獲取access_token填寫client_credential
appid    是    第三方用戶唯一憑證
secret    是    第三方用戶唯一憑證密鑰,即appsecret
#返回說明

#正常情況下,微信會返回下述JSON數據包給公眾號:
{"access_token":"ACCESS_TOKEN","expires_in":7200} #參數說明 #參數 說明 access_token 獲取到的憑證 expires_in 憑證有效時間,單位:秒 #錯誤時微信會返回錯誤碼等信息,JSON數據包示例如下(該示例為AppID無效錯誤): {"errcode":40013,"errmsg":"invalid appid"} #返回碼說明 #返回碼 說明 -1 系統繁忙,此時請開發者稍候再試 0 請求成功 40001 AppSecret錯誤或者AppSecret不屬於這個公眾號,請開發者確認AppSecret的正確性
40002 請確保grant_type字段值為client_credential 40164 調用接口的IP地址不在白名單中,請在接口IP白名單中進行設置。(小程序及小遊戲調用不要求IP地址在白名單內。)
接口參數以及返回參數

發送模板信息請求地址

POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN

技術分享圖片

#參數
string access_token
#接口調用憑證:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

string touser
#接收者(用戶)的 openid

string template_id
#所需下發的模板消息的id

string page
#點擊模板卡片後的跳轉頁面,僅限本小程序內的頁面。支持帶參數,(示例index?foo=bar)。該字段不填則模板無跳轉。

string form_id
#表單提交場景下,為 submit 事件帶上的 formId;支付場景下,為本次支付的 prepay_id

string data
#模板內容,不填則下發空模板

string emphasis_keyword
#模板需要放大的關鍵詞,不填則默認無放大
接口參數

接口判斷返回值

技術分享圖片
#返回值
#Object
#返回的 JSON 數據包

#屬性    類型    說明    支持版本
errcode    number    錯誤碼    
errmsg    string    錯誤信息    
errcode 的合法值

#值    說明
40037    template_id不正確
41028    form_id不正確,或者過期
41029    form_id已被使用
41030    page不正確
45009    接口調用超過限額(目前默認每個帳號日調用限額為100萬)
POST 數據格式:JSON
#請求數據示例
{
  "touser": "OPENID",
  "template_id": "TEMPLATE_ID",
  "page": "index",
  "form_id": "FORMID",
  "data": {
      "keyword1": {
          "value": "339208499"
      },
      "keyword2": {
          "value": "2015年01月05日 12:30"
      },
      "keyword3": {
          "value": "騰訊微信總部"
      } ,
      "keyword4": {
          "value": "廣州市海珠區新港中路397號"
      }
  },
  "emphasis_keyword": "keyword1.DATA"
}
#返回數據示例
{
 "errcode": 0,
 "errmsg": "ok",
 "template_id": "wDYzYZVxobJivW9oMpSCpuvACOfJXQIoKUm0PY397Tc"
}
返回值

全部代碼展示

這裏面有個特別的參數是

string form_id

表單提交場景下,為 submit 事件帶上的 formId;支付場景下,為本次支付的 prepay_id

如果想鉆空子,如果服務端想主動發送模板消息,可以提前手機formId

構建formId 池,每次將用戶提交的表單都搜集起來存入formId池,需要發送通知的時候從中取出即可。
將用戶有可能點擊的區域覆蓋一層不可見的button,並將整個頁面用於傳輸formId的button包裹在一Form標簽內,一旦用戶有點擊按鈕的操作,就將獲取到的formId傳送走。

import requests
import json as osjson
import configparser
from Model.RedisDB import VideoData


_cf = configparser.ConfigParser()
_cf.read("/septnet/config/ServerConf_V2.conf")


# 獲取微信access_token
async def get_access_token():
    try:
        payload = {
            grant_type: client_credential,
            appid: _cf.get("wechat","APPID"),
            secret: _cf.get("wechat","APPSECRET")
        }
        req = requests.get(https://api.weixin.qq.com/cgi-bin/token, params=payload, timeout=3, verify=False)
        access_token = req.json().get(access_token,"")
        print(access_token, access_token)
        return access_token
    except Exception as e:
        print(e)


# 發送模板消息
def template_push(openid,form_id,date,access_token):
    data = {
        "touser": openid,
        "template_id":  _cf.get("wechat","TEMPLATE_ID"),
        "form_id": form_id,
        page: pages/selectDetail/selectDetail?chooseSubjectTaskId=5b8de9ac705deb7cfa927abc,
        "data": {
            keyword1: {
                value: date
            },
            keyword2: {
                value: 收到消息請盡快進入小程序中接收視頻邀請,在2分鐘內如未進行操作,視頻無法成功接通,需對方再次重新發起視頻邀請
            }
        },
        "emphasis_keyword": ‘‘
    }

    push_url = https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token={}.format(access_token)
    result = requests.post(push_url, json=data, timeout=3, verify=False)
    return result


# 發送視頻通話模板消息
async def sendTemplateMessage(key,openid, form_id, date):
    req=await VideoData.get(key)
    if not req:
        access_token=get_access_token()
        if not access_token:
            return False
        try:
            req_push=template_push(openid, form_id, date, access_token)
            req_redis = await VideoData.set(key,access_token,ex=2*60*60)
            if not req_redis:
                return False
            errcode = req_push.json().get("errcode")
            if errcode==0:
                return True
            return False
        except Exception as e:
            print(e)

    access_token = osjson.loads(req)
    template_push(openid, form_id, date, access_token)
    return True

微信小程序之模板消息推送