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

选用/申请订阅模板步骤,略过。

订阅通知核心工具类

<?php
namespace App\Library\Tpl;

use App\Library\AccessToken\BdAccessToken;
use App\Library\Y;

class BdTpl extends BdAccessToken {
    // 百度小程序 模板序列号 => template_id
    public static $serials = [
        'BD1..' => '08d4f3ad...9c2fee981d9',
        'BD2..' => '4d353d38b...1415471cfcd',
        'BD0..' => '5e5e9babf...d28e52e2d3b',
    ];
    // template_id => 场景
    public static $scenes = [
        '08d4f3...ee981d9' => 'tiwen',
        '5e5e9b...52e2d3b' => 'reply',
        '7cf719...eca7065' => 'discuss',
    ];
    /**
     * 提问创建成功通知
     * -----------------------------------------------------------
     * 提问类型{{keyword1.DATA}}
     * 提问内容{{keyword2.DATA}}
     * 提问时间{{keyword3.DATA}}
     * 备注{{keyword4.DATA}}
     */
    const TIWEN_ID='BD13xx';
    const TIWEN = '08d4fxx..xxx2fee981d9';

    public static function getTiwenTpl($typename, $qcontent, $mark='') {
        $tpl['keyword1']['value'] = $typename;
        $tpl['keyword2']['value'] = $qcontent;
        $tpl['keyword3']['value'] = date('Y年m月d日 H:i',time());
        $tpl['keyword4']['value'] = $mark;//备注
        return $tpl;
    }

    /**
     * 百度小程序模板通知
     * 文档地址 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);
        }
    }
}

FormId管理

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

CREATE TABLE `form_ids` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `platform` varchar(20) DEFAULT NULL COMMENT '平台 必须',
  `user_id` int(10) unsigned NOT NULL,
  `u_openid` varchar(100) DEFAULT NULL COMMENT '用户Openid',
  `formid` varchar(200) DEFAULT NULL COMMENT '表单模板通知仅百度,微信没有',
  `template_id` varchar(60) NOT NULL DEFAULT '' COMMENT '模板id',
  `scene` enum('unknow','discuss','reply','grab','tiwen') DEFAULT 'unknow' COMMENT '自定义场景',
  `bind_id` varchar(15) DEFAULT NULL COMMENT '绑定的id 如Q-123456',
  `created_at` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  `consume` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT '是否已消费',
  `cons_time` timestamp NULL DEFAULT NULL COMMENT '消费时间',
  `cons_error` varchar(255) NOT NULL DEFAULT '',
  `is_subscribe` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '是否是订阅',
  `subscribe_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '订阅id,区分订阅事件',
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `bind_id` (`bind_id`)
) ENGINE=InnoDB AUTO_INCREMENT=624316 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;


    /**
     * 订阅
     * @param array $arr 订阅数组
     * @param object $question QuesitonModel
     * @return boolean
     */
    public static function subscribeQuestion($arr, Question $question)
    {
        $user = User::select(['u_id', 'u_platform', 'u_openid'])->where('u_id', $question->user_id)->first();
        $base['u_openid'] = $user->u_openid;
        $base['user_id'] = $question->user_id;
        $base['bind_id'] = 'Q-' . $question->id;
        $base['created_at'] = date('Y-m-d H:i:s', time());

        $data = [];
        $platform = $user->u_platform;

        if ($platform == 'MP-BAIDU') {
            $serials = BdTpl::$serials;
            $scenes = BdTpl::$scenes;
            foreach ($arr as $serial => $formid) {
                if (isset($serials[$serial])) {
                    $data[] = array_merge($base, [
                        'platform' => 'MP-BAIDU',
                        'scene' => $scenes[$serials[$serial]],
                        'template_id' => $serials[$serial],
                        'formid' => $formid,
                    ]);
                }
            }
        } elseif ($platform == 'MP-WEIXIN') {
            foreach ($arr as $template_id => $action) {
                if ($action == 'accept') {
                    $scenes = WxTpl::$scenes;
                    $data[] = array_merge($base, [
                        'platform' => 'MP-WEIXIN',
                        'scene' => $scenes[$template_id],
                        'template_id' => $template_id,
                    ]);
                }
            }
        }

        return !empty($data) && FormId::insert($data);
    }

    /**
     * 问题创建成功通知
     * @param int $q_id 问题id
     * @param string $typename 免费问|付费问|电话问
     * @param string $q_content 问题内容
     * @param string $mark 备注
     */
    public static function sendPublishedSubscribeMsg($q_id, $typename, $q_content, $mark = '') {
        $bind_id = 'Q-' . $q_id;
        $subscribe = FormId::where('bind_id', $bind_id)->where('scene', 'tiwen')->first();
        if (!$subscribe) {
            return false;
        }
        $page = '/packageM/my/questions';
        $q_content = mb_substr($q_content, 0, 10, 'utf-8');
        switch ($subscribe->platform) {
            case 'MP-BAIDU':
                $data = BdTpl::getTiwenTpl($typename, $q_content, $mark);
                break;
            case 'MP-WEIXIN':
                $data = WxTpl::getTiwenTpl($typename, $q_content, $mark);
                break;
            default:
                return false;
                break;
        }
        return self::sendTo($subscribe, $page, $data);
    }
    /**
     * 发送
     * @param object $formid_record 订阅消息记录
     * @param string $page 页面
     * @param array $data 数据
     * @return boolean 
     */
    public static function sendTo($formid_record, $page, $data)
    {
        if (!$formid_record) {
            return false;
        }
        $platform = $formid_record->platform;
        switch ($platform) {
            case 'MP-BAIDU':
                $rs = (new BdTpl())->sendTemplateMessage(
                    $formid_record->template_id,
                    $formid_record->u_openid,
                    $page,
                    $formid_record->formid,
                    1,
                    $data
                );
                break;
            case 'MP-WEIXIN':
                $rs = (new WxTpl())->sendSubscribeMessage(
                    $formid_record->template_id,
                    $formid_record->u_openid,
                    $page,
                    $data
                );
                break;
            default:
                return false;
                break;
        }

        if ($rs === true) {
            $formid_record->consume = $formid_record->consume + 1;
            $formid_record->cons_time = date('Y-m-d H:i:s', time());
            $formid_record->save();
            return true;
        } else {
            $formid_record->cons_time = date('Y-m-d H:i:s', time());
            $formid_record->cons_error = $rs;
            $formid_record->save();
            return false;
        }
    }
}

收集FormId

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

// -----订阅------
$formid_arr_json = $request->post('formid', '');
$formid_arr = json_decode($formid_arr_json, true); //array|null
is_array($formid_arr) && FormId::subscribeQuestion($formid_arr, $question);

适当时机发送

FormId::sendPublishedSubscribeMsg(
    $question->id,
    $question->type_name,
    $question->q_content,
    '点击查看详情'
);
本作品采用《CC 协议》,转载必须注明作者和本文链接
welcome come back
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
95
粉丝
24
喜欢
156
收藏
347
排名:323
访问:2.9 万
私信
所有博文
社区赞助商