百度小程式模板訊息通知示例 - Laravel

php_yt發表於2020-09-19

本篇演示表單型別的模板訊息通知,包含訂閱。
選用/申請模板步驟,略過。

模板通知核心工具類

<?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

相關文章