微信小程序模板消息实现(PHP+小程序)
什么是小程序模板消息?小程序模板消息如何实现?程序模板消息推送以及相关注意事项
参考官方文档和部分资料,总结小程序模板消息推送以及相关注意事项,楼主踩过的坑,特来与大家分享。
一、开发准备:
1. 在微信公众平台 – 小程序的模板中心申请消息模板
二、实现原理:
文档示例:小程序 + 接口(PHP)
小程序部分:
话不多说,先上效果图:
示例代码:
<form bindsubmit="formSubmit" report-submit=\'true\' > <view class="btn-area"><button formType="submit">Submit</button></view> </form> formSubmit: function (e) { console.log(\'form发生了submit事件,formId为:\', e.detail) var that = this; wx.request({ url: \'https://api.XXX.com/sendTemplateMessage.api\', data: { uid: uid, formId: e.detail.formId }, method: \'post\', header: {\'content-type\': \'application/x-www-form-urlencoded\'}, //使用这种方式后台才能实现获取到数据 success: function (res) { console.log("发送模板:" + res.data) } })
注意事项:
小程序通 submit 点击事件获 formid 在安卓和 IOS 是不一样的,安卓系统中为 13 位时间戳,而 IOS 系统中为 32 位字符串,在做接口请求时,不需要做额外处理。
安卓系统
IOS系统
PHP 接口部分:
1. 根据微信公众平台 — 设置 — 消息推送 — URL (服务器地址),在 PHP 项目配置入口文件,实现请求分发。
2. 验证入口文件,传递 token 令牌(消息推送的 token),进行 Signature 签名有效性验证,完成之后才能进行消息模板的服务器 URL 地址配置。
<?php define(\'SS_START_TIME\', microtime(true)); define(\'RUN_SS\', true); require \'../ss/ss.php\'; $ss = new ss(\'xcx\'); $ss->execute(\'xcx\', \'valid\', \'xcx\'); ?> <?php // 小程序验证入口文件 public function xcx(){ $type = $token; //Token(令牌) if ($this->checkSignature($type) && isset($_GET[\'echostr\'])){ echo $_GET[\'echostr\']; exit(); } } /** * 校验微信加密签名 * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) bool */ private function checkSignature($type = \'\'){ // 微信服务器配置Token $token = $type; // 1.将timestamp,token,nonce按字典序排序 $timestamp = $_GET[\'timestamp\']; $nonce = $_GET[\'nonce\']; $signature = $_GET[\'signature\']; $arr = array($timestamp, $token, $nonce); sort($arr, SORT_STRING); // 2.拼接为字符串并sha1加密 $tmpStr = implode($arr); $tmpStr = sha1($tmpStr); // 3.与signature对比判断是否来自微信服务器 if ($tmpStr == $signature){ return true; }else{ return false; } } ?>
可在 https://mp.weixin.qq.com/debug/ 调试获取 access_token
3. 微信公众平台 – 设置 – 开发设置配置消息推送(需要先将入口文件上传服务器)
4. 在微信公众平台获取相关参数:
AppID (小程序 ID)、AppSecret (小程序密钥)、Token (令牌)、TemplateId(模板 id)、EncodingAESKey (消息加密密钥)
4.1 小程序模板接口
/* *小程序模板消息 *@param uid 用户id *$param template_id 模板id *@param form_id 表单提交场景下formId(只能用一次) *@param emphasis_keyword 消息加密密钥 */ public function sendTemplateMessage($uid,$form_id,$template_id){ // 检验uid合法性 防止非法越界 $nickname = "nickname"; // 用户昵称 // 此openid为小程序的openid切勿与微信自动登录的openid混淆 $xcx_open[\'openid\'] = "用户openid"; // openid可以通过PHP接口或者小程序获取 if ($xcx_open[\'openid\']) { $temp_msg = array( \'touser\' => "{$xcx_open[\'openid\']}", \'template_id\' => "{$template_id}", \'page\' => "/pages/index/index", \'form_id\' => "{$form_id}", \'data\' => array( \'keyword1\' => array( \'value\' => "{$nickname}", ), \'keyword2\' => array( \'value\' => date(\'Y-m-d H:i:s\', time()), ), \'keyword3\' => array( \'value\' => "好友已完成测试,快去看看吧!", ), \'keyword4\' => array( \'value\' => "你收到1封新信件,快去看看吧~", ), ), \'emphasis_keyword\'=> "{$emphasis_keyword}" ); $res = $this->sendXcxTemplateMsg(json_encode($temp_msg)); echo "<pre>";var_dump($res);exit; } }
4.2 发送小程序模板消息
/** * 发送小程序模板消息 * @param $data * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) array */ public function sendXcxTemplateMsg($data,$appid = "",$appsecret = "") { // 具体模板格式参考公众平台申请的template_id if (!$appid || !$appsecret) { $appid = \'\'; //小程序id $appsecret = \'\'; //小程序秘钥 } $access_token = $this->getXcxAccessToken($appid,$appsecret); $url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token={$access_token}"; return $this->http_request($url, $data); }
请求数据格式如下:
{ "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" }
4.3 获取 access_token
/** * 获取微信接口调用凭证 * @param string $appid * @param string $appsecret * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) mixed */ public function getXcxAccessToken($appid = \'\', $appsecret = \'\') { if (!$appid || !$appsecret) { $appid = \'\'; $appsecret = \'\'; } // 缓存获取 $cache = &factory::cache(); if (!$cache->get($appid.\'xcx_access_token\')) { $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}"; $res = $this->http_request($url); // access_token设置到缓存中 $cache->set($appid.\'xcx_access_token\', $res[\'access_token\'], 7000); return $res[\'access_token\']; } return $cache->get($appid.\'xcx_access_token\'); }
4.4 CURL 模拟 HTTP 请求(POST)`
/** * curl模拟http请求GET/POST * @param $url * @param null $data * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) array */ public function http_request($url, $data = null) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // 以文件流形式返回 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if (!empty($data)) { // POST请求 curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } $output = curl_exec($ch); curl_close($ch); // 返回数组 return json_decode($output, true); }
传递参数:根据定义接口传递相关参数,用户 uid 通过 uid 获取 openid,此 openid 为小程序的 openid, formId 为表单提交场景下,为 submit 事件带上的 formId,formid 在安卓和 ios 下的数据格式和长度不一致,而且小程序获取 formid 只支持真机调试。
接口调试:errcode 的合法值
值 说明
40037 template_id 不正确
41028 form_id 不正确,或者过期
41029 form_id 已被使用
41030 page 不正确
45009 接口调用超过限额(目前默认每个帐号日调用限额为 100 万)
请求成功:
{ "state": 1, "data": { "errcode": 0, "errmsg": "ok" }, "info": "successful!" }
至此,推送功能完整实现!