diff --git a/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java b/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java index f5aa376..c425dfa 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java +++ b/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java @@ -12,6 +12,13 @@ package com.java3y.austin.common.constant; */ public class SendAccountConstant { + /** + * 账号约定:所有的账号都从10开始,步长为10 + */ + public static final Integer START = 10; + public static final Integer STEP = 10; + + /** * 钉钉 工作应用消息 账号 */ @@ -19,6 +26,14 @@ public class SendAccountConstant { public static final String DING_DING_WORK_NOTICE_PREFIX = "ding_ding_work_notice_"; public static final String DING_DING_ACCESS_TOKEN_PREFIX = "ding_ding_access_token_"; + /** + * 个推PUSH 消息账号 + */ + public static final String GE_TUI_ACCOUNT_KEY = "geTuiAccount"; + public static final String GE_TUI_ACCOUNT_PREFIX = "ge_tui_account_"; + public static final String GE_TUI_ACCESS_TOKEN_PREFIX = "ge_tui_access_token_"; + + /** * 邮件 账号 @@ -46,9 +61,5 @@ public class SendAccountConstant { public static final String SMS_ACCOUNT_KEY = "smsAccount"; public static final String SMS_PREFIX = "sms_"; - /** - * 账号约定:所有的账号都从10开始,步长为10 - */ - public static final Integer START = 10; - public static final Integer STEP = 10; + } diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/account/GeTuiAccount.java b/austin-common/src/main/java/com/java3y/austin/common/dto/account/GeTuiAccount.java new file mode 100644 index 0000000..994fbfe --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/account/GeTuiAccount.java @@ -0,0 +1,30 @@ +package com.java3y.austin.common.dto.account; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 创建个推账号时的元信息 + * + * @author 3y + *
+ * (在调用个推的api时需要用到部分的参数) + *
+ * https://docs.getui.com/getui/start/devcenter/ + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GeTuiAccount { + + private String appId; + + private String appKey; + + private String masterSecret; +} diff --git a/austin-cron/src/main/java/com/java3y/austin/cron/dto/getui/GeTuiTokenResultDTO.java b/austin-cron/src/main/java/com/java3y/austin/cron/dto/getui/GeTuiTokenResultDTO.java new file mode 100644 index 0000000..ef8de29 --- /dev/null +++ b/austin-cron/src/main/java/com/java3y/austin/cron/dto/getui/GeTuiTokenResultDTO.java @@ -0,0 +1,37 @@ +package com.java3y.austin.cron.dto.getui; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author 3y + * @date 2022/5/8 + *
+ * https://docs.getui.com/getui/server/rest_v2/token/ + */ +@NoArgsConstructor +@Data +@AllArgsConstructor +@Builder +public class GeTuiTokenResultDTO { + + + @JSONField(name = "msg") + private String msg; + @JSONField(name = "code") + private Integer code; + @JSONField(name = "data") + private DataDTO data; + + @NoArgsConstructor + @Data + public static class DataDTO { + @JSONField(name = "expire_time") + private String expireTime; + @JSONField(name = "token") + private String token; + } +} diff --git a/austin-cron/src/main/java/com/java3y/austin/cron/dto/getui/QueryTokenParamDTO.java b/austin-cron/src/main/java/com/java3y/austin/cron/dto/getui/QueryTokenParamDTO.java new file mode 100644 index 0000000..6a1a848 --- /dev/null +++ b/austin-cron/src/main/java/com/java3y/austin/cron/dto/getui/QueryTokenParamDTO.java @@ -0,0 +1,40 @@ +package com.java3y.austin.cron.dto.getui; + +import cn.hutool.crypto.SecureUtil; +import cn.hutool.http.ContentType; +import cn.hutool.http.Header; +import cn.hutool.http.HttpRequest; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 请求token时的参数 + * @author 3y + * https://docs.getui.com/getui/server/rest_v2/token/ + */ +@NoArgsConstructor +@Data +@Builder +@AllArgsConstructor +public class QueryTokenParamDTO { + /** + * sign + */ + @JSONField(name = "sign") + private String sign; + /** + * timestamp + */ + @JSONField(name = "timestamp") + private String timestamp; + /** + * appkey + */ + @JSONField(name = "appkey") + private String appKey; +} diff --git a/austin-cron/src/main/java/com/java3y/austin/cron/handler/RefreshGeTuiAccessTokenHandler.java b/austin-cron/src/main/java/com/java3y/austin/cron/handler/RefreshGeTuiAccessTokenHandler.java new file mode 100644 index 0000000..e1f6ab6 --- /dev/null +++ b/austin-cron/src/main/java/com/java3y/austin/cron/handler/RefreshGeTuiAccessTokenHandler.java @@ -0,0 +1,91 @@ +package com.java3y.austin.cron.handler; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.http.ContentType; +import cn.hutool.http.Header; +import cn.hutool.http.HttpRequest; +import com.alibaba.fastjson.JSON; +import com.google.common.base.Throwables; +import com.java3y.austin.common.constant.SendAccountConstant; +import com.java3y.austin.common.dto.account.GeTuiAccount; +import com.java3y.austin.cron.dto.getui.QueryTokenParamDTO; +import com.java3y.austin.cron.dto.getui.GeTuiTokenResultDTO; +import com.java3y.austin.support.config.SupportThreadPoolConfig; +import com.java3y.austin.support.utils.AccountUtils; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + + +/** + * 刷新个推的token + *
+ * https://docs.getui.com/getui/server/rest_v2/token/
+ *
+ * @author 3y
+ */
+@Service
+@Slf4j
+public class RefreshGeTuiAccessTokenHandler {
+
+ @Autowired
+ private StringRedisTemplate redisTemplate;
+
+ @Autowired
+ private AccountUtils accountUtils;
+
+ /**
+ * 每小时请求一次接口刷新(以防失效)
+ */
+ @XxlJob("refreshGeTuiAccessTokenJob")
+ public void execute() {
+ log.info("refreshGeTuiAccessTokenJob#execute!");
+ SupportThreadPoolConfig.getPendingSingleThreadPool().execute(() -> {
+ for (int index = SendAccountConstant.START; true; index = index + SendAccountConstant.STEP) {
+ GeTuiAccount account = accountUtils.getAccount(index, SendAccountConstant.GE_TUI_ACCOUNT_KEY, SendAccountConstant.GE_TUI_ACCOUNT_PREFIX, new GeTuiAccount());
+ if (account == null) {
+ break;
+ }
+ String accessToken = getAccessToken(account);
+ if (StrUtil.isNotBlank(accessToken)) {
+ redisTemplate.opsForValue().set(SendAccountConstant.GE_TUI_ACCESS_TOKEN_PREFIX + index, accessToken);
+ }
+ }
+ });
+ }
+
+ /**
+ * 获取 access_token
+ *
+ * @param account
+ * @return
+ */
+ private String getAccessToken(GeTuiAccount account) {
+ String accessToken = "";
+ try {
+ String url = "https://restapi.getui.com/v2/" + account.getAppId() + "/auth";
+ String time = String.valueOf(System.currentTimeMillis());
+ String digest = SecureUtil.sha256().digestHex(account.getAppKey() + time + account.getMasterSecret());
+ QueryTokenParamDTO param = QueryTokenParamDTO.builder()
+ .timestamp(time)
+ .appKey(account.getAppKey())
+ .sign(digest).build();
+
+ String body = HttpRequest.post(url).header(Header.CONTENT_TYPE.getValue(), ContentType.JSON.getValue())
+ .body(JSON.toJSONString(param))
+ .timeout(20000)
+ .execute().body();
+ GeTuiTokenResultDTO geTuiTokenResultDTO = JSON.parseObject(body, GeTuiTokenResultDTO.class);
+ if (geTuiTokenResultDTO.getCode().equals(0)) {
+ accessToken = geTuiTokenResultDTO.getData().getToken();
+ }
+ } catch (Exception e) {
+ log.error("RefreshGeTuiAccessTokenHandler#getAccessToken fail:{}", Throwables.getStackTraceAsString(e));
+ }
+ return accessToken;
+ }
+
+}
diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/getui/SendPushParam.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/getui/SendPushParam.java
new file mode 100644
index 0000000..f0a035e
--- /dev/null
+++ b/austin-handler/src/main/java/com/java3y/austin/handler/domain/getui/SendPushParam.java
@@ -0,0 +1,115 @@
+package com.java3y.austin.handler.domain.getui;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 推送消息的param
+ * @author 3y
+ * https://docs.getui.com/getui/server/rest_v2/push/
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+@Builder
+public class SendPushParam {
+
+ /**
+ * requestId
+ */
+ @JSONField(name = "request_id")
+ private String requestId;
+ /**
+ * settings
+ */
+ @JSONField(name = "settings")
+ private SettingsVO settings;
+ /**
+ * audience
+ */
+ @JSONField(name = "audience")
+ private AudienceVO audience;
+ /**
+ * pushMessage
+ */
+ @JSONField(name = "push_message")
+ private PushMessageVO pushMessage;
+
+ /**
+ * SettingsVO
+ */
+ @NoArgsConstructor
+ @Data
+ public static class SettingsVO {
+ /**
+ * ttl
+ */
+ @JSONField(name = "ttl")
+ private Integer ttl;
+ }
+
+ /**
+ * AudienceVO
+ */
+ @NoArgsConstructor
+ @Data
+ @AllArgsConstructor
+ @Builder
+ public static class AudienceVO {
+ /**
+ * cid
+ */
+ @JSONField(name = "cid")
+ private List