### [如何实现小程序发送服务通知](https://www.prosaas.cn/article/16660) **Published:** 2020-06-10T03:27:54 **Author:** 5201314 **Excerpt:** 如何实现小程序发送服务通知?小程序给用户发送消息需要比较多的验证,刚刚遇到这个需求可能会花较长时间研究测试,所…  **如何实现小程序发送服务通知?** 小程序给用户发送消息需要比较多的验证,刚刚遇到这个需求可能会花较长时间研究测试,所以从基础整理了一整套发送消息的逻辑,为以后开发消息通知功能提供思路,减少学习时间 发送模板消息主要有以下几个部分 > 一、获取access\_token > > 二、建立消息模板 > > 三、获取form\_id > > 四、发送消息通知 > > 五、设定定时任务 > > 一、获取access\_token 向微信请求发送消息时,会需要到access\_token,access\_token相当于是小程序的身份证,虽然有appid和appsecret这2个证明,但是微信为了保证安全性,就用了access\_token这个有时效的身份证明来验证,一条access\_token只有2小时有效期,而且单个小程序1天只能请求1000次access\_token,所以我们需要一套逻辑来保证access\_token的可用性 https://api.weixin.qq.com/cgi-bin/token?grant\_type=client\_credential&appid=APPID&secret=APPSECRET 只需要向上面这个地址请求就可以返回对应的access\_token 根据这个接口,写如下方法 public function test(){ $appId = ''; $appSecret = ''; $token = file\_get\_contents("https://api.weixin.qq.com/cgi-bin/token?grant\_type=client\_credential&appid=".$appId."&secret=".$appSecret); $token = json\_decode($token); $token = $token->access\_token; db('token')->where('id',1)->update(\['access\_token'=>$token\]);//覆盖上一条access\_token } 再设置一个定时器每小时触发一次该接口,之后就可以随意取出肯定能用的token了 $token = db('token')->find(); $token = $token\['access\_token'\]; **二、建立消息模板** 在小程序微信公众平台的左边栏有一个模板消息的选项卡,只需要按照文档添加一个模板消息,就可以得到对应的对应的模板ID,这一步基本都是网页自行操作,不作更多展示 **三、获取form\_id** 微信为了防止小程序对用户进行过多消息通知,对消息通知进行了一个限制,每发送一条消息通知,就需要一条form\_id或者prepay\_id prepay\_id是用户在使用微信支付之后返回的Id,本文中不做详解 form\_id是与button绑定的Id,每当用户点击绑定过的button就会返回一条form\_id,一条form\_id的有效期是7天,且每个用户的form\_id只能对该用户使用,所以我们需要一个专门的逻辑来保存和使用form\_id ①设计form\_id表结构 form\_id有2个条件,第一个是仅7天内有效,第二个是仅对创建form\_id的用户有效,针对这2个要求建立如下表 创建时间用户id idcreateTimeopenIdform\_id id作为主键自增不用解释 createTime作为找到过期form\_id的标志,设置定时任务,删除过期form\_id openId用来找到用户自己的form\_id来使用 ②取到form\_id
// pages/index/index.js form\_id: function(e) { wx.request({ url: 'test.com/index/index/form\_id',//自行替换接口 method: "POST", data: { form\_id: e.detail.formId, openId: openId//自行获取当前用户openId }, header: { 'content-type': 'application/x-www-form-urlencoded' } }) }, //test.com/index/index/form\_id public function form\_id(){ if (empty($\_POST)) {die;} $form\_id = $\_POST\['form\_id'\]; if ($form\_id == 'the formId is a mock one'){die;}//过滤开发工具生成的form\_id $openId = $\_POST\['openId'\]; if (!$openId) {die;} $data = compact('form\_id','openId'); db('form\_id')->insert($data); } ③使用form\_id public function test(){ $openId = ''; $form\_id = db('form\_id')->where('openId',$openId)->order('id')->field('form\_id')->find(); $form\_id = $form\_id\['form\_id'\]; } ④定时删除过期form\_id public function test(){ $time = time()-518400;//保证form\_id可用性删除6天前的form\_id db('form\_id')->where('createTime','<',$time)->delete(); //将该方法每天执行一次 } 四、发送消息通知 当access\_token和form\_id都保证可用之后,就可以给用户发送消息通知了 public function message($data){ //获取form\_id $form\_id = db('form\_id')->where('openId',$openId)->order('id')->find(); if (!$form\_id) {die;} $form\_id = $form\_id\['form\_id'\]; db('form\_id')->where('form\_id',$form\_id)->delete(); //获取access\_token $access\_token = db('token')->where('id',1)->find(); $access\_token = $access\_token\['access\_token'\]; //获取消息内容 $openId = $data\['openId'\]; $title = $data\['title'\]; $data1 = $data\['data1'\]; $data2 = $data\['data2'\]; $request\_url='https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access\_token='.$access\_token; $request\_data=\[ 'touser' => $openId, 'template\_id' => '',//表id 'page' => 'pages/test/test?data1='.$data1.'&data2='.$data2,//本消息点击后跳转到的页面 "form\_id" => $form\_id, 'data' => \[ 'keyword1' => \[ 'value' => $title \], 'keyword2' => \[ 'value' => $data1 \], 'keyword3' => \[ 'value' => $data2 \] \], 'emphasis\_keyword' => "keyword1.DATA"//消息中要放大的内容 \]; $return=json\_decode($this->request($request\_url,$request\_data),true);//发送消息,并读取返回值 return $return; } //上面的$this->request方法 public function request($url, $data=null) { $headers=array('Content-type:application/json;charset=UTF-8','Accept:application/json','Cache-Control:no-cache','Pragma:no-cache'); $curl=curl\_init(); curl\_setopt($curl, CURLOPT\_URL, $url); curl\_setopt($curl, CURLOPT\_SSL\_VERIFYPEER, false); curl\_setopt($curl, CURLOPT\_SSL\_VERIFYHOST, false); if (!empty($data)) { $data=json\_encode($data); curl\_setopt($curl, CURLOPT\_POST, 1); curl\_setopt($curl, CURLOPT\_POSTFIELDS, $data); } curl\_setopt($curl, CURLOPT\_RETURNTRANSFER, 1); curl\_setopt($curl, CURLOPT\_HTTPHEADER, $headers); $output=curl\_exec($curl); curl\_close($curl); return $output; } 五、设定定时任务 为了保证上述操作都能顺利进行,我们需要设定几个定时任务来帮助消息发送,先假设有几个方法 > getToken //每小时更新一次token > > delForm\_id //每天删除一次6天前的form\_id > > message //每分钟执行一次发送消息 首先连接上服务器打开定时任务设置 crontab -e 设置中的每一行就是一个定时任务,分成3个部分 1.\* \* \* \* \* 这5个参数分别表示定时任务的执行时间,每个参数与上个参数隔一个空格,分别为(分)(时)(天)(月)(星期),下面举例子 \* \* \* \* \*//每分钟执行一次 0 \* \* \* \*//每小时的第0分钟执行一次 \*/5 \* \* \* \*//每5分钟执行一次 \* 23 \* \* \*//每天的23点执行一次 \* \* 1 \* \*//每月1号执行一次 \* \* \* \*/2 \*//每2个月执行一次 0 0 \* \* 6//每周6的0点0分执行一次 2.`/usr/bin/php` 这是php执行文件的路径,如果cd到该路径,给出php执行文件路径就会执行php文件,可以用来测试php文件是否可以设置定时任务 注意,这个路径只是一个快捷方式,真正的php执行文件在`/usr/local/php/bin/php`或者`/usr/local/php`(版本号)`/bin/php`,如果在bin下没有创建快捷方式请自行创建 3./项目路径/执行文件 这是需要执行的php文件路径,如果写的是原生php,直接指到该文件即可,如果是用thinkphp框架写的,那需要指到根目录或者public目录下的index.php,后边跟上/模块/控制器/方法 知道这3点我们就可以写出上述3个定时任务 \* \*/1 \* \* \*/usr/bin/php /项目路径/index.php /index/index/getToken \* 4 \* \* \*/usr/bin/php /项目路径/index.php /index/index/delForm\_id \* \* \* \* \*/usr/bin/php /项目路径/index.php /index/index/message 最后,重启一下定时任务 //CentOS5/CentOS6 /sbin/service crond restart //CentOS7 /bin/systemctl restart crond.service 相关推荐:小程序教程 以上就是如何实现小程序发送服务通知的详细内容,更多请关注知企PROSAAS其它相关文章! **Categories:** 后端开发 ---