微信小程序消息推送需要用戶觸發動作才能發送消息,比如用戶提交訂單、支付成功。一次只能發一條。也就是說只有用戶點了小程序,操作了form表單提交然後生成一個formid ,纔可以通過這條formid可以推送一條模板消息 。也就是用戶不點你小程序按鈕,就不會推送。(微信真的是神坑。。。)
微信小程序消息推送分兩種,一種直接從小程序的前端頁面發起請求推送,另外一種在後臺發起請求進行消息推送
一、微信端發起請求
首先,登錄微信小程序後臺添加或創建消息模板拿到模板id,這個操作就不多說了,
1.獲取access_token
access_token是接口調用的憑證,目前有效期爲兩個小時,需要定時刷新,重複獲取將導致上次獲取的access_token失效。
獲取access_token的接口地址:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
發送模板的消息接口地址:
https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN
小程序wxml頁面代碼:
<form report-submit bindsubmit='formaction'>
<button form-type="submit">發送模板消息</button>
</form>
表單提交觸發事件
formaction: function (e) {
var formId = e.detail.formId;//獲取formid
var l = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=' + this.data.token;
var d = {
"keyword1": {
"value": "00273",
"color": "#4a4a4a"
},
"keyword2": {
"value": "紅火早餐店",
"color": "#9b9b9b"
},
"keyword3": {
"value": "5元",
"color": "#9b9b9b"
},
"keyword4": {
"value": "包子、豆漿",
"color": "#9b9b9b"
},
"keyword5": {
"value": "5元",
"color": "#9b9b9b"
},
"keyword6": {
"value": "2019年11月18日 12:30",
"color": "#9b9b9b"
}
};
console.log(d)
wx.request({
url: l,
//注意不要用value代替data
data: {
touser: '',//用戶的openid
template_id: '',//申請的模板消息id,
page: '/pages/test/test',
form_id: formId ,
data: d,
color: '#ccc',
emphasis_keyword: 'keyword1.DATA'
},
method: 'POST',
success: function (res) {
console.log("發送成功");
console.log(res);
},
fail: function (err) {
// fail
console.log("push err")
console.log(err);
}
});
},
二、後臺發起請求(這裏我用的java寫的)
1、懶得解釋,直接貼後臺代碼,大部分都有註釋(這裏有些代碼是借用別人的博客總結過來的,具體地址做的早了也忘了,不好意思)
/*
* 小程序推送所需數據
* */
public class WxMssVo {
private String touser;//用戶openid
private String template_id;//模版id
private String page = "pages/index/index";//默認跳到小程序首頁
private String form_id;//收集到的用戶formid
// private String emphasis_keyword = "keyword1.DATA";//放大那個推送字段
private Map<String, TemplateDataVo> data;//推送文字
public String getTouser() {
return touser;
}
public void setTouser(String touser) {
this.touser = touser;
}
public String getTemplate_id() {
return template_id;
}
public void setTemplate_id(String template_id) {
this.template_id = template_id;
}
public String getForm_id() {
return form_id;
}
public void setForm_id(String form_id) {
this.form_id = form_id;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public Map<String, TemplateDataVo> getData() {
return data;
}
public void setData(Map<String, TemplateDataVo> data) {
this.data = data;
}
}
/*
* 設置推送的文字和顏色
* */
public class TemplateDataVo {
//字段值例如:keyword1:訂單類型,keyword2:下單金額,keyword3:配送地址,keyword4:取件地址,keyword5備註
private String value;//依次排下去:需要推送的內容
// private String color;//字段顏色(微信官方已廢棄,設置沒有效果)
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.cqe.service;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSONObject;
import com.cqe.entity.TemplateDataVo;
import com.cqe.entity.WxMssVo;
@Service
public class WeChatService {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
/**
*
* @param access_token app的token
* @param openid 用戶openid
* @param formId 表單ID
* @param templateId 模板ID
* @param keywords {與模板字段一一對應}
* @return
*/
public String pushOneUser(String appid,String appsecret,String openid, String formId,String templateId,String[] keywords) {
//如果access_token爲空則從新獲取
String access_token = getAccess_token(appid,appsecret);
String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send" +
"?access_token=" + access_token;
//拼接推送的模版
WxMssVo wxMssVo = new WxMssVo();
wxMssVo.setTouser(openid);//用戶openid
wxMssVo.setForm_id(formId);//formId
wxMssVo.setTemplate_id(templateId);//模版id
Map<String, TemplateDataVo> m = new HashMap<String, TemplateDataVo>();
//封裝數據
if(keywords.length>0){
for(int i=1;i<=keywords.length;i++){
TemplateDataVo keyword = new TemplateDataVo();
keyword.setValue(keywords[i-1]);
m.put("keyword"+i, keyword);
}
wxMssVo.setData(m);
}else{
System.out.println("keywords長度爲空");
return null;
}
if(restTemplate==null){
restTemplate = new RestTemplate();
}
ResponseEntity<String> responseEntity =
restTemplate.postForEntity(url, wxMssVo, String.class);
System.out.println("小程序推送結果={}"+ responseEntity.getBody());
return responseEntity.getBody();
}
/*
* 獲取access_token
* appid和appsecret到小程序後臺獲取,當然也可以讓小程序開發人員給你傳過來
* */
public String getAccess_token(String appid,String appsecret) {
//獲取access_token
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
"&appid=" + appid + "&secret=" + appsecret;
if(restTemplate==null){
restTemplate = new RestTemplate();
}
String json = restTemplate.getForObject(url, String.class);
JSONObject myJson = JSONObject.parseObject(json);
return myJson.get("access_token").toString();
}
public static void main(String[] args) {
String appid = "";
String appsecret = "";
System.out.println(new WeChatService().getAccess_token(appid,appsecret));
WeChatService weChatUtil = new WeChatService();
String values[] ={"Jack方","2019-5-8 10:10:10","xxx有限公司","JAVA開發","xx區xx廣場xx號","請帶好入職材料"};
weChatUtil.pushOneUser(appid,appsecret,"openid","formid","模板id",values);//執行這部分代碼會推送
}
}
以上兩種方法親測可用,由於我用的模板是項目中的和我測試用的推送信息不符,所以就不上圖了,但是兩種方法都是測試通過的