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


最近在用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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM