1. 程式人生 > >java推送微信模板訊息

java推送微信模板訊息

/**
 * 註冊成功,通知模板訊息實體類
 */
public class TemplateMessage {
    private String touser; //使用者OpenID
    private String template_id; //模板訊息ID
    private String url; //URL置空,在傳送後,點模板訊息進入一個空白頁面(ios),或無法點選(android)。
    private String topcolor; //標題顏色
    private Map<String, TemplateData> templateData; //模板詳細資訊
   //此處省略get/set 方法
}
/**
 * 模板詳細資訊 
 */
public class TemplateData {
    private String value;
    private String color;
    public TemplateData(String value,String color){
        this.value = value;
        this.color = color;
    }
    //此處省略get/set 方法
}
/*
*AccessToken 物件
*/
public class AccessToken  implements Serializable
{
//獲取到的憑證 private String accessToken; //憑證有效時間,單位:秒 private int expiresin; //此處省略get/set 方法 }
/**
 * 微信請求 - 信任管理器
 */
public class MyX509TrustManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    @Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { // return new X509Certificate[0]; return null; } }
/**
 * 微信列舉
 * /
public class WeiXinEnum {    
     // 快取型別     
    public enum CACHE_TYPE {
        CACHE_WX_ACCESS_TOKEN,   //模板訊息access_token
    }    
    // 模板訊息編號
    public enum WX_TEMPLATE_MSG_NUMBER{
        USER_REGISTER_SUCCESS(0,"OPENTM407796225", "註冊成功"),
        ORDER_PAYED_SUCCESS(1, "OPENTM207421553","訂單支付"),
        ORDER_...;
        private int code;
        private String msgNumber;
        private String label;
        WX_TEMPLATE_MSG_NUMBER(int code, String msgNumber,String label){
            this.code = code;
            this.msgNumber = msgNumber;
            this.label = label;
        }
        public int getCode(){
            return code;
        }
        public String getMsgNumber(){
            return msgNumber;
        }
        public String getLabel(){
            return label;
        }
    }
}
import com.alibaba.fastjson.JSONObject;
import com.qyuedai.crm.weixin.vo.MyX509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
public class WX_HttpsUtil {
    private static Logger log = LoggerFactory.getLogger(WX_HttpsUtil.class);
    /**
     * 傳送https請求
     * @param requestUrl 請求地址
     * @param requestMethod 請求方式(GET、POST)
     * @param outputStr 提交的資料
     * @return JSONObject(通過JSONObject.get(key)的方式獲取json物件的屬性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            // 建立SSLContext物件,並使用我們指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 從上述SSLContext物件中得到SSLSocketFactory物件
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 設定請求方式(GET/POST)
            conn.setRequestMethod(requestMethod);
            // 當outputStr不為null時向輸出流寫資料
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意編碼格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            // 從輸入流讀取返回內容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 釋放資源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSONObject.parseObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("連線超時:{}", ce);
        } catch (Exception e) {
            log.error("https請求異常:{}", e);
        }
        return jsonObject;
    }
}
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.qyuedai.common.redis.Redis;
import com.qyuedai.crm.weixin.vo.AccessToken;
import com.qyuedai.crm.weixin.vo.WeiXinEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WX_TokenUtil {
    private static Logger log = LoggerFactory.getLogger(WX_TokenUtil.class);
   /**
     *  獲得微信 AccessToken
     * access_token是公眾號的全域性唯一介面呼叫憑據,公眾號呼叫各介面時都需使用access_token。
     * 開發者需要access_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取
     * 的access_token失效。  
     * (此處我是把token存在Redis裡面了)   
     */
    public static AccessToken getWXToken() {
        AccessToken access_token = Redis.getInstance().get(WeiXinEnum.CACHE_TYPE.CACHE_WX_ACCESS_TOKEN.name());
        if(access_token == null || access_token.getAccessToken().equals("")){
            String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId+"&secret="+ appSecret;
            JSONObject jsonObject = WX_HttpsUtil.httpsRequest(tokenUrl, "GET", null);
            if (null != jsonObject) {
                try {
                    access_token = new AccessToken();
                    access_token.setAccessToken(jsonObject.getString("access_token"));
                    access_token.setExpiresin(jsonObject.getInteger("expires_in"));
                } catch (JSONException e) {
                    access_token = null;
                    // 獲取token失敗
                    log.error("獲取token失敗 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
                }
            }
            Redis.getInstance().set(WeiXinEnum.CACHE_TYPE.CACHE_WX_ACCESS_TOKEN.name(), access_token,7100);
        }
        return access_token;
    }
}
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WX_UserUtil {
    private static Logger log = LoggerFactory.getLogger(WX_UserUtil.class);
    /**
     * 根據微信openId 獲取使用者是否訂閱
     * @param openId 微信openId
     * @return 是否訂閱該公眾號標識
     */
    public static Integer subscribeState(String openId){
        String tmpurl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+WX_TokenUtil.getWXToken().getAccessToken() +"&openid="+openId;
        JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "GET",null);
        JSONObject resultJson = new JSONObject(result);
        log.error("獲取使用者是否訂閱 errcode:{} errmsg:{}", resultJson.getInteger("errcode"), resultJson.getString("errmsg"));
        String errmsg = (String) resultJson.get("errmsg");
        if(errmsg==null){
            //使用者是否訂閱該公眾號標識(0代表此使用者沒有關注該公眾號 1表示關注了該公眾號)。
            Integer subscribe = (Integer) resultJson.get("subscribe");
            return subscribe;
        }
        return -1;
    }

}
import com.alibaba.fastjson.JSONObject;
import com.qyuedai.crm.weixin.vo.TemplateData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
public class WX_TemplateMsgUtil {
    private static Logger log = LoggerFactory.getLogger(WX_TemplateMsgUtil.class);

    /**
     * 封裝模板詳細資訊
     * @return
     */
    public static JSONObject packJsonmsg(Map<String, TemplateData> param) {
        JSONObject json = new JSONObject();
        for (Map.Entry<String,TemplateData> entry : param.entrySet()) {
            JSONObject keyJson = new JSONObject();
            TemplateData  dta=  entry.getValue();
            keyJson.put("value",dta.getValue());
            keyJson.put("color", dta.getColor());
            json.put(entry.getKey(), keyJson);
        }
        return json;
    }

    /**
     * 根據模板的編號 新增並獲取模板ID
     * @param templateSerialNumber 模板庫中模板的 "編號"
     * @return 模板ID
     */
    public static String getWXTemplateMsgId(String templateSerialNumber){
        String tmpurl = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token="+ WX_TokenUtil.getWXToken().getAccessToken();
        JSONObject json = new JSONObject();
        json.put("template_id_short", templateSerialNumber);
        JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "POST", json.toString());
        JSONObject resultJson = new JSONObject(result);
        String errmsg = (String) resultJson.get("errmsg");
        log.info("獲取模板編號返回資訊:" + errmsg);
        if(!"ok".equals(errmsg)){
            return "error";
        }
        String templateId = (String) resultJson.get("template_id");
        return templateId;
    }

    /**
     * 根據模板ID 刪除模板訊息
     * @param templateId 模板ID
     * @return
     */
    public static String deleteWXTemplateMsgById(String templateId){
        String tmpurl = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token="+ WX_TokenUtil.getWXToken().getAccessToken();
        JSONObject json = new JSONObject();
        json.put("template_id", templateId);
        try{
            JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "POST", json.toString());
            JSONObject resultJson = new JSONObject(result);
            log.info("刪除"+templateId+"模板訊息,返回CODE:"+ resultJson.get("errcode"));
            String errmsg = (String) resultJson.get("errmsg");
            if(!"ok".equals(errmsg)){
                return "error";
            }
        }catch(Exception e){
         e.printStackTrace();
        }
        return "success";
    }


    /**
     * 傳送微信訊息(模板訊息)
     * @param touser 使用者 OpenID
     * @param templatId 模板訊息ID
     * @param clickurl URL置空,則在傳送後,點選模板訊息會進入一個空白頁面(ios),或無法點選(android)。
     * @param topcolor 標題顏色
     * @param data 詳細內容
     * @return
     */
    public static String sendWechatMsgToUser(String touser, String templatId, String clickurl, String topcolor, JSONObject data) {
        String tmpurl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+ WX_TokenUtil.getWXToken().getAccessToken();
        JSONObject json = new JSONObject();
        json.put("touser", touser);
        json.put("template_id", templatId);
        json.put("url", clickurl);
        json.put("topcolor", topcolor);
        json.put("data", data);
        try{
            JSONObject result = WX_HttpsUtil.httpsRequest(tmpurl, "POST", json.toString());
            JSONObject resultJson = new JSONObject(result);
            log.info("傳送微信訊息返回資訊:" + resultJson.get("errcode"));
            String errmsg = (String) resultJson.get("errmsg");
            if(!"ok".equals(errmsg)){  //如果為errmsg為ok,則代表傳送成功,公眾號推送資訊給使用者了。
                return "error";
            }
         }catch(Exception e){
            e.printStackTrace();
            return "error";
        }finally {
            if(templatId!=null) {
                //刪除新增的 微信模板
                deleteWXTemplateMsgById(templatId);
            }
        }
        return "success";
   }
}
import com.qyuedai.crm.weixin.util.WX_TemplateMsgUtil;
import com.qyuedai.crm.weixin.util.WX_UserUtil;
import com.qyuedai.crm.weixin.vo.TemplateData;
import com.qyuedai.crm.weixin.vo.WeiXinEnum;
import java.util.HashMap;
import java.util.Map;
import static com.qyuedai.crm.weixin.util.WX_TemplateMsgUtil.getWXTemplateMsgId;
import static com.qyuedai.crm.weixin.util.WX_TemplateMsgUtil.packJsonmsg;
public class Test {

    public static void main(String[] args) {
        //新增使用者成功 - 推送微信訊息
        senMsg("oUBBZwTa7qxb0vP98X8WhAazdvUE");
    }
   static void senMsg(String openId){
        //使用者是否訂閱該公眾號標識 (0代表此使用者沒有關注該公眾號 1表示關注了該公眾號)
        Integer  state= WX_UserUtil.subscribeState(openId);
        // 綁定了微信並且關注了服務號的使用者 , 註冊成功-推送註冊簡訊
        if(state==1){
            Map<String,TemplateData> param = new HashMap<>();
            param.put("first",new TemplateData("恭喜您註冊成功!","#696969"));
            param.put("keyword1",new TemplateData("15618551533","#696969"));
            param.put("keyword2",new TemplateData("2017年05月06日","#696969"));
            param.put("remark",new TemplateData("祝投資愉快!","#696969"));
            //註冊的微信-模板Id
            String regTempId =  getWXTemplateMsgId(WeiXinEnum.WX_TEMPLATE_MSG_NUMBER.USER_REGISTER_SUCCESS.getMsgNumber());
            //呼叫傳送微信訊息給使用者的介面
            WX_TemplateMsgUtil.sendWechatMsgToUser(openId,regTempId, "", "#000000", packJsonmsg(param));
        }
    }
}