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


    最近在用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
  • 相关阅读:
    计数排序
    epel
    Web开发:我希望得到的编程学习路线图
    第五章:if语句与运算符
    java web学习建议
    第四章:c++数据类型
    第二章:做一个最简单的c++程序
    linux的商业应用
    第三章:初步了解函数
    解析Linux商业应用现状
  • 原文地址:https://www.cnblogs.com/zzy-9318/p/9831641.html
Copyright © 2020-2023  润新知