微信消息推送

微信公众平台和小程序虽然都是腾讯开发,但是其是俩个独立的平台,包括账号也是独立存在,所以小程序和公众平台不可以使用同一个账号注册使用。

因是俩个平台,所以微信公众平台的用户openId和小程序用户openId不同,当然消息推送实现方式也不同

如果本地测试接口,需要在公众平台后台配置ip白名单,否则请求不成功

公众号消息推送

  • 模版消息通知位置:公众号详情聊天页面
  • 推送前提:模版id、参数、接收人openId、接收人必须关注公众号。
  • 模板跳转能力:点击查看详情可以跳转到指定的任意http链接

  • 1.小程序后台配置模版消息

    • 进入模版页面,点击右上角”从模版库添加“,搜索符合需求的模版消息并且配置勾选需要的参数
      ADEFB6A4-2897-4B05-9FB9-7BA5D395535F.png
    • 添加成功之后,模版列表页面复制该模版id,为后续接口调用模版消息使用
  • 2.请求接口

    请注意,URL置空,则在发送后,点击模版消息会进入一个空白页面(ios),或无法点击(android)。

    POST请求

    https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
    请求包为一个json:

    1. {
    2. "touser":"OPENID",
    3. "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
    4. "url":"http://weixin.qq.com/download",
    5. "topcolor":"#FF0000",
    6. "data":{
    7. "User": {
    8. "value":"黄先生",
    9. "color":"#173177"
    10. },
    11. "Date":{
    12. "value":"06月07日 19时24分",
    13. "color":"#173177"
    14. },
    15. "CardNumber":{
    16. "value":"0426",
    17. "color":"#173177"
    18. },
    19. "Type":{
    20. "value":"消费",
    21. "color":"#173177"
    22. },
    23. "Money":{
    24. "value":"人民币260.00元",
    25. "color":"#173177"
    26. },
    27. "DeadTime":{
    28. "value":"06月07日19时24分",
    29. "color":"#173177"
    30. },
    31. "Left":{
    32. "value":"6504.09",
    33. "color":"#173177"
    34. }
    35. }
    36. }

    发送效果图:

    image

    返回码说明

    在调用模版消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:

    1. {
    2. "errcode":0,
    3. "errmsg":"ok",
    4. "msgid":200228332
    5. }

    错误时的返回JSON数据,形式类似,错误返回码说明:

返回码 说明
-1 系统繁忙
0 请求成功
40001 验证失败
40002 不合法的凭证类型
40003 不合法的OpenID
40004 不合法的媒体文件类型
40005 不合法的文件类型
40006 不合法的文件大小
40007 不合法的媒体文件id
40008 不合法的消息类型
40009 不合法的图片文件大小
40010 不合法的语音文件大小
40011 不合法的视频文件大小
40012 不合法的缩略图文件大小
40013 不合法的APPID
41001 缺少access_token参数
41002 缺少appid参数
41003 缺少refresh_token参数
41004 缺少secret参数
41005 缺少多媒体文件数据
41006 access_token超时
42001 需要GET请求
43002 需要POST请求
43003 需要HTTPS请求
44001 多媒体文件为空
44002 POST的数据包为空
44003 图文消息内容为空
45001 多媒体文件大小超过限制
45002 消息内容超过限制
45003 标题字段超过限制
45004 描述字段超过限制
45005 链接字段超过限制
45006 图片链接字段超过限制
45007 语音播放时间超过限制
45008 图文消息超过限制
45009 接口调用超过限制
46001 不存在媒体数据
47001 解析JSON/XML内容错误

小程序消息推送

  • 模版消息通知位置:服务通知
  • 推送前提:用户有过支付行为或者提交表单操作,会生成对应的form_id,一次生成一个form_id,每次都不一样,一个form_id只可以用一次。
    (1次提交表单可下发1条,多次提交下发条数独立,相互不影响)
  • 模板跳转能力:点击查看详情仅能跳转下发模板的该帐号的小程序各个页面
    4250933-76d4c5ed3f994df3.png
    1.小程序后台配置模版消息

    • 进入模版页面,点击右上角添加按钮,搜索符合需求的模版消息并且配置勾选需要的参数
    • 添加成功之后,模版列表页面复制该模版id,为后续接口调用模版消息使用
      2.获取access_token

    • access_token 的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效。

    • 接口地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    • HTTP请求方式:GET
    • 请求参数说明
参数 必填 说明
grant_type 获取 access_token 填写 client_credential
appid 第三方用户唯一凭证
secret 第三方用户唯一凭证密钥,即appsecret

返回参数说明

正常情况下,微信会返回下述 JSON 数据包给开发者:

  1. {"access_token": "ACCESS_TOKEN", "expires_in": 7200}

access_token:获取到的凭证

expires_in:凭证有效时间,单位:秒

错误时微信会返回错误码等信息,JSON 数据包示例如下(该示例为 AppID 无效错误):

  1. {"errcode": 40013, "errmsg": "invalid appid"}

3.消息推送

  • 这里需要获取到接收人的openId

  • form_id生成方式

    • 页面的 form 组件,属性report-submit为true时,可以声明为需发模板消息,此时点击按钮提交表单可以获取formId,用于发送模板消息。或者当用户完成支付行为,可以获取prepay_id用于发送模板消息。

      • form例子

        1. <form bindsubmit="formSubmit" report-submit="true">
        2. <input name="input" class="input" placeholder="please input here" />
        3. <button formType="submit">Submit</button> <button formType="reset">Reset</button>
        4. </form>
      • js获取form_id

        1. formSubmit: function (e) {
        2. var form_id = e.detail.formId;
        3. }
    • 开始推送

参数 必填 说明
touser 接收者(用户)的 openid
template_id 所需下发的模板消息的id
page 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
form_id 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
data 模板内容,不填则下发空模板
color 模板内容字体的颜色,不填默认黑色
emphasis_keyword 模板需要放大的关键词,不填则默认无放大

示例:

  1. {
  2. "touser": "OPENID",
  3. "template_id": "TEMPLATE_ID",
  4. "page": "index",
  5. "form_id": "FORMID",
  6. "data": {
  7. "keyword1": {
  8. "value": "339208499",
  9. "color": "#173177"
  10. },
  11. "keyword2": {
  12. "value": "2015年01月05日 12:30",
  13. "color": "#173177"
  14. },
  15. "keyword3": {
  16. "value": "粤海喜来登酒店",
  17. "color": "#173177"
  18. } ,
  19. "keyword4": {
  20. "value": "广州市天河区天河路208号",
  21. "color": "#173177"
  22. }
  23. },
  24. "emphasis_keyword": "keyword1.DATA"
  25. }

返回码说明:
在调用模板消息接口后,会返回JSON数据包。
正常时的返回JSON数据包示例:

  1. ```
  2. {
  3. "errcode": 0,
  4. "errmsg": "ok"
  5. }
  6. ```

错误时会返回错误码信息,说明如下:

返回码 说明
40037 template_id不正确
41028 form_id不正确,或者过期
41029 form_id已被使用
41030 page不正确
45009 接口调用超过限额(目前默认每个帐号日调用限额为100万)

效果图如下:

CE6E7116C5C453F28FBFDC9F11412B7D.png

事件队列发送消息

针对消息推送,当一条消息需要给很多人推送时或者同时给很多人推送消息时,为了保证服务器不会奔溃和用户请求等待时间,需要使用异步队列来推送消息,目前只有微信公众号这边的消息推送做了异步事件消息队列。

具体实现原理参照:Laravel 队列laravel 事件监听

  • 队列配置

    1. 配置

      将.env队列驱动配置为利用数据库的异步处理

      1. QUEUE_DRIVER=database
    2. 生成队列数据库表与失败队列数据库表

      1. php artisan queue:table
      2. php artisan queue:failed-table
      3. php artisan migrate
    3. 开启队列监听进程

      1. php artisan queue:listen

      或者 开启后台监听(不影响自己输入其他命令)

      1. php artisan queue:listen &

      也能用work 后面参数是休息时间和尝试次数

      1. php artisan queue:work connection --daemon --sleep=3 --tries=3
  • 创建事件监听

    1. 手动注册监听事件

      在文件“/Users/guoqing/work/LouWang/app/Providers/EventServiceProvider.php”的“$listen”数组中添加监听事件路径

      eg:

      1. protected $listen = [
      2. 'App\Events\MessageRemind' => [// 事件
      3. 'App\Listeners\SendSmsWeChatRemind',// 监听器
      4. ],
      5. ];

      当然这个时候这个事件监听类还没创建,执行如下命令生成事件和监听器

      1. php artisan event:generate

      这个时候“/app/Events/”目录下生成了MessageRemind.php事件类,”/app/Listeners/“下生成了SendSmsWeChatRemind.php监听类

    2. 定义事件

      在事件触发的时候,首先进入事件类,事件类接收到传来的参数,监听器再根据传来的参数做相应的处理操作,所以事件这边基本就是参数的定义和接收传递分发功能。

      我们使用构造器接收必要的参数,并将其设置为当前事件属性。

    3. 定义监听器

      监听器handle方法注入事件
      eg:

      1. public function handle(MessageRemind $event)// 注入事件
      2. {
      3. // 获取传来的参数
      4. $remindUsers = $event->remindUsers;
      5. $rel_guid = $event->rel_guid;
      6. $type = $event->type;
      7. $weChatTemplate = $event->weChatTemplate;
      8. $smsContent = $event->smsContent;
      9. $weChatData = $event->weChatData;
      10. // 根据参数相应处理,这里做开始发送消息
      11. }

      这里有一点注意,我们怎么将处理事件操作加入到队列中异步操作呢

      在开始使用监听器队列之前,请确保在你的服务器或本地开发环境中能够配置并启动 队列 监听器。

      要指定监听器启动队列,只需将 ShouldQueue 接口添加到监听器类。由 Artisan 命令 event:generate 生成的监听器已经将此接口导入到当前命名空间中,因此你可以直接使用它:

      1. <?php
      2. namespace App\Listeners;
      3. use App\Events\MessageRemind;
      4. use Illuminate\Queue\InteractsWithQueue;
      5. use Illuminate\Contracts\Queue\ShouldQueue;
      6. class SendSmsWeChatRemind implements ShouldQueue
      7. {
      8. }

      当这个监听器被事件调用时,事件调度器会自动使用 Laravel 的 队列系统。如果在队列中执行监听器时没有抛出异常,任务会在执行完成后自动从队列中删除。

  • 手动触发监听

    调用事件的时候就简单了,只需new event 传入必须的参数即可,而且不会影响后续程序的进行

    eg:

    1. event(new MessageRemind($managers, config('status.remind_log_type_find_house_help'), null, $smsContent, $weChatData, 'findHouseHelp'));

您的支持是对我最大的鼓励!