前段时间做毕设用到过,怕以后会忘记,特地记录下,主要是发送模板信息和批量收集formid
效果图
首先小程序发送模板信息需要以下几样参数
官方文档
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/template-message.html
1.获取access_token (需要知道小程序的appid和appsecret)
接口地址:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
返回格式:
{"access_token": "ACCESS_TOKEN", "expires_in": 7200}
当然,由于调用token接口的次数是有限制的。。所以可以先将获取到的token缓存起来,要用的时候先检测缓存是否过期(2个小时),如果没过期就直接使用缓存中的token,过期就调用接口。此处用的是TP5框架
public function access_token()
{
$appid = 'xxxxxxxx';
$appsecret = 'xxxxxxxx';
$access_token=Cache::get('weixin_access_token');
if($access_token)
{
return json(['access_token'=>$access_token]);
}else{
$url_get ='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret;
$ch1 = curl_init ();
$timeout = 5;
curl_setopt ( $ch1, CURLOPT_URL, $url_get );
curl_setopt ( $ch1, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch1, CURLOPT_CONNECTTIMEOUT, $timeout );
curl_setopt ( $ch1, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch1, CURLOPT_SSL_VERIFYHOST, false );
$accesstxt = curl_exec ( $ch1 );
curl_close($ch1 );
$access = json_decode ( $accesstxt, true );
// 缓存数据7200秒
Cache::set('weixin_access_token',$access['access_token'],7200);
return json(['access_token'=>$access['access_token']]);
}
}
2.获取模板id
在微信公众平台搜索选择你所需要的模板信息,
可以调整关键词的顺序,提交之后可直接在详情查看复制模板id
3.获取openid(需要appid和appsecret)
获取openid的方法网上有很多,这里贴几个博主的写的
https://blog.csdn.net/qq_27626333/article/details/54614037
https://blog.csdn.net/qq_34328404/article/details/80624577
https://www.cnblogs.com/YSPyishuihan/p/6885242.html
注:如果是单纯获取openid,可直接获取,不需要用户授权。。。接下来放上我自己的写法(仅供参考)
小程序端
onLoad: function (options) {
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
var code = res.code;
var that=this;
//console.log(code);
wx.request({
url: "https://后台接口地址",
data: {
"code": code
},
header: {
'content-type': 'application/json'
},
method: 'GET',
success: function (res) {
// success
console.log(res.data.openid);
that.setData({
openid:res.data.openid
})
}
})
}
})
},
后台接口端(TP5)
public function login($code)
{
$code=Request::instance()->param('code');
$appid = 'xxxxxxxxx';
$appsecret = 'xxxxxxx';
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$appid.'&secret='.$appsecret.'&js_code=' . $code . '&grant_type=authorization_code';
$info = file_get_contents($url);//发送HTTPs请求并获取返回的数据,推荐使用curl
$json = json_decode($info,true);//对json数据解码
$openid=$json['openid'];
if($openid)
{
return json(['status'=>0,'openid'=>$openid]);
}else{
return json(['status'=>1,'msg'=>"error"]);
}
}
4.form_id
首先formid有两种获取途径。一是支付行为,二是用户在真机上提交表单,官方文档写得很清楚了。这里获取到formid后可以存到数据库中,等待使用。formid有效期是七天,一个formid只能使用一次,使用后就相当于过期了。但是多个formid互相独立,相当于你提交十个表单就有十个formid
这里再贴几个博主的文章
https://www.cnblogs.com/YSPyishuihan/p/6891262.html
https://segmentfault.com/a/1190000016214784
https://blog.csdn.net/u011415782/article/details/82379590
https://blog.csdn.net/lgj199505/article/details/82425425
接下来放上我自己的写法(仅供参考)
小程序端:
formSubmit:function(e){
var form_id = e.detail.formId;
var openid = e.detail.value.openid;
wx.request({
url: 'https://后台地址',
data: {
"form_id": form_id,
"openid":openid
},
header: {
'content-type': 'application/json'
},
method: 'GET',
success: function (res) {
console.log(res.data);
}
})
}
后台接口端:(将openid一起存入数据库)
public function reg()
{
$play_data['form_id'] = Request::instance()->param('form_id');
$play_data['openid'] = Request::instance()->param('openid');
$play_res = db('表名')->insert($play_data);
if($play_res)
{
return json(['status'=>0,'msg'=>"注册成功"]);
}else{
return json(['status'=>1,'msg'=>"注册失败"]);
}
}
public function send_cet()
{
$openid="这里填推送用户的openid";
$token=json_decode($this->access_token()->getContent(),true);
$template_id=""; //模板id
$page=""; //点击模板信息后进入的页面 例如 pages/xxx/xxx?id={$id}&name={$name}
$res=db('formid_pool')->where('openid',$openid)->find();
$data_temp=array("touser"=>$openid,"template_id"=>$template_id,"form_id"=>$res['form_id'],"page"=>$page,
"data"=>array("keyword1"=>array("value"=>"陈独秀"),"keyword2"=>array("value"=>"12345678910"),
"keyword3"=>array("value"=>"英语四级"),"keyword4"=>array("value"=>"222"),"keyword5"=>array("value"=>"222"),
"keyword6"=>array("value"=>"222"),"keyword7"=>array("value"=>"666")
));
$data_string=json_encode($data_temp);
$url="https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=".$token['access_token'];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
$r=curl_exec($curl);
curl_close($curl);
$status=json_decode($r,true);
if($status['errcode']==0)
{
db('formid_pool')->where('openid',$openid)->where('form_id',$res['form_id'])->delete(); //使用完之后删除
echo "success";
}else{
print_r($status);die;
}
die;
}
这里在网上查了挺多方法的
http://www.51xuediannao.com/xiaochengxu/0cba78ba.html (主要用的是这个骚操作)
https://blog.csdn.net/jensen_yao/article/details/83341054
button::after{
border:none;
}
.aa{
width: 120rpx;
height: 120rpx;
position:fixed;
}
test:function(e){
if (e.detail.formId != 'the formId is a mock one') {
this.setData({
formIdString: e.detail.formId + "," + this.data.formIdString
})
}
console.log(this.data.formIdString)
},
这种方法可用在注册上,但是这样收集的也还不够,你可以在用户有可能点击的地方改写为上面的结构,每点击一次,就向后台发送一起请求,将用户的openid和formid发过去,再构建一个formid池(建一个数据表存着),记录下用户的openid和formid和该formid过期的时间,大概是这样
public function save()
{
$openid=Request::instance()->param('openid');
$formid=Request::instance()->param('formid');
$time=date("Y-m-d H:i:s",strtotime('+7 days'));
if($formid=="the formId is a mock one"||empty($openid))
{
return json(['status'=>0,'msg'=>'no']);
}else{
db('formid_pool')->insert(['openid'=>$openid,'form_id'=>$formid,'time'=>$time]);
return json(['status'=>0,'msg'=>'yes']);
}
}
另外,我当时在改写结构的过程中遇到了个问题,就是安卓机有时候无法获取到formid,苹果却没影响。最后在某个博主的文章找到一点头绪
https://blog.csdn.net/eaglewyy/article/details/80023829
查看了下自己的结构,我在用户有可能点击的地方都改造为上面的结构,但是点击的地方大多数是用navigator标签进行跳转操作,所有有可能navigator打断了小程序bindsubmit事件,直接将原来的navigator标签删掉,并在form中加一个data-fn='页面地址',后台进行跳转
这是原来的
改为
js端
test:function(e)
{
wx.navigateTo({
url: e.currentTarget.dataset.fn,
})
}