微信小程序結合微信公眾號進行消息發送


微信小程序結合微信公眾號進行消息發送

由於小程序的模板消息已經廢棄了,官方讓使用訂閱消息功能。而訂閱消息的使用限制比較大,用戶必須得訂閱、需要獲取用戶同意接收消息的權限、用戶必須得和小程序有交互的時候才能發送且只能發送一次。而我們的需求有可能是不限時間不限“次數”的發送消息。那么就可以使用官方提供的統一服務消息

統一服務消息

該功能還是有一點的使用限制的。

第一:小程序和公眾號的主體必須是同一個。
第二:用戶必須關注公眾號。
第三:我們得有消息模板,小程序消息模板和公眾號消息模板都可以。

結合文檔,使用Java對發送消息的功能進行簡單的封裝

第一:使用httpClient請求地址,獲取access_token

GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
根據官方接口的返回值,我們封裝返回值對象
@Data
public class AccessToken {
    /** 接口調用憑證 */
    private String access_token;
    /** 過期時間 */
    private Long expires_in;
    /** 錯誤信息代碼 */
    private String errcode;
    /** 錯誤信息 */
    private String errmsg;
}
使用httpClient發送請求
AccessToken accessToken = new AccessToken();

String url = WxMessageConstant.GET_XCX_ACCESS_TOKEN_URL + "&appid=" + WxMessageConstant.APP_ID + "&secret=" + WxMessageConstant.SECRET;
String result = HttpClientUtils.doGet(url);

accessToken = JSON.parseObject(result, AccessToken.class);

注意:獲得的token結果可以放在redis里面,設置上過期時間,防止應用重復獲取access_token!

第二:構造請求

構造請求url

根據官方提供的接口再加上我們的獲取的access_token進行構造

POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
構造請求參數

根據官方文檔,我們一步一步來構造請求參數對象,我們用的是公眾號的消息模板,所以這里沒有weapp_template_msg參數

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReqSendMessageData {
    /**
     * 消息接收者
     */
    private String touser;
    /**
     * 公眾號模板消息信息
     */
    private MpTemplateMsg mp_template_msg;
}

構造mp_template_msg對象

@Data
@NoArgsConstructor
@AllArgsConstructor
public class MpTemplateMsg {
    /** 公眾號openId */
    private String appid;
    /** 公眾號模板id */
    private String template_id;
    /** 跳轉到公眾號的地址,文檔上寫的必填,我沒填,沒有報錯 */
    private String url;
    /** 公眾號綁定的小程序信息 */
    private Miniprogram miniprogram;
    /** 數據 */
    private Map<String,Object> data;
}

構造小程序信息

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Miniprogram {
    /** 小程序appid */
    private String appid;
    /** 要跳轉到小程序的頁面 */
    private String page;
}

貼出httpClient發送post請求的方式

public static String postSendJsonParam(String url, String param) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = null;
        // 請求方式
        HttpPost httpPost = null;
        // 響應
        CloseableHttpResponse httpResponse = null;
        httpPost = new HttpPost(url);
        httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
        httpPost.setHeader("User-Agent", REQUEST_HEADER_USER_AGENT);
        httpPost.addHeader("content-type", "application/json;charset=utf-8");
        httpPost.addHeader("accept", "application/json");
        httpPost.setEntity(new StringEntity(param, "UTF-8"));

        try {
            
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return result;
    }

構造返回值對象,我們根據錯誤代碼進行擴展操作

@Data
public class ResSendMessageDTO {
    /** 錯誤代碼 */
    private String errcode;
    /** 錯誤信息 */
    private String errmsg;
}

最后我們可以把這些封裝成一個service交給spring管理。

public interface MessageService {
    /**
     * @author: taoym
     * @date: 2020/7/2 9:08
     * @desc: 推送消息
     */
    ResSendMessageDTO sendMessage(ReqSendMessageData data);
}

具體實現不展示了。

封裝消息發送者

@Component
public class MessageSender {

    @Autowired
    private MessageService messageService;

    /**
     * @param first      消息標題
     * @param keywordMap 消息內容
     * @param page       要跳轉到小程序的頁面
     * @param templateId 模板消息編號
     * @param touser     消息接收者openId
     * @author: taoym
     * @date: 2020/9/28 11:25
     * @desc: 消息發送者
     */
    public ResSendMessageDTO sendMessage(String first, Map<String, Keyword> keywordMap, String touser, String page, String templateId) {

        // 消息模板上的數據
        Map<String, Object> messageData = Maps.newHashMap();
        // first,可以理解為 標題
        messageData.put("first", new First(first));
        // keywordMap 可以理解為內容
        messageData.putAll(keywordMap);

        ReqSendMessageData reqSendMessageData = new ReqSendMessageData();
        reqSendMessageData.setTouser(PasswordUtils.decrypt(touser));
        MpTemplateMsg mpTemplateMsg = new MpTemplateMsg();
        Miniprogram miniprogram = new Miniprogram();
        miniprogram.setPage(page);
        mpTemplateMsg.setMiniprogram(miniprogram);
        mpTemplateMsg.setData(messageData);
        mpTemplateMsg.setTemplate_id(templateId);
        reqSendMessageData.setMp_template_msg(mpTemplateMsg);
        ResSendMessageDTO resSendMessageDTO = messageService.sendMessage(reqSendMessageData);
        // 0為成功的標志
        if (!resSendMessageDTO.getErrcode().equals("0")) {
            throw new ExceptionCore(resSendMessageDTO.getErrcode(), resSendMessageDTO.getErrmsg());
        }
        return resSendMessageDTO;
    }
}

最后我們只需要根據模板消息的內容構造合理的參數,然后調用該方法即可發送消息。


免責聲明!

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



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