小程序---訂閱消息


微信小程序訂閱消息官方文檔地址:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html

小程序用訂閱消息替換了模板推送,今天我們就共同學習如何在Java后台編寫小程序訂閱消息推送的知識。

發送訂閱消息三步走

  1.拿到用戶的openid

  2.獲取access_token

  3.調用小程序消息推送的接口

一,獲取用戶的openid(用戶唯一標識)

openid是由前端傳到后端的,我們只需要接收即可

二,獲取access_token

官方介紹:access_token是小程序全局唯一后台接口調用憑據,調用絕大多數后台接口時都需使用。開發者可以通過 getAccessToken接口獲取並進行妥善保存。為了access_token 的安全性,后端 API 不能直接在小程序內通過 wx.request 調用,即api.weixin.qq.com 不能被配置為服務器域名。開發者應在后端服務器使用getAccessToken獲取 access_token,並調用相關 API;

 其實通俗的講,access_token就是小程序官方給我們提供的一個憑證,你要調用小程序官方的接口,就必須先拿到access_token。所以下面先講下如果獲取access_token

grant_type是一個固定的值,只有appid和secret是需要我們填入的,這兩個值在我們的小程序后台就可以拿到。

注意點: access_token 的存儲與更新

1.access_token的存儲至少要保留 512 個字符空間

2.access_token的有效期目前為 2 個小時,需定時刷新,重復獲取將導致上次獲取的 access_token失效 

3.建議開發者使用中控服務器統一獲取和刷新 access_token ,其他業務邏輯服務器所使用的access_token 均來自於該中控服務器,不應該各自去刷新,否則容易造成沖突,導致 access_token 覆蓋而影響業務

4.access_token 的有效期通過返回的 expires_in 來傳達,目前是7200秒之內的值,中控服務器需要根據這個有效時間提前去刷新。在刷新過程中,中控服務器可對外繼續輸出的老access_token ,此時公眾平台后台會保證在5分鍾內,新老 access_token 都可用,這保證了第三方業務的平滑過渡

5.access_token 的有效時間可能會在未來有調整,所以中控服務器不僅需要內部定時主動刷新,還需要提供被動刷新access_token 的接口,這樣便於業務服務器在API調用獲知 access_token 已超時的情況下,可以觸發 access_token 的刷新流程

所以要在獲取到access_token的時候,把access_token存到數據庫,或者存到本地緩存,並且還要記錄當前時間,后面再用的時候先判斷這個access_token有沒有超過2個小時,如果超過2個小時的話,就要重新獲取了。

三,發送消息到小程序

我們通過上面第二步,成功的獲取到了access_token。下面就要調用小程序官方為我們提供的發送消息的接口了。先看下官方文檔。

這里需要注意的一點是,我們要給用戶發送消息,就必須引導用戶授權,就是下面這個圖

因為用戶不點擊允許,你是沒有辦法給用戶推送消息的。每一次授權只允許發送一條消息,所以如果你想盡量多的發送消息,就得盡量多的引導用戶授權。

推送的代碼如下圖:

 可以看到,我們這里需要定義用戶的openid,模板id,跳轉路徑,模板消息內容等,參數是否必填參考上圖官方文檔

這些都定義好以后,我們就可以提供一個服務給到Java的其他代碼調用,或者提供一個接口供外界傳入openid,然后給對應的用戶推送消息了

測試:在瀏覽器里調用上面接口,可以看到下圖所示,說明消息推送成功。

推送效果圖

下面我把完整的代碼貼出來給到大家

兩個推送消息相關數據類如下:
1:WxMssVo(用來封裝請求官方接口的參數)

package com.qcl.demo;
import java.util.Map;
/*
 * 小程序推送所需數據
 * */
public class WxMssVo {
    private String touser;//用戶openid
    private String template_id;//訂閱消息模版id
    private String page = "pages/index/index";//默認跳到小程序首頁
    private Map<String, TemplateData> data=new HashMap<String,TemplateData>;//推送文字

    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 getPage() {
        return page;
    }
    public void setPage(String page) {
        this.page = page;
    }
    public Map<String, TemplateData> getData() {
        return data;
    }
    public void setData(Map<String, TemplateData> data) {
        this.data = data;
    }
}

2:TemplateData (用來定義消息的內容)

package com.qcl.demo;

public class TemplateData {
    private String value;
public TemplateData(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }

controller接口

package com.qcl.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 發送小程序訂閱消息
 */
@RestController
public class SendWxMessage {
    /*
     * 發送訂閱消息
     * */
    @GetMapping("/pushOneUser")
    public String pushOneUser() {
        return push("o3DoL0WEdzcJ20AVJg1crP96gbjM");
    }

    public String push(String openid) {
        RestTemplate restTemplate = new RestTemplate();
        //這里簡單起見我們每次都獲取最新的access_token(時間開發中,應該在access_token快過期時再重新獲取)
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + getAccessToken();
        //拼接推送的模版
        WxMssVo wxMssVo = new WxMssVo();
        wxMssVo.setTouser(openid);//用戶的openid(要發送給那個用戶,通常這里應該動態傳進來的)
        wxMssVo.setTemplate_id("CFeSWarQLMPyPjwmiy6AV4eB-IZcipu48V8bFLkBzTU");//訂閱消息模板id
        wxMssVo.setPage("pages/index/index");

        Map<String, TemplateData> m = new HashMap<>(3);
        m.put("thing1", new TemplateData("小程序入門課程"));
        m.put("thing6", new TemplateData("杭州浙江大學"));
        m.put("thing7", new TemplateData("第一章第一節"));
        wxMssVo.setData(m);
        ResponseEntity<String> responseEntity =
                restTemplate.postForEntity(url, wxMssVo, String.class);
        return responseEntity.getBody();
    }

    @GetMapping("/getAccessToken")
    public String getAccessToken() {
        RestTemplate restTemplate = new RestTemplate();
        Map<String, String> params = new HashMap<>();
        params.put("APPID", "wx7c54942dfc87f4d8");  //
        params.put("APPSECRET", "5873a729c365b65ab42bb5fc82d2ed49");  //
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}", String.class, params);
        String body = responseEntity.getBody();
        JSONObject object = JSON.parseObject(body);
        String Access_Token = object.getString("access_token");
        String expires_in = object.getString("expires_in");
        System.out.println("有效時長expires_in:" + expires_in);
        return Access_Token;
    }
}

ok,到這里我們就可以完整的實現Java發送小程序消息的功能了~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM