接入微信小程序公众号消息发送
微信小程序,公众号等接口都在这里有
微信接入,WxJava - 微信开发 Java SDK(开发工具包)的git地址
weixin-java-mp 对应的公众号
1、引入依赖
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>${weixin-java-mp.version}</version>
</dependency>
2、 在bootstrap.yml配置对应的公众号的信息
mp是公共号信息
template是模板的id
wx:
mp:
enable: true
appId: wx69f9c4cc5c753***
configs:
- appId: wx69f9c4cc5c753***
secret: d3be0c48a322bf59b1144419d385e***
token: 5SCHU6DNQpwAFy9Q2wBnoDPySUyuZ***
aesKey: 40DAyYHCGKLD4jU2WuE5Ml6AQC3lqdnAG5qQ2lF1***
template:
partyReportNotify: WWtsAMj2s01RfjkZlS2s6z_38wkkXrL5bGDxs84K***
meetingNotify: Xwb6zRzeQj8U3idV296htHFJIN0rYHaLt__PlXOO***
reportSuccess: cu7MBQzAcyXn9qVY6h8FWSTFaxP-FFrzwSVM5ODX***
reportFailed: k0nKV5feyCKjTLEdY-_Piz8GMg0f3t840AhsSeBA***
3、WxMpProperties 读取配置文件信息
package com.sinoecare.vc2.app.config;
import java.util.List;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import com.sinoecare.vc2.app.util.JsonUtils;
import lombok.Data;
@Data
@ConfigurationProperties(prefix = "wx.mp")
@ConditionalOnProperty(value = "wx.mp.enable", havingValue = "true")
public class WxMpProperties {
private String appId;
private String enable;
private List<MpConfig> configs;
private MpTemplateId template;
@Data
public static class MpConfig {
/**
* 设置微信公众号的appid
*/
private String appId;
/**
* 设置微信公众号的app secret
*/
private String secret;
/**
* 设置微信公众号的token
*/
private String token;
/**
* 设置微信公众号的EncodingAESKey
*/
private String aesKey;
}
@Data
public static class MpTemplateId {
/**
* 在线学习党建知识通知
*/
private String partyStudyNotify;
/**
* 会议通知
*/
private String meetingNotify;
/**
* 报名成功提醒
*/
private String reportSuccess;
/**
* 报名取消成功提醒
*/
private String reportFailed;
}
@Override
public String toString() {
return JsonUtils.toJson(this);
}
}
4、配置类 WxMpConfiguration
package com.sinoecare.vc2.app.config;
import static me.chanjar.weixin.common.api.WxConsts.EventType.SUBSCRIBE;
import static me.chanjar.weixin.common.api.WxConsts.EventType.UNSUBSCRIBE;
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType.EVENT;
import static me.chanjar.weixin.mp.constant.WxMpEventConstants.POI_CHECK_NOTIFY;
import static me.chanjar.weixin.mp.constant.WxMpEventConstants.CustomerService.KF_CLOSE_SESSION;
import static me.chanjar.weixin.mp.constant.WxMpEventConstants.CustomerService.KF_CREATE_SESSION;
import static me.chanjar.weixin.mp.constant.WxMpEventConstants.CustomerService.KF_SWITCH_SESSION;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.sinoecare.vc2.app.handler.KfSessionHandler;
import com.sinoecare.vc2.app.handler.LocationHandler;
import com.sinoecare.vc2.app.handler.LogHandler;
import com.sinoecare.vc2.app.handler.MenuHandler;
import com.sinoecare.vc2.app.handler.MsgHandler;
import com.sinoecare.vc2.app.handler.NullHandler;
import com.sinoecare.vc2.app.handler.ScanHandler;
import com.sinoecare.vc2.app.handler.StoreCheckNotifyHandler;
import com.sinoecare.vc2.app.handler.SubscribeHandler;
import com.sinoecare.vc2.app.handler.UnsubscribeHandler;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.api.WxConsts.EventType;
import me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
@AllArgsConstructor
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {
private final LogHandler logHandler;
private final NullHandler nullHandler;
private final KfSessionHandler kfSessionHandler;
private final StoreCheckNotifyHandler storeCheckNotifyHandler;
private final LocationHandler locationHandler;
private final MenuHandler menuHandler;
private final MsgHandler msgHandler;
private final UnsubscribeHandler unsubscribeHandler;
private final SubscribeHandler subscribeHandler;
private final ScanHandler scanHandler;
private final WxMpProperties properties;
@Bean(autowire = Autowire.BY_NAME,value = "mpService")
public WxMpService wxMpService() {
// 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!!
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
if (configs == null) {
throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
}
WxMpService service = new WxMpServiceImpl();
service.setMultiConfigStorages(configs
.stream().map(a -> {
WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
configStorage.setAppId(a.getAppId());
configStorage.setSecret(a.getSecret());
configStorage.setToken(a.getToken());
configStorage.setAesKey(a.getAesKey());
return configStorage;
}).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
return service;
}
@Bean
public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
return newRouter;
}
}
5、写一个发送公众号信息的工具类
package com.sinoecare.vc2.app.util;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.sinoecare.vc2.app.config.WxMpProperties;
import com.sinoecare.vc2.app.service.AppWeixinUserService;
import com.sinoecare.vc2.common.core.bean.AppWeixinUser;
import com.sinoecare.vc2.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.List;
/**
* MscUtil<br>
* Description:
*
* @author WFJ
* @version 2.0
* @create 2020/4/13
*/
@Component
@Data
@Slf4j
@AllArgsConstructor
@Configuration
public class AppWeixinMpUtil {
/**
* @param openId 发送对象的openId
* @param type 发送模板类型
* @param datas 发送内容
* @param url 跳转地址 非必穿
* @return
* @throws WxErrorException
*/
public static String sendMpMessage(String openId, String type, String url, List<WxMpTemplateData> datas, WxMpProperties properties, AppWeixinUserService appWeixinUserService, WxMpService wpService) throws WxErrorException {
if (properties == null || properties.getTemplate() == null || properties.getEnable().equals("false")) {
throw new RuntimeException("没有配置公众号");
}
if (StrUtil.isBlank(type) || ReflectUtil.getField(WxMpProperties.MpTemplateId.class, type) == null) {
throw new RuntimeException("消息模板类型不正确");
}
//没传openId 取当前用户的OpenId
if (StrUtil.isBlank(openId)) {
openId = SecurityUtils.getUser().getOpenId();
}
WxMpProperties.MpTemplateId template = properties.getTemplate();
//取对应 templateId
String templateId = ReflectUtil.getFieldValue(template, type).toString();
//小程序openId 转 公众号 openId
AppWeixinUser mpUser = appWeixinUserService.getMpOpenIdByWxOpenId(openId);
//没传openId 取当前用户的OpenId
if (mpUser == null) {
throw new RuntimeException("发送对象不存在");
// mpUser = AppWeixinUser.builder().openId("o1zInv4Rs4bTRjwLNkgQAzpkTFu8").build();
}
WxMpTemplateMessage message = new WxMpTemplateMessage();
message.setTemplateId(templateId);
message.setData(datas);
message.setToUser(mpUser.getOpenId());
message.setUrl(url);
String msgId = wpService.getTemplateMsgService().sendTemplateMsg(message);
return msgId;
}
}
6、发送公众号消息的案例
try catch 后不报错 ,不影响正常业务流程
WxMpService 和WxMpProperties 需要在业务类中注入
@Autowired
@Qualifier("mpService")
private WxMpService wpService;
@Autowired
private AppWeixinUserService appWeixinUserService;
@Autowired
private WxMpProperties properties;
@Autowired
private AppWechatUserService appWechatUserService;
@Autowired
private AppPartyService appPartyService;
//发送公众号消息 partyReportNotify
try {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
List<WxMpTemplateData> datas = new ArrayList<>();
datas.add(new WxMpTemplateData("first", "在职党员社区报到有一个新活动"));
datas.add(new WxMpTemplateData("keyword1", df.format(appPartyReport.getBeginTime())));
datas.add(new WxMpTemplateData("keyword2", appPartyReport.getAddress()));
datas.add(new WxMpTemplateData("keyword3", appPartyReport.getTitle()));
datas.add(new WxMpTemplateData("remark", "欢迎报名,请打开村务云小程序查看详情"));
List<String> partyIds = appPartyService.getAllReportIds();
if (CollUtil.isNotEmpty(partyIds)) {
List<AppWechatUser> appWechatUsers = appWechatUserService.getuserByNameAndIdnumber(partyIds);
if (CollUtil.isNotEmpty(appWechatUsers)) {
for (AppWechatUser user : appWechatUsers) {
String mpMessage = AppWeixinMpUtil.sendMpMessage(user.getOpenId(), "partyReportNotify", null, datas, properties, appWeixinUserService, wpService);
}
}
}
} catch (Exception e) {
log.error("发送公众号消息失败-三会一课", e);
}
return new R<>();