😊 @ 作者: 一恍过去
💖 @ 主页: https://blog.csdn.net/zhuocailing3390
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: 微信公众号开发——向指定用户发送模板消息
⏱️ @ 创作时间: 2022年12月14日
目录
- 准备工作
- 1、定义消息模板
- 2、定义模板消息发送请求实体类
- 3、定义订单模板消息实体雷
- 4、配置RestTemplate请求
- 6、请求工具类
- 5、发送模板消息示例
准备工作
1、调用微信公众号接口,需要实现获取AccessToken
,参考《获取AccessToken接口调用凭据》
2、在本地进行联调时,为让微信端能够访问到本地服务,需要进行内网穿透,参考《本地服务器内网穿透实现(NATAPP)》
3、配置微信接口配置信息
,用于告诉微信接收消息的回调地址
1、定义消息模板
比如新增一个用于订单的模板消息:
订单编号:{{orderId.DATA}} 订单金额:{{amount.DATA}} 订单时间:{{time.DATA}}
2、定义模板消息发送请求实体类
SendMessageRep:
@EqualsAndHashCode(callSuper = true)
@Data
public class SendMessageRep extends BaseRep {
/**
* 接收者openid
*/
private String touser;
/**
* 模板ID
*/
private String template_id;
/**
* 模板跳转链接(海外帐号没有跳转能力),非必须
*/
private String url;
/**
* 防重入id。对于同一个openid + client_msg_id, 只发送一条消息,10分钟有效,超过10分钟不保证效果。若无防重入需求,可不填
*/
private String client_msg_id;
/**
* 跳小程序所需数据,不需跳小程序可不用传该数据,非必须
*/
private Miniprogram miniprogram;
/**
* 模板数据
*/
private OrderMessageDataRep data;
/**
* 跳小程序所需数据
*/
@Data
public class Miniprogram {
/**
* 所需跳转到的小程序appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
*/
private String appid;
/**
* 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏,非必须
*/
private String pagepath;
}
}
SendMessageDataRep:
@Data
public class SendMessageDataRep {
/**
* 模板数据
*/
private String value;
/**
* 模板内容字体颜色,不填默认为黑色
*/
private String color;
}
3、定义订单模板消息实体雷
业务实体类需要根据实际清情况进行定义
OrderMessageDataRep:
/**
* @Description: 推送的订单数据,模板消息,具体字段根据定义的模块来设置
* 订单编号:{{orderId.DATA}} 订单金额:{{amount.DATA}} 订单时间:{{time.DATA}}
**/
@Data
public class OrderMessageDataRep {
/**
* 订单编号
*/
private SendMessageDataRep orderId;
/**
* 订单金额
*/
private SendMessageDataRep amount;
/**
* 订单时间
*/
private SendMessageDataRep time;
}
4、配置RestTemplate请求
@Component
public class RestHttpRequest {
private final RestTemplate restTemplate;
public RestHttpRequest(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public Map doHttp(String url, HttpMethod method, Object obj) {
HttpHeaders headers = new HttpHeaders();
HttpEntity entity = new HttpEntity(obj, headers);
ResponseEntity<Map> exchange = restTemplate.exchange(url, method, entity, Map.class);
return exchange.getBody();
}
}
6、请求工具类
public class MapUtils {
/**
* 将Map参数转换为字符串
*
* @param map
* @return
*/
public static String mapToString(Map<String, Object> map) {
StringBuffer sb = new StringBuffer();
map.forEach((key, value) -> {
sb.append(key).append("=").append(value.toString()).append("&");
});
String str = sb.toString();
str = str.substring(0, str.length() - 1);
return str;
}
/**
* 将Bean对象转换Url请求的字符串
*
* @param t
* @param <T>
* @return
*/
public static <T> String getUrlByBean(T t) {
String pre = "?";
Map<String, Object> map = entityToMap(t);
return pre + mapToString(map);
}
}
5、发送模板消息示例
说明:
//测试接口:/wechat/sendMsg(向指定用户发送模板消息)
//正常流程:用户在公众号进行操作(购物成功)后,向当前用户发送模板消息
//消息模板的定义如下:其中DATA为固定写法
订单编号:{{orderId.DATA}}
订单金额:{{amount.DATA}}
订单时间:{{time.DATA}}
//在推送完成后,微信服务器会向消息接口发送消息
//orderId、amount、time表示一个属性(名称任意),value为该属性的值,color为显示时的颜色
{
"touser":"OPENID",
"template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
"url":"http://weixin.qq.com/download",
"data":{
"orderId": {
"value":"xxxxxxxxxx",
"color":"#173177"
},
"amount": {
"value":"33.33元",
"color":"#F6067A"
},
"time": {
"value":"2022-12-12 12:12:12",
"color":"#FF6931"
}
}
}
示例代码 :
@Slf4j
@Controller
public class MessageController {
/**
* 发送模板消息
* url和 miniprogram 都是非必填字段,若都不传则模板无跳转;
* 若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。
* 当用户的微信客户端版本不支持跳小程序时,将会跳转至url。
*/
@PostMapping(value = "/sendMsg")
@ApiOperation(value = "发送模板消息", notes = "发送模板消息")
@ResponseBody
public Map sendMsg() {
String url = wxBean.getApiUrl() + InterfaceConstant.SEND_MSG;
SendMessageRep rep = new SendMessageRep();
rep.setAccess_token(weChantService.getAccessToken());
url = url + MapUtils.getUrlByBean(rep);
rep.setTouser("推送给具体用户的openId");
rep.setTemplate_id("定义的模板Id");
rep.setUrl("http://weixin.qq.com");
rep.setClient_msg_id(UUIDUtils.getUuId());
OrderMessageDataRep orderMessage = new OrderMessageDataRep();
// 封装模板数据
SendMessageDataRep orderId = new SendMessageDataRep();
orderId.setValue(String.valueOf(System.currentTimeMillis()));
orderId.setColor("#173177");
orderMessage.setOrderId(orderId);
SendMessageDataRep amount = new SendMessageDataRep();
amount.setValue("3.33");
amount.setColor("#F6067A");
orderMessage.setAmount(amount);
SendMessageDataRep time = new SendMessageDataRep();
time.setValue("2022-12-12 12:12:12");
time.setColor("#FF6931");
orderMessage.setTime(time);
rep.setData(orderMessage);
return restHttpRequest.doHttp(url, HttpMethod.POST, rep);
}
}