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 cid; + } + + /** + * PushMessageVO + */ + @NoArgsConstructor + @Data + @AllArgsConstructor + @Builder + public static class PushMessageVO { + /** + * notification + */ + @JSONField(name = "notification") + private NotificationVO notification; + + /** + * NotificationVO + */ + @NoArgsConstructor + @Data + @AllArgsConstructor + @Builder + public static class NotificationVO { + /** + * title + */ + @JSONField(name = "title") + private String title; + /** + * body + */ + @JSONField(name = "body") + private String body; + /** + * clickType + */ + @JSONField(name = "click_type") + private String clickType; + /** + * url + */ + @JSONField(name = "url") + private String url; + } + } +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/getui/SendPushResult.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/getui/SendPushResult.java new file mode 100644 index 0000000..6a14fc6 --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/domain/getui/SendPushResult.java @@ -0,0 +1,38 @@ +package com.java3y.austin.handler.domain.getui; + + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 发送消息后的返回值 + * @author 3y + * https://docs.getui.com/getui/server/rest_v2/common_args/?id=doc-title-1 + */ +@Builder +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SendPushResult { + /** + * msg + */ + @JSONField(name = "msg") + private String msg; + /** + * code + */ + @JSONField(name = "code") + private Integer code; + /** + * data + */ + @JSONField(name = "data") + private JSONObject data; + +}