微信消息推送開發


隨着微信使用越來越廣泛,因其也產生了許多二次開發的小功能,今天要介紹的就是微信服務號的中的消息模板推送。

 

添加模板消息方式如上面,如果不滿足可以添加自定義的,但是需要審核,周期為7到15天。消息模板內容一般如下:

我們需要用到的是模板Id,顯示內容,first、keyword1、keyword2、keyword3、keyword4、remark我們傳過來的值。

如果想要使用模板推送消息,我們首先得獲取到access_token憑證,該憑證有效期為2個小時。我們可以獲取的時候存起來,這里我是使用redis存儲。

具體獲取方式如下代碼:

  public static AccessToken getAccessToken() throws Exception {

        //獲取憑證地址
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
        CloseableHttpClient httpCilent = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(accessTokenUrl);
        try {
            CloseableHttpResponse response = httpCilent.execute(httpGet);
            System.out.println("code===="+response.getStatusLine().getStatusCode());
            if (response.getStatusLine().getStatusCode() == 200) {
                String entity = EntityUtils.toString(response.getEntity());
                System.out.println("entity===="+entity);
                AccessToken accessToken = JSONObject.parseObject(entity, AccessToken.class);
              
                return accessToken;
            }else {
                logger.error("獲取access_token發送get請求獲取到的狀態為:"+response.getStatusLine().getStatusCode());
                return null;
            }
        } catch (IOException e) {
            logger.error("獲取access_token出錯",e);
            throw new Exception("獲取access_token出錯",e);
        }finally {
            try {
                httpCilent.close();
            } catch (IOException e) {
                logger.error("關閉請求連接失敗",e);
                throw new Exception("關閉請求連接失敗",e);
            }
        }
    }
View Code
public class AccessToken {

    // 獲取到的憑證
    private String access_token;

    // 憑證有效時間,單位:秒
    private  Integer expires_in;

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

    public Integer getExpires_in() {
        return expires_in;
    }

    public void setExpires_in(Integer expires_in) {
        this.expires_in = expires_in;
    }
}
View Code

這里需要注意的是,微信獲取access_token的接口有多種,這里我們使用的是這個接口:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET

使用的get請求,其會返回一個json字符串:{"access_token":"xxx","expires_in":7200}的結果。其中還有一步很重要,就是需要設置ip白名單,如果不設置獲取不到access_token。

獲取到access_token后,還需要填充內容,具體的封裝方式如下:

public class WechatTemplateMsg {

    //發送人的openid
    private String touser;
    //消息模板Id
    private String template_id;

    //模板跳轉鏈接
    private String url;
    //data數據
    private  TreeMap<String, TreeMap<String, String>> data;

    //設置參數值,color可為空
    public static TreeMap<String,String> init(String value,String color){
        TreeMap<String, String> params = new TreeMap<String, String>();
        params.put("value", value);
        params.put("color", color);
        return params;
    }

    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 getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public TreeMap<String, TreeMap<String, String>> getData() {
        return data;
    }

    public void setData(TreeMap<String, TreeMap<String, String>> data) {
        this.data = data;
    }
}
View Code
public String leaderSendTemplate(String openid,String repairDate,String repairInfoCount,String resultCount) {

        //封裝信息
        TreeMap<String, TreeMap<String, String>> params = new TreeMap<>();
        params.put("first",WechatTemplateMsg.init("","#000000"));
        //報表時間
        params.put("keyword1",WechatTemplateMsg.init(repairDate,"#000000"));
        //報修數量
        params.put("keyword2",WechatTemplateMsg.init(repairInfoCount,"#000000"));
        //維修完成數量
        params.put("keyword3",WechatTemplateMsg.init(resultCount,"#000000"));
        //內容
        params.put("remark",WechatTemplateMsg.init("","#173177"));
        ResourceBundle resource = ResourceBundle.getBundle("properties/pay");
        String template_id =resource.getString("Leader_ID");//模板Id
        String leaderUrl =resource.getString("leaderUrl");//轉跳地址
        WechatTemplateMsg templateMsg = new WechatTemplateMsg();
        templateMsg.setTouser(openid);//報修人OpenId
        templateMsg.setTemplate_id(template_id);
        templateMsg.setUrl(leaderUrl);//跳轉地址
        templateMsg.setData(params);//參數
        return JsonUtil.toJsonString(templateMsg);
    }
View Code

這樣我們就可以獲取到String的date了,其中date的數據格式如下:

{"touser":"openid","template_id":"模板id","url":"需要轉跳地址","data":{"first":{"color":"#000000","value":"您好,存在新 的待維修單,請查看!"},"keyword1":{"color":"#000000","value":"一體機1"},"keyword2":{"color":"#000000","value":"2019-01-28 10:00"},"keyword3":{"color":"#000000","value":"地址"},"keyword4":{"color":"#000000","value":"無"},"remark":{"color":"#173177","value":"感謝您的使用"}}}

我們就可以使用access_token或date發送消息了,具體如下:

public static String sendDate(String access_token,String data) throws Exception {
   
        String sendUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESSTOKEN";
                     
        sendUrl = sendUrl.replace("ACCESSTOKEN",access_token);
        logger.info("sendUrl"+sendUrl);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(sendUrl);
        try {
            //轉換參數
            StringEntity dateSet = new StringEntity(data, ContentType.APPLICATION_JSON);
            // 設置post求情參數
            httpPost.setEntity(dateSet);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                //發送成功
                String entity = EntityUtils.toString(httpResponse.getEntity());
                logger.info("返回結果:"+entity);
                //返回結果
                ResultTemplateDate resultTemplateDate = JSONObject.parseObject(entity, ResultTemplateDate.class);
                return resultTemplateDate.getErrcode();
            }else {
                logger.error("StatusCode:"+httpResponse.getStatusLine().getStatusCode());
            }

        } catch (IOException e) {
            logger.info("發送消息失敗",e);
            throw new Exception("發送消息失敗",e);
        }finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                logger.error("關閉HttpClients異常");
                throw new Exception("關閉HttpClients異常",e);
            }
        }
        return "-1";
    }
View Code

這樣就發送成功了,返回成的結果為:{"errcode":0,"errmsg":"ok","msgid":655130036042940416}。

以下為一些工具類:

public class ResultTemplateDate {

    //返回消息代碼:0:成功
    /*
     * 常見錯誤狀態碼: 40001:不合法的調用憑證 、40003:不合法的OpenID
     *                  40030:不合法的refresh_token、
     *                  40036:不合法的template_id長度、40037:不合法的template_id
     *                  41009:    缺失openid參數
    **/
    private String  errcode;
    //返回信息:“ok”:成功
    private String errmsg;

    public String getErrcode() {
        return errcode;
    }

    public void setErrcode(String errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }
}
View Code
// 將對象轉成String
public static String toJsonString(Object obj) {
        if (obj == null) {
            return "{}";
        }
        if (obj instanceof String) {
            if (StringUtils.isEmpty(obj.toString())) {
                return "{}";
            }
        }
        String json = "";
        try {
            if (gson != null) {
                json = gson.toJson(obj);
            }
        } catch (Exception e) {
            return "{}";
        }
        return json;
    }
View Code

在這過程中也遇到一些問題,其中最難的是遇到{"errcode":48001,"errmsg":"api unauthorized hint: [L5EA1a05308051!]"}這個錯誤,一開始以為沒有微信沒有認證,但去看了以及認證了,也有該接口權限,一直再找問題出現在哪。最后發現是調用錯接口了。

 

這是第一次開發這個功能,如果不正確的地方,請指正,謝謝!

 


免責聲明!

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



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