笔者在上个月接到一个需求,大概是需要计算一条数据的最大办理时间从而发送任务超期的微信小程序服务通知,俺也是第一次接触到需要调用微信的API去进行发送消息,该博客权当记录此次功能开发的过程了~
本身微信的官方文档是提供了采用http调用的方式去进行调用微信的API微信小程序官方文档
但是俺想着都已经是什么年代了,于是找到了GitHub上的一个资料GitHub地址
我们可以看到几乎涵盖了所有微信相关的API,在这里不得不感慨一下binarywang,王哥他们真的太厉害了~
可以理解为不同的jar包对应引入了不从的SDK库,使调用的更方便,更简洁,下面就来依次讲解吧:
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.0.0</version>
</dependency>
准备工作当然不止后端的JAR包引入,我们还需要选择一个将要发送消息通知的模板,此步如果是全栈大怨种就看该官方文档,很详细选择服务通知模板,如果是后端好哥们,就让前端自己研究,宗旨是需要拿到模板ID很重要!!见下图,为我圈中的那个ID,需要被后端拿到。
我们先看我们所需要的所有配置,笔者均写到了yml中,可能不是太好看,见谅~
wx:
miniapp:
#上面拿到的很重要的那个模板ID
template-id: g19lTFku79jXC58CDzTnoIeazJC8HHvbW82apat_vgs
configs:
#微信小程序的appid 开发者工具拿到
appid: wx05e2612sfav212bddev12
#开发者工具拿到Secret
secret: 91b5a9e5645e8cf2123213safasfgwgf
#微信小程序消息服务器配置的token
token: 123
#微信小程序消息服务器配置的EncodingAESKey
aesKey:
msgDataFormat: JSON
该配置文件笔者这里为两个,大家也可以只写一个,主要目的是为了注入引入的JAR包中的WxMaService,只有用这个,我们才能进行调用API
这里需要注意的是笔者的WxProperties是写的另一个配置文件,如果大家觉得写配置文件很麻烦,也可以写一个,采用手动注入值的放肆,这个WxProperties见下一个配置文件:
/**
* @describe:
* @author: jiazl /
* @version: v1.0
*/
@Slf4j
@Configuration
@EnableConfigurationProperties(WxProperties.class)
public class WxConfig {
private final WxProperties properties;
@Autowired
public WxConfig(WxProperties properties) {
this.properties = properties;
}
@Bean
public WxMaService getService() {
if (properties == null || properties.getAppid() == null || properties.getSecret() == null) {
throw new WxRuntimeException("required wechat param not found");
}
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid(properties.getAppid());
config.setSecret(properties.getSecret());
config.setToken(properties.getToken());
config.setAesKey(properties.getAesKey());
config.setMsgDataFormat(properties.getMsgDataFormat());
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(config);
return service;
}
采用配置类注入的方式,如果大家不想写配置,可以采用手动设置值,目的是为了让上面的配置中的service注入到容器里面。
@Data
@ConfigurationProperties(prefix = "wx.miniapp.configs")
public class WxProperties {
/**
* 设置微信小程序的appid
*/
private String appid;
/**
* 设置微信小程序的Secret
*/
private String secret;
/**
* 设置微信小程序消息服务器配置的token
*/
private String token;
/**
* 设置微信小程序消息服务器配置的EncodingAESKey
*/
private String aesKey;
/**
* 消息格式,XML或者JSON
*/
private String msgDataFormat;
}
@RestController
@Slf4j
@Api(tags = "征兵测试接口")
public class ZbSendDemoController {
@Autowired
private WxMaService wxService;
@Value("${wx.miniapp.template-id}")
private String templteId;
@Resource
public RabbitTemplate rabbitTemplate;
/**
* 跳转的小程序页面
*/
private static final String PAGES_ZP = "pages/draft-review/list/list";
@GetMapping("/api/zphs/sendZbhsMsg")
@ApiOperation("传openId发送微信服务通知")
public ApiResult<Boolean> sendMsg(String openID) {
sendSmallMsg(openID);
return ApiResult.success(true);
}
private void sendSmallMsg(String openId) {
Map<String, String> map = new HashMap<>();
map.put("phrase1","测试");
map.put("thing3", "您收到了应征公民测试测试的任务提醒消息");
map.put("time12", LocalDateTimeUtil.formatNormal(LocalDateTime.now()));
WxMaSubscribeMessage wxMaSubscribeMessage = WxMaSubscribeMessage.builder()
.toUser(openId)
.templateId(templteId)
.page(PAGES_ZP)
.build();
// 设置将推送的消息
map.forEach((k, v) -> {
wxMaSubscribeMessage.addData(new WxMaSubscribeMessage.Data(k, v));
});
try {
log.info("开始发送消息!!!!");
wxService.getMsgService().sendSubscribeMsg(wxMaSubscribeMessage);
log.info("消息发送成功!!!!");
} catch (WxErrorException e) {
e.printStackTrace();
}
}
@GetMapping("/api/zphs/sendMqDemo")
@ApiOperation("消息队列发送微信服务通知测试")
public ApiResult<Boolean> sendMqDemo(String taskId,String time,String state,String id ) {
sendMessage( taskId, time, state,id);
return ApiResult.success(true);
}
public void sendMessage(String taskId,String time,String state,String id) {
//发送延时队列消息
Map<String, Object> map = new HashMap<>(10);
map.put("taskId", taskId);
map.put("state", state);
map.put("bzpId",id);
String message = JSON.toJSONString(map);
log.info("开始发送!!!");
rabbitTemplate.convertAndSend(RabbitMqSendMsgConfig.DELAYED_EXCHANGE_NAME, RabbitMqSendMsgConfig.DELAYED_ROUTING_KEY,
message, msg -> {
msg.getMessageProperties().setDelay(Integer.parseInt(time));
return msg;
});
log.info("发送消息成功!!!");
}
笔者这里的Controller很乱,因为里面不仅有发送消息的代码,也有RabbitMq的代码,当然这都是和具体业务相关,我们的重点是sendSubscribeMsg
到这一步,消息就发送成功了,我们可以看到实例:
到这里,我们需要有几个地方注意:
1
模板中当前状态,温馨提示,工单创建时间均为参数对应值,代码是为发送前的Map里面
2
Controller最上面有一行:
private static final String PAGES_ZP = "pages/draft-review/list/list";
对应为点击进入小城许跳转的页面,为具体业务所定
3
OpenId是个很重要的东西,是登录微信小程序都会获取到的,唯一性的,微信的API就是通过OpenId给具体的用户发送消息,所以第一个方法内我的参数就为OpenId,这个OpenId是前端传输到后端的,我在这里仅仅是一个Demo接口,切记
4
如果有时间,我会写一篇RabbitMq的文章,讲解一下用法及踩过的坑,然后将整个业务需求进行描述讲解
5
注意图片中的参数的个数及名称
一定要和微信小程序模板上的保持一致,个数及参数名(模板的参数可以在微信开发者工具上看),注意部分参数有字数限制,具体限制要求可以查看微信开发者工具上的具体描述。
6
祝大家天天开心~~~~
好了,俺这次的文章就到这里结束了,祝大家都找到新的工作,天天开心,万事如意~~
敬礼!
salute!!