百度小程序模板消息通知示例 - Laravel

本篇演示表单类型的模板消息通知,包含订阅。
选用/申请模板步骤,略过。

模板通知核心工具类

<?php
namespace App\Library\Tpl;
use Illuminate\Support\Facades\Cache;
use App\Library\Y; //curl类

class BdTpl {
    private $_appid;
    private $_app_key;
    private $_secret;

    /**
     * 提问创建成功通知
     * -----------------------------------------------------------
     * 提问类型{{keyword1.DATA}}
     * 提问内容{{keyword2.DATA}}
     * 提问时间{{keyword3.DATA}}
     * 备注{{keyword4.DATA}} 
     */
    const TIWEN_ID='BD1323';
    const TIWEN = '08d4f***81d9';

    public function __construct(){
        $this->_appid       = env('BD_APPID');
        $this->_app_key     = env('BD_KEY');
        $this->_secret      = env('BD_SECRET');
    }

    /**
     * 百度小程序模板通知
     * 文档地址 https://smartprogram.baidu.com/docs/develop/serverapi/sendTemplateMessage/
     *
     * POST https://openapi.baidu.com/rest/2.0/smartapp/template/send?access_token=ACCESS_TOKEN
     * application/x-www-form-urlencoded
     * 
     * @param string template_id 模板id
     * @param string touser_openId 接收者open_id
     * @param string page 跳转地址 index?foo=bar
     * @param string scene_id formId、payId 或 orderId
     * @param int    scene_type 场景 type ,1:表单;2:百度收银台订单;3:直连订单。
     * @param json/string data {"keyword1": {"value": "2018-09-06"},"keyword2": {"value": "kfc"}}
     *
     * $bdTpl = new BdTpl();
     * $bdTpl->sendTemplateMessage(BdTpl::TIWEN, $openid, '/pages/my/my', $formid, 1, $tpl);
     */
    public function sendTemplateMessage($template_id, $touser_openId, $page, $scene_id, $scene_type, $data){
        $access_token = $this->getOauthAccessToken();
        if(!$access_token){return false;}

        $params['template_id'] = $template_id;
        $params['touser_openId'] = $touser_openId;
        $params['page'] = $page;
        $params['scene_id'] = $scene_id;
        $params['scene_type'] = $scene_type;
        $params['data'] = json_encode($data);

        $url = 'https://openapi.baidu.com/rest/2.0/smartapp/template/send?access_token='.$access_token;
        $res = Y::curl($url,$params,1,1);

        if( $res && isset($res['errno']) && $res['errno'] == 0 ){
            return true;
        }else{
            return json_encode($res);
        }
    }

    /**
     * 开发者服务权限
     * 文档地址: https://smartprogram.baidu.com/docs/develop/serverapi/power_exp/
     * 推荐POST https://openapi.baidu.com/oauth/2.0/token
     * @param grant_type:必须参数,固定为“client_credentials”
     * @param client_id: 必须参数,智能小程序的AppKey 从开发者平台中获取
     * @param client_secret:必须参数,智能小程序的AppSecret 从开发者平台中获取
     * @param scope:必须参数,固定为"smartapp_snsapi_base"
     *
     * Example https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=Va5yQRHlA4Fq4eR&client_secret=0rDSjzQ20XUj5itV7WRtznPQS&scope=smartapp_snsapi_base
     * Access Token 的有效期为一个月
     */
    private function getOauthAccessToken(){
        $cache = Cache::get('tplaccesstoken');
        if( $cache ){
            return $cache;
        }

        $params['grant_type']         = 'client_credentials';
        $params['client_id']         = $this->_app_key;
        $params['client_secret']     = $this->_secret;
        $params['scope']             = 'smartapp_snsapi_base';
        $res = Y::curl("https://openapi.baidu.com/oauth/2.0/token",$params,1,1);
        if( $res ){
            Cache::put( 'tplaccesstoken', $res['access_token'], 20*24*60 );
            return $res['access_token'];
        }

        return false;
    }


}

FormId管理

首先是表设计,存放填写表单时提交的formid。(参考如下)

CREATE TABLE `form_ids` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `openid` varchar(255) NOT NULL DEFAULT '' COMMENT '用户Openid',
  `formid` varchar(255) NOT NULL DEFAULT '' COMMENT '表单模板通知',
  `is_subscribe` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否是订阅formId',
  `template_id` varchar(20) NOT NULL DEFAULT '' COMMENT '模板id',
  `created_at` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  `consume` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否已消费',
  `cons_time` timestamp NULL DEFAULT NULL COMMENT '消费时间',
  `cons_error` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

建立模型

<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use App\Library\Tpl\BdTpl; // 模板通知工具类

class FormId extends Model
{
    protected $guarded = [];
    public $timestamps = false;


    /**
     * 收集订阅 循环插入form_ids表
     * ---------------------------------------
     * @param $arr 订阅模板id数组
     * ['BD1323' => '13.cdc02275a75da3d7369333e8da3999c4.457072.1599723744.1','BD2385' => '..',]
     */
    public static function collectF(array $arr)
    {
        $user      = auth()->user();
        $openid  = $user->u_openid;
        $user_id = $user->u_id;

        $data = [];
        foreach ($arr as $template_id => $formid)
        {
            $data[] = [
                'formid'           => $formid, //13.cdc02275a75da3d7369333e8da3999c4.457072.1599723744.1
                'user_id'          => $user_id,
                'openid'         => $openid,
                'created_at'    => date('Y-m-d H:i:s',time()),
                'template_id'     => $template_id, //BD1323
                'is_subscribe'     => 1,
            ];
        }

        self::insert($data);
    }

    /**
     * 收集普通字符串form_id
     */
    public static function insertF($user_id, $openid, string $formid)
    {
        if( $formid ){
            self::insert([
                'user_id' => $user_id,
                'openid'=> $openid,
                'formid'  => $formid,
                'created_at'=>date('Y-m-d H:i:s',time()),
            ]);
        }
    }

    /**
     * 提问订阅
     */
    public static function sendPubSubscribeTemplate($user_id, $type_name, $q_content, $remark='')
    {
        $subscribe = self::where('user_id', $user_id)
                        ->where('template_id',BdTpl::TIWEN_ID)
                        ->where('is_subscribe',1)
                        ->where('consume',0) //未消费
                        ->first();
        $tpl['keyword1']['value'] = $type_name; //提问类型
        $tpl['keyword2']['value'] = $q_content; //提问内容
        $tpl['keyword3']['value'] = date('Y-m-d H:i:s',time());//提问时间
        $tpl['keyword4']['value'] = $remark;//备注

        self::send($subscribe, BdTpl::TIWEN, '/pages/my/my', $tpl);
    }

    /**
     * 非订阅表单通知 有效期7天
     */
    public static function sendReplyTemplate($user_id, $lawyer_name, $q_id, $reply_content)
    {
        $seven_days_ago = date('Y-m-d H:i:s',strtotime('-7 day'));

        $formid_record = self::where('user_id', $user_id)
                        ->where('is_subscribe',0)
                        ->where('consume',0) //未消费
                        ->where('created_at','>',$seven_days_ago) //7天之内
                        ->first();
        $tpl['keyword1']['value'] = $lawyer_name;
        $tpl['keyword2']['value'] = $reply_content;
        $tpl['keyword3']['value'] = date('Y-m-d H:i:s',time());

        self::send($formid_record, BdTpl::REPLY, '/pages/msg/chat?q_id='.$q_id, $tpl);
    }

    /**
     * 发送
     * -------------------------------------------------
     * @param $formid_record 一条模板id记录
     * @param $template_id 模板id
     * @param $page 跳转页面
     * @param $tpl 模板内容
     */
    public static function send($formid_record, $template_id, $page, $tpl)
    {
        if($formid_record)
        {
            $bdTpl = new BdTpl();
            $rs = $bdTpl->sendTemplateMessage($template_id, $formid_record->openid, $page, $formid_record->formid, 1, $tpl);
            if($rs === true){
                $formid_record->consume = 1;
                $formid_record->cons_time = date('Y-m-d H:i:s',time());
                $formid_record->save();
                return true;
            }else{
                $formid_record->consume = 1;
                $formid_record->cons_error = $rs;
                $formid_record->save();
                return false;
            }
        }else{
            return false;
        }
    }

}

收集FormId

订阅场景,可同时订阅最多3个模板,因此是 json 数组。

// ----------收集订阅模板id----------
//json数组 OR 全部拒绝授权为空字符串
$formid_arr_json = $request->post('formid','');
$formid_arr = json_decode($formid_arr_json, true); //array|null
if( is_array($formid_arr) ){ FormId::collectF($formid_arr); }

非订阅场景,表单 id 是字符串

// 收集表单form_id
$formid = $request->post('formid','');
if(is_string($formid)){
    FormId::insertF($user->id, $user->openid, $formid);
}

适当时机发送

FormId::sendPubSubscribeTemplate(
    $user_id,
    $type_name,
    mb_strlen($content)>30?mb_substr($content,0,30,'utf-8').'...':$content
);
本作品采用《CC 协议》,转载必须注明作者和本文链接
focus
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 1

学习了!

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!