package com.qianwen.core.notify.provider.wechat.mini;
|
|
import java.time.Duration;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.concurrent.atomic.AtomicReference;
|
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.qianwen.core.http.HttpRequest;
|
import com.qianwen.core.log.exception.BizServiceException;
|
import com.qianwen.core.notify.DefaultNotifyType;
|
import com.qianwen.core.notify.NotifyType;
|
import com.qianwen.core.notify.Provider;
|
import com.qianwen.core.notify.notifier.AbstractNotifier;
|
import com.qianwen.core.notify.notifier.NotifierProperties;
|
import com.qianwen.core.notify.provider.wechat.WechatMiniProvider;
|
import com.qianwen.core.notify.template.TemplateManager;
|
import com.qianwen.core.tool.api.BizMessage;
|
import com.qianwen.core.tool.metadata.Values;
|
import com.qianwen.core.tool.utils.Func;
|
import com.qianwen.core.tool.utils.StringFormatUtil;
|
import com.qianwen.core.tool.utils.StringUtil;
|
|
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
|
import cn.binarywang.wx.miniapp.bean.device.WxMaDeviceSubscribeMessageRequest;
|
|
public class WeixinMiniDeviceNotifier extends AbstractNotifier<WechatMiniMessageTemplate> {
|
private static final Logger log = LoggerFactory.getLogger(WeixinMiniDeviceNotifier.class);
|
private final AtomicReference<String> accessToken;
|
private long refreshTokenTime;
|
private final long tokenTimeOut;
|
private static final String tokenApi = "https://api.weixin.qq.com/cgi-bin/token";
|
private static final String notify = "https://api.weixin.qq.com/cgi-bin/message/device/subscribe/send?access_token=";
|
private final WechatMiniProperties properties;
|
private final String notifierId;
|
private NotifierProperties notifierProperties;
|
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public String getNotifierId() {
|
return this.notifierId;
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public NotifierProperties getNotifierProperties() {
|
return this.notifierProperties;
|
}
|
|
public WeixinMiniDeviceNotifier(NotifierProperties properties, TemplateManager templateManager) {
|
super(templateManager);
|
this.accessToken = new AtomicReference<>();
|
this.tokenTimeOut = Duration.ofSeconds(7000L).toMillis();
|
WechatMiniProperties wechatMpProperties = (WechatMiniProperties) new JSONObject(properties.getConfiguration()).toJavaObject(WechatMiniProperties.class);
|
this.properties = wechatMpProperties;
|
this.notifierProperties = properties;
|
this.notifierId = properties.getId();
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public NotifyType getType() {
|
return DefaultNotifyType.weiXinMini;
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public Provider getProvider() {
|
return WechatMiniProvider.miniDeviceSubMessage;
|
}
|
|
public void send(WechatMiniMessageTemplate template, String traceId, Values context, List<String> notifiedParty) {
|
String access_token = getToken();
|
Map<String, Object> maps = context.getAllValues();
|
List<WxMaSubscribeMessage.MsgData> templateDataList = new ArrayList<>();
|
List<WechatMiniMessageTemplate.ConfigProperty> templateMapping = template.getProperties();
|
if (Func.isNotEmpty(maps)) {
|
maps.forEach((k, v) -> {
|
WxMaSubscribeMessage.MsgData temp = new WxMaSubscribeMessage.MsgData();
|
if (Func.isNotEmpty(v)) {
|
temp.setValue(v.toString());
|
}
|
if (Func.isNotEmpty(templateMapping)) {
|
temp.setName((String) templateMapping.stream().filter(x -> {
|
return x.getName().equals(k);
|
}).map(x2 -> {
|
return x2.getValue();
|
}).findFirst().orElse(k));
|
} else {
|
temp.setName(k);
|
}
|
templateDataList.add(temp);
|
});
|
}
|
HttpRequest httpRequest = HttpRequest.post(notify.concat(access_token));
|
WxMaDeviceSubscribeMessageRequest deviceSubscribeMessageRequest = new WxMaDeviceSubscribeMessageRequest();
|
deviceSubscribeMessageRequest.setTemplateId(template.getTemplateId());
|
deviceSubscribeMessageRequest.setToOpenidList(notifiedParty);
|
if (Func.isNotBlank(template.getPage())) {
|
deviceSubscribeMessageRequest.setPage(StringFormatUtil.format(template.getPage(), maps));
|
}
|
if (Func.isNotBlank(template.getMiniprogramState())) {
|
deviceSubscribeMessageRequest.setMiniprogramState(template.getMiniprogramState());
|
}
|
deviceSubscribeMessageRequest.setData(templateDataList);
|
Map<String, Object> result = httpRequest.bodyString(deviceSubscribeMessageRequest.toJson()).execute().onFailed((k2, v2) -> {
|
log.info(StringUtil.format("发送小程序设备订阅消息{}失败,原因{}", new Object[]{k2.url(), v2.getMessage()}));
|
}).asMap(Object.class);
|
if (result.containsKey("errcode") && !result.get("errcode").equals(0)) {
|
BizMessage bizMessage = new BizMessage();
|
bizMessage.setMessage(result.get("errcode").toString());
|
bizMessage.setMessage(result.get("errmsg").toString());
|
throw new BizServiceException(bizMessage);
|
}
|
|
}
|
|
private String getToken() {
|
if (System.currentTimeMillis() - this.refreshTokenTime > this.tokenTimeOut || this.accessToken.get() == null) {
|
return requestToken();
|
}
|
return this.accessToken.get();
|
}
|
|
private String requestToken() {
|
HttpRequest httpRequest = HttpRequest.get("https://api.weixin.qq.com/cgi-bin/token");
|
Map<String, Object> queries = new HashMap<>();
|
queries.put("grant_type", "client_credential");
|
queries.put("appid", this.properties.getAppid());
|
queries.put("secret", this.properties.getSecret());
|
httpRequest.queryMap(queries);
|
Map<String, Object> result = httpRequest.execute().onFailed((k, v) -> log.info(StringUtil.format("发送小程序设备订阅消息{}失败,原因{}", new Object[] { k.url(), v.getMessage() }))).asMap(String.class);
|
if (result.containsKey("access_token")) {
|
this.refreshTokenTime = System.currentTimeMillis();
|
this.accessToken.set(result.get("access_token").toString());
|
return result.get("access_token").toString();
|
}
|
BizMessage bizMessage = new BizMessage();
|
bizMessage.setMessage(result.get("errcode").toString());
|
bizMessage.setMessage(result.get("errmsg").toString());
|
throw new BizServiceException(bizMessage);
|
}
|
|
@Override // com.qianwen.core.notify.notifier.Notifier
|
public void close() {
|
this.accessToken.set(null);
|
this.refreshTokenTime = 0L;
|
}
|
}
|