一、準備工作
1. 註冊微信開放平臺和微信公衆平臺
- 微信開放平臺還需要開發者資質認證
- 微信公衆平臺必須是服務號,需要通過消息模板推送
2. 創建移動應用
3. 綁定微信服務號
必須綁定,通過開放平臺獲取unionid,與公衆號的unionid匹配。
不綁定的話,公衆號獲取不到unionid
二、使用微信登錄獲取unionid
uni.login({
provider: "weixin",
success: function(loginRes) {
var wechatUnionid = loginRes.authResult.unionid;
}
});
三、微信公衆號服務器配置和驗證令牌Token
@RequestMapping("verifyToken")
public byte[] verifyToken(String signature, String timestamp, String nonce, String echostr) throws UnsupportedEncodingException {
List<String> params= new ArrayList<>();
params.add(nonce);
params.add(timestamp);
// 在微信公衆號平臺上設置的Token
params.add("token");
if (echostr!=null){
// 確定是否是微信的請求,驗證是否正確簽名,返回echostr
if(wechatUtil.verifySignature(params,signature)){
return URLEncoder.encode(echostr,"UTF-8").getBytes();
} else {
return null;
}
} else {
return null;
}
}
public boolean verifySignature(List<String> params,String signature){
// 字典序排序
Collections.sort(params);
// SHA1加密
String paramsStr = StringUtils.join(params.toArray(),"");
String checksignature = DigestUtils.shaHex(paramsStr);
return checksignature.equals(signature);
}
四、獲取並緩存access_token
https請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
參數 | 是否必須 | 說明 |
---|---|---|
grant_type | 是 | 獲取access_token直接填寫client_credential |
appid | 是 | 開發者ID(AppID) |
secret | 是 | 開發者密碼(AppSecret) |
五、獲取公衆號用戶信息openid和unionid
- 獲取openid
https請求方式: GET
https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
參數 | 是否必須 | 說明 |
---|---|---|
access_token | 是 | 調用接口憑證 |
next_openid | 是 | 第一個拉取的OPENID,不填默認從頭開始拉取 |
- 獲取unionid
https請求方式: GET
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
參數 | 是否必須 | 說明 |
---|---|---|
access_token | 是 | 調用接口憑證 |
openid | 是 | 普通用戶的標識,對當前公衆號唯一 |
lang | 否 | 返回國家地區語言版本,zh_CN 簡體,zh_TW 繁體,en 英語 |
- 通過開放平臺綁定微信公衆號,公衆號才能獲取到unionid。
六、通過openid推送模板消息
- 在公衆號設置模板消息的模板,可以得到模板id
- 通過開放平臺獲取到的unionid與公衆號的unionid匹配就可以獲取到openid,使用openid推送
https請求方式: GET
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
參數 | 是否必須 | 說明 |
---|---|---|
access_token | 是 | 調用接口憑證 |
- 後端創建實體類
public class TemplateContentEntity {
public String touser; //用戶OpenID
public String template_id; //模板消息ID
public HashMap<String,TemplateDataEntity> data;
@Override
public String toString() {
return "{" +
"touser='" + touser + '\'' +
", template_id='" + template_id + '\'' +
", data=" + data +
'}';
}
}
public class TemplateDataEntity {
public String value;
public String color;
public TemplateDataEntity(String value, String color){
this.value = value;
this.color = color;
}
@Override
public String toString() {
return "{" +
"value='" + value + '\'' +
", color='" + color + '\'' +
'}';
}
}
- 推送代碼
@RequestMapping("sendTemplateMsg")
public JSONObject sendTemplateMsg(String openid,String msg){
// 模板消息實體類
TemplateContentEntity temp = new TemplateContentEntity();
temp.touser=openid;
temp.template_id = wechatTemplateID;
LinkedHashMap<String, TemplateDataEntity> data = new LinkedHashMap<>();
data.put("first",new TemplateDataEntity("消息","#173177"));
data.put("keyword1",new TemplateDataEntity(msg,"#000"));
data.put("keyword2",new TemplateDataEntity(nowTime,"#000"));
data.put("remark",new TemplateDataEntity("如有問題請聯繫管理員","#173177"));
temp.data= data;
// sendMessage使用post傳json格式
return wechatUtil.sendMessage(temp);
}