java 微信小程序-发送模板消息

开发前准备工作

  1. 登录微信公众平台-小程序后台,在模板消息里面设置需要发送的模板,拿到模板id。
    地址: https://mp.weixin.qq.com
    在这里插入图片描述
  2. 找到微信官方文档-小程序开发-下发小程序和公众号统一的服务消息接口。
    地址: https://developers.weixin.qq.com/miniprogram/dev/api-backend/
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190910163537962.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3Jvb2tpZVRh,size_16,color_FFFFFF,t_70
    3.下发小程序和公众号统一的服务消息接口需要接口调用凭证。
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190910164758597.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3Jvb2tpZVRh,size_16,color_FFFFFF,t_70
    4.接口调用凭证需要小程序的appid 和 secret,在小程序后台获取。
    在这里插入图片描述
    代码编写
    调用接口凭证,获取access_token
    注意:access_token 的有效期目前为 2 个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效;
    建议开发者使用中控服务器统一获取和刷新 access_token;
	/**  
	 * 获取access_token
	 * @param appid 凭证  
	 * @param appsecret 密钥  
	 * @return  
	 */    
	public static AccessToken getAccessToken() {    
	    AccessToken accessToken = null;    
	    
	    String requestUrl = WeChatConstants.WECHAT_ACCESS_TOKEN_URL.replace("APPID", WeChatConstants.WECHAT_APPID).replace("APPSECRET", WeChatConstants.WECHAT_APPSECRET);    
	    JSONObject jsonObject = WeChatUtil.httpRequest(requestUrl, "GET", null);  //调用通用的https请求方法  
	    // 如果请求成功    
	    if (null != jsonObject) {    
	        try {    
	            accessToken = new AccessToken();    
	            accessToken.setToken(jsonObject.getString("access_token"));    
	            accessToken.setExpiresIn(jsonObject.getInteger("expires_in"));
	            accessToken.setCreatedate(new Date());
	            weixincache.put("accessToken", accessToken);
	        } catch (JSONException e) {    
	            accessToken = null;    
	            // 获取token失败    
	            log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
	        }    
	    }    
	    return accessToken;    
	}

配置类

public class WeChatConstants {
	
	public static final String WECHAT_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; 
	
	public static final String WECHAT_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

	// 待支付课程提醒
	public static final String  UNPAID_PAY_TEMPLATE_ID = "需要发送的小程序后台模板id";

	// 支付成功课程提醒
	public static final String  PAY_SUCCEED_TEMPLATE_ID = "需要发送的小程序后台模板id";

 public static final String WECHAT_APPID = "小程序appid";

public static final String WECHAT_APPSECRET = "小程序secret密钥";

}

公众平台通用接口工具类

public class WeChatUtil {    
    private static Logger log = LoggerFactory.getLogger(WeChatUtil.class);
    
    /**  
     * 发起https请求并获取结果  
     *   
     * @param requestUrl 请求地址  
     * @param requestMethod 请求方式(GET、POST)  
     * @param outputStr 提交的数据  
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)  
     */    
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {    
        JSONObject jsonObject = null;    
        StringBuffer buffer = new StringBuffer();    
        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 httpUrlConn = (HttpsURLConnection) url.openConnection();    
            httpUrlConn.setSSLSocketFactory(ssf);    
    
            httpUrlConn.setDoOutput(true);    
            httpUrlConn.setDoInput(true);    
            httpUrlConn.setUseCaches(false);    
            // 设置请求方式(GET/POST)    
            httpUrlConn.setRequestMethod(requestMethod);    
    
            if ("GET".equalsIgnoreCase(requestMethod))    
                httpUrlConn.connect();    
    
            // 当有数据需要提交时    
            if (null != outputStr) {    
                OutputStream outputStream = httpUrlConn.getOutputStream();    
                // 注意编码格式,防止中文乱码    
                outputStream.write(outputStr.getBytes("UTF-8"));    
                outputStream.close();    
            }    
    
            // 将返回的输入流转换成字符串    
            InputStream inputStream = httpUrlConn.getInputStream();    
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");    
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);    
    
            String str = null;    
            while ((str = bufferedReader.readLine()) != null) {    
                buffer.append(str);    
            }    
            bufferedReader.close();    
            inputStreamReader.close();    
            // 释放资源    
            inputStream.close();    
            inputStream = null;    
            httpUrlConn.disconnect();    
            jsonObject = JSONObject.parseObject(buffer.toString());
        } catch (ConnectException ce) {    
            log.error("Weixin server connection timed out.");    
        } catch (Exception e) {    
            log.error("https request error:{}", e);    
        }    
        return jsonObject;    
    }    
    
} 

发送模板消息接口

	/**
	 * @param orderId 订单id
	 * @param openid 用户openid
	 * @param formId 表单ID
	 * @param templateId 模板ID
	 * @param keywords {与模板字段一一对应}
	 * @return
	 */
	public static Map<String,String> pushOneUser(Long orderId, String openid, String formId,String templateId,String[] keywords) {
		Map<String,String> map = new HashMap<>();
		String msg = null;
		try {
			//如果access_token为空则从新获取
			String access_token = RedisUtil.getString("access_token");
			if (access_token == null) {
				AccessToken accessToken = getAccessToken();
				access_token = accessToken.getToken();
				RedisUtil.setString("access_token", access_token, (60 * 120));
			}
			if (RedisUtil.exists(access_token)){
				AccessToken accessToken = getAccessToken();
				access_token = accessToken.getToken();
				RedisUtil.setString("access_token", access_token, (60 * 120));
			}
			String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send" +
					"?access_token=" + access_token;

			//拼接推送的模版
			WxMssVo wxMssVo = new WxMssVo();
			wxMssVo.setTouser(openid);//用户openid
			wxMssVo.setForm_id(formId);//formId
 			wxMssVo.setTemplate_id(templateId);//模版id
			wxMssVo.setPage(wxMssVo.getPage()+"?orderId="+orderId);
			Map<String, TemplateDataVo> m = new HashMap<>();

			//封装数据
			if(keywords.length>0){
				for(int i=1;i<=keywords.length;i++){
					TemplateDataVo keyword = new TemplateDataVo();
					keyword.setValue(keywords[i-1]);
					m.put("keyword"+i, keyword);
				}
				wxMssVo.setData(m);
			}else{
				log.error("keywords长度为空");
				return null;
			}
			log.info("发送模板消息请求参数"+JSONObject.toJSONString(JSONObject.toJSONString(wxMssVo)));
			JSONObject jsonObject = WeChatUtil.httpRequest(url, "POST", JSONObject.toJSONString(wxMssVo));  //调用通用的https请求方法
			log.info("发送模板消息返回"+JSONObject.toJSONString(jsonObject));
			map.put("content",JSONObject.toJSONString(m));
			map.put("returnMsg",JSONObject.toJSONString(JSONObject.toJSONString(jsonObject)));
			map.put("errcode",jsonObject.getString("errcode"));
			// 如果请求成功
			if (null != jsonObject) {
				 msg =  jsonObject.getString("errmsg");
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return map;
	}

封装模板类

public class WxMssVo {
	private String touser;//用户openid
	private String template_id;//模版id
	private String page = "pages/MyOrder/MyOrderDetail";// 订单详情页
	private String form_id;//收集到的用户formid
	//    private String emphasis_keyword = "keyword1.DATA";//放大那个推送字段
	private Map<String, TemplateDataVo> data;//推送文字

	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 String getForm_id() {
		return form_id;
	}

	public void setForm_id(String form_id) {
		this.form_id = form_id;
	}

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

	public void setData(Map<String, TemplateDataVo> data) {
		this.data = data;
	}
}
public class TemplateDataVo {
	//字段值例如:keyword1:content,keyword2:课程名称,keyword3:创建时间,keyword4:订单金额
	private String value;//依次排下去
//    private String color;//字段颜色(微信官方已废弃,设置没有效果)


	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}

测试发送模板消息
关于获取formid
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/template-message.html

    /**
     * @param orderEntity
     * @param openid 用户openid,可以是小程序的openid,也可以是mp_template_msg.appid对应的公众号的openid
     * @param formId 小程序模板消息formid
     */
    public  void pushOneUser(OrderEntity orderEntity,String openid,String formId){
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String template = WeChatConstants.PAY_SUCCEED_TEMPLATE_ID; // 需要发送的模板id
            String price = "12.30";  // 订单金额
            Date orderDate = orderEntity.getCreateTime(); // 创建时间
            String dateString = formatter.format(orderDate);
            String courseName = "测试发送模板消息"; // 课程名称
            String content = "您的课程已支付,我们会在1-3个工作日内联系您,安排开课~";
            String[] keywords = {content, courseName, dateString, price};
            WeChat.pushOneUser(orderEntity.getId(),openid,formId,template,keywords);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

官方返回值
在这里插入图片描述
程序调用成功返回值
在这里插入图片描述
程序调用失败返回值
在这里插入图片描述
发送模板消息记录表
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值