微信消息發送(小程序,公眾號)


1.場景描述:

         在小程序開發過程中需要發送消息,由於小程序消息(訂閱消息)需要經常點擊訂閱,用戶操作麻煩,所以將小程序與公眾號進行關聯;

優先發送消息到公眾號。

2.Java代碼實現

主要有以下幾個類
WeChatMessageSendUtil //消息發送類
PubMessage //統一消息發送實體
  MpTemplateMsg //公眾號消息模板實體
miniprogram // 跳小程序所需數據,不需跳小程序可不用傳該數據 (注意:路徑前要去掉‘/’ ;如:pages/menu)
STemplateData //公眾號消息模板參數
TemplateModel //訂閱消息模板實體
TemplateData //訂閱消息模板參數 Schedulers //定時器用於維護accessToken SysParam //獲取配置文件參數 WeappTemplateMsg //作廢

 2.1.配置文件(application.properties)

#####################################微信小程序參數  for message #################################################

message.wxapp.appid=微信小程序appid
message.wxapp.appsecret=微信小程序appsecret

  2.2.java Class

import io.swagger.annotations.ApiModelProperty;

/**
 * 跳小程序所需數據,不需跳小程序可不用傳該數據
 */
public class miniprogram {
	@ApiModelProperty(value = "所需跳轉到的小程序appid(該小程序appid必須與發模板消息的公眾號是綁定關聯關系,暫不支持小游戲)", example = "")
	private String appid;
	@ApiModelProperty(value = "所需跳轉到小程序的具體頁面路徑,支持帶參數,(示例index?foo=bar),要求該小程序已發布,暫不支持小游戲", example = "")
	private String page;
	//private String pagepath;

	public miniprogram() {
	}

	public miniprogram(String appid, String page) {
		this.appid = appid;
		this.page = page;
	}
/*public miniprogram(String appid, String pagepath) {
		this.appid = appid;
		this.pagepath = pagepath;
	}*/

	public String getAppid() {
		return appid;
	}

	public void setAppid(String appid) {
		this.appid = appid;
	}

	//public String getPagepath() {
	//	return pagepath;
	//}

	//public void setPagepath(String pagepath) {
	//	this.pagepath = pagepath;
	//}


	public String getPage() {
		return page;
	}

	public void setPage(String page) {
		this.page = page;
	}
}

 

import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import java.util.Map;

@EntityListeners(AuditingEntityListener.class)
public class MpTemplateMsg {
	@ApiModelProperty(value = "服務號", example = "")
	private String appid;
	@ApiModelProperty(value = "消息模板id", example = "")
	private String template_id;
	@ApiModelProperty(value = "模板跳轉鏈接(海外帳號沒有跳轉能力)", example = "")
	private String url="/index";
	@ApiModelProperty(value = "模板參數", example = "")
	Map<String, STemplateData> data;

	@ApiModelProperty(value = "跳小程序所需數據,不需跳小程序可不用傳該數據", example = "")
	private miniprogram miniprogram;

	public String getAppid() {
		return appid;
	}

	public void setAppid(String appid) {
		this.appid = appid;
	}

	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 Map<String, STemplateData> getData() {
		return data;
	}

	public void setData(Map<String, STemplateData> data) {
		this.data = data;
	}

	public miniprogram getMiniprogram() {
		return miniprogram;
	}

	public void setMiniprogram(miniprogram miniprogram) {
		this.miniprogram = miniprogram;
	}
}

 

import com.redlichee.core.entity.BaseEntity;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import javax.persistence.Id;

@EntityListeners(AuditingEntityListener.class)
public class PubMessage extends BaseEntity {
	@Id
	//收件人openid
	private String touser;
	//小程序消息模板
	private TemplateModel weapp_template_msg;
	//服務號消息模板
	private MpTemplateMsg mp_template_msg;

	public PubMessage() {
	}

	public PubMessage(String touser, TemplateModel weapp_template_msg, MpTemplateMsg mp_template_msg) {
		this.touser = touser;
		this.weapp_template_msg = weapp_template_msg;
		this.mp_template_msg = mp_template_msg;
	}

	public String getTouser() {
		return touser;
	}

	public void setTouser(String touser) {
		this.touser = touser;
	}

	public TemplateModel getWeapp_template_msg() {
		return weapp_template_msg;
	}

	public void setWeapp_template_msg(TemplateModel weapp_template_msg) {
		this.weapp_template_msg = weapp_template_msg;
	}

	public MpTemplateMsg getMp_template_msg() {
		return mp_template_msg;
	}

	public void setMp_template_msg(MpTemplateMsg mp_template_msg) {
		this.mp_template_msg = mp_template_msg;
	}
}

 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;

@EnableScheduling
@Component
@Lazy(false)
public class Schedulers {
    @Autowired
	SysParam sysParam;
	private static Logger logger = LoggerFactory.getLogger(Schedulers.class);
	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");


	//每隔2秒執行一次

	/*@Scheduled(fixedRate = 2000)
	public void testTasks2() {

			System.out.println("定時任務執行時間:1111111111111");

	}
*/

	/**
	 * access_token 是小程序的全局唯一調用憑據
	 * access_token 的有效期為 2 個小時,需要定時刷新 access_token,重復獲取會導致之前一次獲取的
	 * access_token 失效
	 * 延遲一秒執行
	 */
	@Scheduled(initialDelay = 1000, fixedDelay = 6000*1000 )
	public void getAccessToken(){
		try {

			String token = WeChatMessageSendUtil.getAccessToken(sysParam.getWXAPP_APP_ID(),sysParam.getWXAPP_APP_SECRET());
			//將獲取到的token放到內存
			WeChatMessageSendUtil.ACCESSTOKEN = token;
			logger.info("獲取到的微信accessToken為"+token);
		} catch (Exception e) {
			logger.error("獲取微信accessToken出錯,信息如下");
			e.printStackTrace();
		}
	}
}

 

public class STemplateData {
	private String value;//
	private String color;

	public STemplateData() {
	}

	public STemplateData(String value, String color) {
		this.value = value;
		this.color = color;
	}

	public STemplateData(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

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

	@Override
	public String toString() {
		return "TemplateData{" +
				"value='" + value + '\'' +
				", color='" + color + '\'' +
				'}';
	}
}

 

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class SysParam {
	@Value("${message.wxapp.appid}")
	private   String WXAPP_APP_ID;
	@Value("${message.wxapp.appsecret}")
	private   String WXAPP_APP_SECRET;

	public String getWXAPP_APP_ID() {
		return WXAPP_APP_ID;
	}

	public void setWXAPP_APP_ID(String WXAPP_APP_ID) {
		this.WXAPP_APP_ID = WXAPP_APP_ID;
	}

	public String getWXAPP_APP_SECRET() {
		return WXAPP_APP_SECRET;
	}

	public void setWXAPP_APP_SECRET(String WXAPP_APP_SECRET) {
		this.WXAPP_APP_SECRET = WXAPP_APP_SECRET;
	}
}

 

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;
	}

	@Override
	public String toString() {
		return "TemplateData{" +
				"value='" + value + '\'' +
				'}';
	}
}

 

import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import java.util.Map;

/**
 * @author why
 * 訂閱消息模板實體
 */

@EntityListeners(AuditingEntityListener.class)
public class TemplateModel {

	private String form_id;//收集到的用戶formid
	private String emphasis_keyword = "keyword1.DATA";//放大那個推送字段

	@ApiModelProperty(value = "接收人的openId", example = "")
	private String touser;
	@ApiModelProperty(value = "消息模板id", example = "")
	private String template_id;
	@ApiModelProperty(value = "跳轉頁", example = "")
	private String page="/index";
	@ApiModelProperty(value = "參數", example = "")
	Map<String, TemplateData> data;

	public TemplateModel() {
	}

	public TemplateModel(String touser, String template_id, String page, Map<String, TemplateData> data) {
		this.touser = touser;
		this.template_id = template_id;
		this.page = page;
		this.data = 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 Map<String, TemplateData> getData() {
		return data;
	}

	public void setData(Map<String, TemplateData> data) {
		this.data = data;
	}

	@Override
	public String toString() {
		return "WxSendModel{" +
				"touser='" + touser + '\'' +
				", template_id='" + template_id + '\'' +
				", page='" + page + '\'' +
				", data=" + data +
				'}';
	}
}

 

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@Component
public class WeChatMessageSendUtil {
	public static final String POST_PUB_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN";
	public static final String POST_APP_MESSAGE ="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
	public static String ACCESSTOKEN;

	@Autowired
	SysParam sysParam;
	@Autowired
	Schedulers schedulers;

	public static void main(String[] args) {


	}
	/**
	 * 統一消息發送模板
	 */
	public  Map<String,Object> send(PubMessage pubMessage){
		Map<String,Object> resMap=new HashMap<>();
		//獲取token
		if ( ACCESSTOKEN==null){
			schedulers.getAccessToken();
		}
		String accessToken =ACCESSTOKEN;
		//存儲小程序消息模板信息
		TemplateModel weapp_template_msg = pubMessage.getWeapp_template_msg();
		pubMessage.setWeapp_template_msg(null);
		RestTemplate restTemplate = new RestTemplate();
        //發送服務號消息
		ResponseEntity<String> responseEntity =
				restTemplate.postForEntity(POST_PUB_MESSAGE.replace("ACCESS_TOKEN",accessToken), pubMessage, String.class);
		String body = responseEntity.getBody();
		JSONObject jsonObject = JSONObject.parseObject(body);

		if ("40001".equals(jsonObject.get("errcode")+"")){//防止AccessToken過期
			//AccessToken過期
			String token = WeChatMessageSendUtil.getAccessToken(sysParam.getWXAPP_APP_ID(),sysParam.getWXAPP_APP_SECRET());
			//將獲取到的token放到內存
			WeChatMessageSendUtil.ACCESSTOKEN = token;
			accessToken=token;
			responseEntity =restTemplate.postForEntity(POST_PUB_MESSAGE.replace("ACCESS_TOKEN",accessToken), pubMessage, String.class);
			body = responseEntity.getBody();
			jsonObject = JSONObject.parseObject(body);
		}
		if ("0".equals(jsonObject.get("errcode")+"")){
             //服務號發送成功,不再發送小程消息
			resMap.put("code","success");
			resMap.put("msg","公眾號消息發送成功");
			resMap.put("data",pubMessage);
		}else{
			//服務號發送失敗,發送訂閱消息
			String s = WxAppSend(weapp_template_msg, accessToken);
			JSONObject jsonObject2 = JSONObject.parseObject(s);
			if ("0".equals(jsonObject2.get("errcode")+"")){
				resMap.put("code","success");
				resMap.put("msg","小程序消息發送成功");
				resMap.put("data",pubMessage);
			}else{
				resMap.put("code","error");
				resMap.put("msg","小程序消息發送失敗");
				resMap.put("data",jsonObject2);
				resMap.put("msg2","公眾號消息發送失敗");
				resMap.put("data",jsonObject);
			}
		}
       return resMap;
	}

	/**
	 * 訂閱消息模板發送
	 * @param templateModel
	 * @param accessToken
	 * @return
	 */
	public static String WxAppSend(TemplateModel templateModel,String accessToken) {
		String body ="";
		try {
			RestTemplate restTemplate = new RestTemplate();
			String url = POST_APP_MESSAGE.replace("ACCESS_TOKEN",accessToken);
			//拼接推送的模版
			ResponseEntity<String> responseEntity =
					restTemplate.postForEntity(url, templateModel, String.class);
			body = responseEntity.getBody();
		}catch (Exception e){

			return e.getMessage();
		}
		return body;
	}


	/**
	 * 獲取token
	 * @param appId
	 * @param secret
	 * @return
	 */
	public static String getAccessToken(String appId,String secret) {
		Map<String, Object> map = null;
		String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?" +
				"grant_type=client_credential" +
				"&appid="+appId+
				"&secret="+secret;
		try {
			HttpClient client = HttpClientBuilder.create().build();//構建一個Client
			HttpGet get = new HttpGet(access_token_url);    //構建一個GET請求
			HttpResponse response = client.execute(get);//提交GET請求
			HttpEntity result = response.getEntity();//拿到返回的HttpResponse的"實體"
			String content = EntityUtils.toString(result);
			//System.out.println(content);
			JSONObject res = JSONObject.parseObject(content);
			//map = JsonUtil.parseJSON2Map(res);
			return res.get("access_token")+"";
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("獲取信息失敗");
		}
		return "error:access_token";
	}
}

 


免責聲明!

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



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