一、订阅消息流程
注意:目前微信这边只支持一次性订阅,就是同意几次发送几次,永久性订阅目前只支持一些政府,医疗等行业。所以我们做不到一次订阅就可以一直发消息,需要每次订阅发一次。
但是前端支持一次订阅三个不同的模板id,这样就可以做到一次订阅可以发三次(不同模板id的消息)消息。
所以这个订阅消息,对于后端来说就只是调用微信的接口,发送消息就可以了,重点还是在前端去考虑如何在合适的地点去吊起弹窗,去上用户进行授权。
二、获取模板id
首先登录微信公众平台,作为开发者,你可以去选取订阅的模板,也可以去自己创建模板,但是自己创建的模板一个月只有十次机会,并且你创建了,微信这边给你审核,一般审核时间在3-7天,并且审核失败你需要重新提交审核,这也会消耗你的每月十次机会的。
选中一个订阅模板,进入编辑
选中之后再我的模板
点击详情
注意这个详细内容很重要。
三、代码展示
1. 导入微信小程序包依赖(pom中配置)
<!--微信小程序工具包-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.0.0</version>
</dependency>
2.配置微信的必要参数(yml文件中配置)
wx:
miniapp:
app-id: wxba11af1453cscs
app-secret: f86410070e07cscscsc
这些参数很重要,都可以在微信公众平台找到
3.微信配置
- 属性配置
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxProperties {
/**
* 设置微信小程序的appid.
*/
private String appId;
/**
* 设置微信小程序的Secret.
*/
private String appSecret;
}
- 将微信小程序注入到spring中
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@AllArgsConstructor
public class WxConfig {
private final WxProperties properties;
/**
* 小程序service配置
*/
@Bean
public WxMaService wxMaService() {
WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
wxMaConfig.setAppid(this.properties.getAppId());
wxMaConfig.setSecret(this.properties.getAppSecret());
WxMaService wxMaService = new WxMaServiceImpl();
wxMaService.setWxMaConfig(wxMaConfig);
return wxMaService;
}
}
4.获得微信的openid
@Slf4j // 这个是为了记录log的,写在类的最前方
private final WxMaService wxMaService;
/**
* 获得微信openid
* @param code 前端给的微信code
* @return openid
*/
public String wxLogin(String code) {
try {
WxMaUserService wxMaUserService = wxMaService.getUserService();
WxMaJscode2SessionResult sessionInfo = wxMaUserService.getSessionInfo(code);
String openid = sessionInfo.getOpenid();
return openid;
} catch (WxErrorException e) {
log.error("微信授权异常: 错误码:{}, 错误码描述:{}",
e.getError().getErrorCode(), e.getError().getErrorMsg());
//出现异常直接抛出异常,这是自己自定义的异常,需要修改成自己项目定义的,或者直接在后面return null;
throw new ApiErrorException(ErrorCode.WX_CODE_EXPIRED);
}
}
5.处理订阅消息的主体
/**
* 设置会议订阅消息
*
* @param form 消息条件
* @return 订阅会议消息
*/
public static List<WxMaSubscribeMessage.Data> setMeetingMsg (MeetingMsgForm form) {
List<WxMaSubscribeMessage.Data> dataList = new ArrayList<>();
//这里要完全按照订阅消息模板详情去设置,thing1 ,thing2...不能变
WxMaSubscribeMessage.Data data1 = new WxMaSubscribeMessage.Data();
data1.setName("thing1");
data1.setValue(form.getTitle());
dataList.add(data1);
WxMaSubscribeMessage.Data data2 = new WxMaSubscribeMessage.Data();
data2.setName("date2");
DateTime time = DateUtil.parse(form.getDate(), "yyy-MM-dd HH:mm");
data2.setValue(time.toString("yyy-MM-dd HH:mm"));
dataList.add(data2);
WxMaSubscribeMessage.Data data3 = new WxMaSubscribeMessage.Data();
data3.setName("thing3");
data3.setValue(form.getMeetingName());
dataList.add(data3);
return dataList;
}
import lombok.Data;
@Data
public class MeetingMsgForm {
/**
* 会议名称
*/
private String title;
/**
* 会议日期
*/
private String date;
/**
* 会议备注
*/
private String content;
}
6.业务处理,发送订阅消息
@Slf4j // 这个是为了记录log的,写在类的最前方
/**
* 根据模板id发送消息
*
* @param form 消息主体
* @param userOpenIds 用户的openid列表
* @param templateId 模板id
*/
private void sendWxMsg(MeetingMsgForm form, Long recordId, List<String> userOpenIds) {
for (String openId : userOpenIds) {
WxMaSubscribeMessage.WxMaSubscribeMessageBuilder builder = WxMaSubscribeMessage.builder();
//发送人openid
builder.toUser(openId);
//发送的模板id
builder.templateId(templateId);
//消息主体
builder.data(GetMsgUtil.setMeetingMsg(form));
//点击订阅消息的跳转链接(默认是正式发布的小程序页面,当然也可以通过参数进行控制)
builder.page("/cs/cs");
WxMaSubscribeMessage msg = builder.build();
try {
wxMaService.getMsgService().sendSubscribeMsg(msg);
} catch (WxErrorException e) {
log.error("会议通知发送失败,用户openId:{}, 错误码:{},错误信息:{}",
openId, e.getError().getErrorCode(), e.getError().getErrorMsg());
}
}
}
四、总结
发送订阅消息主要是一次性订阅,我们后端可以无限次数的请求微信的服务器,但是微信服务器会根据用户是否授权,以及授权了几次去进行发送,所以这里最容易出的问题就是发送了消息,但是提示报错为用户未授权。
如果做这个订阅消息,一定和需求的制定者说清楚,目前不支持永久性订阅,只能是订阅一次发送一次。需要前端去设置在那里弹起订阅。