在用户购买会员卡后的第二天下午四点发送微信模板消息
在pom.xml里面配置
net.coobird thumbnailator 0.4.8 com.github.binarywang weixin-java-miniapp ${wexin-tools-version} com.github.binarywang weixin-java-mp 3.1.0 com.github.binarywang weixin-java-common ${wexin-tools-version} com.github.binarywang weixin-java-pay ${wexin-tools-version}
所以先在数据库里面建了一张表,把发送时间写进去,把微信模板中要用到的信息存入到数据库中,并设置一个标识去标识这个用户有没有被发送过消息。然后写个定时任务,每隔一定时间去把这个时间拿出来跟当前时间作比较,当前时间大于存在数据库里的时间就执行发送模板消息,然后把标识改成1。
这里面的OPENID都是公众号的openid,不是小程序的openid.可以根据小程序的unionID去找到用户在公众号中的openid
package com.umshuo.service; import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON; import com.aliyun.openservices.shade.com.alibaba.fastjson.JSONObject; import com.qiniu.util.StringUtils; import com.umshuo.domain.Business; import com.umshuo.domain.Receiver; import com.umshuo.domain.User; 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.result.WxMpUser; import me.chanjar.weixin.mp.bean.result.WxMpUserList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.Set; @Slf4j @Service public class SyncOpenIdService { @Autowired @Qualifier("wxMpService") private WxMpService wxMpService; @Autowired @Qualifier("wxMpServiceBusiness") private WxMpService wxMpServiceBusiness; @Autowired private UserService userService; @Autowired private ReceiverService receiverService; @Autowired private BusinessService businessService; @Autowired private RedisTemplateredisTemplate; public void syncFromWechat(String lastOpenId){ try { log.info("同步关注微信公众号社区买手的用户信息 - lastMpOpenId: [{}]", lastOpenId); WxMpUserList list = getWxMpUserList(lastOpenId); log.info("获取的用户数量: " + list.getOpenids().size()); List
定时任务:
第一个:
2.
package com.umshuo.properties; import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class WechatMpConfig { @Autowired WechatAccountConfig wechatAccountConfig; /** * 微信服务装载 * @return */ @Bean public WxMpService wxMpService() { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); return wxMpService; } /** * 微信服务装载 * @return */ @Bean public WxMpService wxMpServiceBusiness() { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(wxMpConfigStorageBusiness()); return wxMpService; } /** * 配置温馨的APPID和密码 * @return */ @Bean public WxMpConfigStorage wxMpConfigStorage() { WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage(); wxMpConfigStorage.setAppId(wechatAccountConfig.getAppId()); wxMpConfigStorage.setSecret(wechatAccountConfig.getSecret()); return wxMpConfigStorage; } /** * 配置温馨的APPID和密码 * @return */ @Bean public WxMpConfigStorage wxMpConfigStorageBusiness() { WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage(); wxMpConfigStorage.setAppId(wechatAccountConfig.getAppIdBusiness()); wxMpConfigStorage.setSecret(wechatAccountConfig.getSecretBusiness()); return wxMpConfigStorage; } }
package com.umshuo.properties; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "wechat.mp") public class WxMpProperties { /** * 设置微信公众号的appid */ private String appId; /** * 设置微信公众号的app secret */ private String secret; /** * 设置微信公众号的token */ private String token; /** * 设置微信公众号的EncodingAESKey */ private String aesKey; public String getAppId() { return this.appId; } public void setAppId(String appId) { this.appId = appId; } public String getSecret() { return this.secret; } public void setSecret(String secret) { this.secret = secret; } public String getToken() { return this.token; } public void setToken(String token) { this.token = token; } public String getAesKey() { return this.aesKey; } public void setAesKey(String aesKey) { this.aesKey = aesKey; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } }
package com.umshuo.service; import com.alibaba.fastjson.JSON; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Lists; import com.umshuo.common.JsonUtil; import com.umshuo.common.ServerResponse; import com.umshuo.common.StringUtil; import com.umshuo.common.WXBizDataCrypt; import com.umshuo.properties.WechatAccountConfig; import com.umshuo.properties.WechatMpConfig; import com.umshuo.vo.SessionKeyVo; import lombok.Getter; 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.json.JSONException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * @author chezhu.xin */ @Slf4j @Service public class WxService { @Autowired @Qualifier("wxMpService") private WxMpService mpService; @Autowired @Qualifier("wxMpServiceBusiness") private WxMpService wxMpServiceBusiness; @Autowired private WechatAccountConfig wechatAccountConfig; private static final CacheCACHE = CacheBuilder.newBuilder() .initialCapacity(1000) .maximumSize(20000) .expireAfterWrite(30, TimeUnit.MINUTES) .build(); private static final Cache OPENID_CACHE = CacheBuilder.newBuilder() .initialCapacity(1000) .maximumSize(20000) .expireAfterWrite(30, TimeUnit.MINUTES) .build(); @Getter private enum WxAppIdEnum { /** * 微信小程序信息 */ APP_1("小程序名字", "这里放APPID", "这里放模板id"), APP_2("小程序名字", "这里放APPID", "这里放模板id"), APP_3("小程序名字", "这里放APPID", "这里放模板id"); private final String desc; private final String appId; private final String appSecret; WxAppIdEnum(String desc, String appId, String appSecret) { this.desc = desc; this.appId = appId; this.appSecret = appSecret; } public static WxAppIdEnum getWxAppIdEnum(String appId) { for (WxAppIdEnum wxAppIdEnum : Lists.newArrayList(WxAppIdEnum.values())) { if (Objects.equals(appId, wxAppIdEnum.getAppId())) { return wxAppIdEnum; } } return null; } } public ServerResponse sessionKey(String code, String appId) throws JSONException { WxAppIdEnum wxAppIdEnum = WxAppIdEnum.getWxAppIdEnum(appId); if (wxAppIdEnum == null) { return ServerResponse.createByErrorMessage(appId); } String requestAppId = wxAppIdEnum.appId; String requestAppSecret = wxAppIdEnum.appSecret; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("https://api.weixin.qq.com/sns/jscode2session"); stringBuilder.append("?").append("appid").append("=").append(requestAppId); stringBuilder.append("&").append("secret").append("=").append(requestAppSecret); stringBuilder.append("&").append("js_code").append("=").append(code); stringBuilder.append("&").append("grant_type").append("=").append("authorization_code"); String result = new RestTemplate().getForObject(stringBuilder.toString(), String.class); log.debug(stringBuilder.toString()); log.debug(result); String sessinKey = JsonUtil.toJsonObject(result).getString("session_key"); String openid = JsonUtil.toJsonObject(result).getString("openid"); log.debug("添加缓存=="+openid); CACHE.put(code, sessinKey); OPENID_CACHE.put(code, openid); SessionKeyVo sessionKeyVo = JsonUtil.fromJson(result, SessionKeyVo.class); return ServerResponse.createBySuccess(sessionKeyVo); } public ServerResponse descrypt(String code, String appId, String encryptedData, String iv) throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, JSONException { if (StringUtil.isBlank(code)) { return ServerResponse.createByErrorMessage("code 值不允许为空"); } String sessionKey = CACHE.getIfPresent(code); if (StringUtil.isBlank(sessionKey)) { WxAppIdEnum wxAppIdEnum = WxAppIdEnum.getWxAppIdEnum(appId); if (wxAppIdEnum == null) { return ServerResponse.createByErrorMessage(appId); } String requestAppId = wxAppIdEnum.appId; String requestAppSecret = wxAppIdEnum.appSecret; String stringBuilder = "https://api.weixin.qq.com/sns/jscode2session" + "?" + "appid" + "=" + requestAppId + "&" + "secret" + "=" + requestAppSecret + "&" + "js_code" + "=" + code + "&" + "grant_type" + "=" + "authorization_code"; String resultStr = new RestTemplate().getForObject(stringBuilder, String.class); String str = JsonUtil.toJsonObject(resultStr).getString("session_key"); String openid = JsonUtil.toJsonObject(resultStr).getString("openid"); if (StringUtil.isNotBlank(str)) { sessionKey = str; CACHE.put(appId,sessionKey); } log.debug("查询的结果:{}",resultStr); if(StringUtil.isNotBlank(resultStr)){ SessionKeyVo sessionKeyVo = JsonUtil.fromJson(resultStr, SessionKeyVo.class); return ServerResponse.createBySuccess(sessionKeyVo); } } String result = WXBizDataCrypt.getInstance().decrypt(encryptedData, sessionKey, iv, "utf-8"); log.debug("result:{}", result); SessionKeyVo sessionKeyVo = JsonUtil.fromJson(result, SessionKeyVo.class); return ServerResponse.createBySuccess(sessionKeyVo); } /** * 解密unionID */ public String descrypt(String sessionKey, String encryptedData, String iv) throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { String result = WXBizDataCrypt.getInstance().decrypt(encryptedData, sessionKey, iv, "utf-8"); log.debug("result:{}", result); SessionKeyVo sessionKeyVo = JsonUtil.fromJson(result, SessionKeyVo.class); return sessionKeyVo.getUnionid(); } /** * 发送社区买手模板消息 * @param templateMap * @return */ public boolean sendMessage(Map templateMap) { try { WxMpTemplateMessage template = new WxMpTemplateMessage(); template.setToUser((String)templateMap.get("openId")); template.setTemplateId((String)templateMap.get("templateId")); template.setMiniProgram(new WxMpTemplateMessage.MiniProgram(wechatAccountConfig.getMiniAppId(),(String)templateMap.get("url"))); template.setData((List )templateMap.get("data")); String response = mpService.getTemplateMsgService().sendTemplateMsg(template); log.debug("发送微信模板信息结果 - openId:[{}], response:[{}]", template.getToUser(), JSON.toJSONString(response)); return true; } catch (WxErrorException ex) { ex.printStackTrace(); log.error("【微信模版消息】发送失败, {}", ex); } return false; } /** * */ /** * 发送社区达模板消息 * @param templateMap * @return */ public boolean sendMessageBusiness(Map templateMap) { try { WxMpTemplateMessage template = new WxMpTemplateMessage(); template.setToUser((String)templateMap.get("openId")); template.setTemplateId((String)templateMap.get("templateId")); template.setMiniProgram(new WxMpTemplateMessage.MiniProgram(wechatAccountConfig.getMiniAppIdBusiness(),(String)templateMap.get("url"))); template.setData((List )templateMap.get("data")); String response = wxMpServiceBusiness.getTemplateMsgService().sendTemplateMsg(template); log.debug("发送微信模板信息结果 - openId:[{}], response:[{}]", template.getToUser(), JSON.toJSONString(response)); return true; } catch (WxErrorException ex) { ex.printStackTrace(); log.error("【微信模版消息】发送失败, {}", ex); } return false; } }