├── .idea
├── vcs.xml
├── .gitignore
├── encodings.xml
├── git_toolbox_prj.xml
├── misc.xml
├── compiler.xml
└── jarRepositories.xml
├── src
└── main
│ └── java
│ └── cloud
│ └── ohiyou
│ ├── vo
│ ├── CookieSignResult.java
│ └── SignResultVO.java
│ ├── utils
│ ├── HiFiNiEncryptUtil.java
│ ├── WeChatWorkUtils.java
│ └── DingTalkUtils.java
│ ├── ObsoleteCode.java
│ └── Main.java
├── .github
└── workflows
│ └── HiFiNi-Auto-CheckIn.yml
├── READMES
├── WeChatWorkRobotConfigInfo.md
└── DingTalkRobotConfigInfo.md
├── pom.xml
├── README.md
└── .gitignore
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
9 |
3 |
签到、推送、自动化工作流。
8 | 9 | ## 通知 10 | 11 | 🔈 支持设置多cookie 通过`&`分割,如:cookie1&cookie2(2024年3月29日17:57:46) 12 | 13 | 🔈 更新新的签到校验方式(2024年3月21日09:06:51) 14 | 15 | 🔈 对论坛新的签到校验方式进行适配(2024年3月18日19:37:13) 16 | 17 | 🔈 过renji验证 18 | 19 | 🔈 每天北京时间6.30执行签到任务(根据github当前时段的任务数量,可能会有延迟) 20 | 21 | ## 如何使用 22 | 23 | 1.[Fork 仓库](https://github.com/anduinnn/HiFiNi-Auto-CheckIn) 24 | 25 | 2.仓库 -> Settings -> Secrets -> New repository secret, 添加Secrets变量如下: 26 | 27 | | 变量名 | 信息 | 是否必须 | 28 | | ---------------- | ------------------------------------------- | -------- | 29 | | COOKIE | HiFiNi的cookie信息 | 是 | 30 | | SERVER_CHAN | [Service酱](https://sct.ftqq.com/)推送的key | 否 | 31 | | DINGTALK_WEBHOOK | 钉钉机器人推送的token | 否 | 32 | | WXWORK_WEBHOOK | 企业微信机器人推送的token | 否 | 33 | 34 | 3.启动工作流程 35 |  36 | 37 | 38 | 39 | ## 如何拉取最新代码? 40 | 41 | 在自己的仓库里找到此项目 42 |  43 | 44 | 45 | 46 | 47 | 48 | ## 获取HifiNiCookie 49 | 访问`https://www.hifini.com/` 50 | 首页`F12`打开调试工具,在请求标头中找到并复制cookie的值 51 |  52 | 53 | ## 获取Server酱的key(需要关注公众号) 54 | 访问 `https://sct.ftqq.com/` 55 |  56 | 57 | ## 配置钉钉机器人 58 | 点击查看[如何配置钉钉机器人?](READMES/DingTalkRobotConfigInfo.md) 59 | 60 | ## 配置企业微信机器人 61 | 点击查看[如何配置企业微信机器人?](READMES/WeChatWorkRobotConfigInfo.md) 62 | -------------------------------------------------------------------------------- /READMES/DingTalkRobotConfigInfo.md: -------------------------------------------------------------------------------- 1 | # 配置钉钉机器人推送 2 | `以下方法使用PC端为例` 3 | 1. 创建群聊 4 | 5 | 打开钉钉,页面右上角➕,发起群聊。 6 | 7 |  8 | 9 | 选择普通群,随便选两个人。(由于钉钉限制,必须选中额外的两个人,~~然后将他们踢出群聊就行,不然TA就能看到你的签到信息。~~💦) 10 | 11 |  12 |  13 | 14 | `群聊名称可以随便修改` 15 | 16 | 2. 添加机器人 17 | 18 | 点击右上角群设置。 19 | 20 |  21 | 22 | 点击机器人 23 | 24 |  25 | 26 | 点击添加机器人x2 27 | 28 |  29 |  30 | 31 | 选择自定义,点击添加 32 | 33 |  34 | 35 | 填写机器人名字(随便)、**安全设置关键词(必须有`HiFiNi`或者`HiFiNi签到`,也可以两个都添加)** --> 勾选同意免责条款 --> 点击完成 36 | 37 |  38 | 39 | 出现以下页面代表设置完成 40 | 41 |  42 | 43 | **❗❗❗复制Webhook❗❗❗** 44 | ``` 45 | 复制之后你会得到如下: 46 | https://oapi.dingtalk.com/robot/send?access_token=12345678910xxxxxxxxxx 47 | 48 | 我们不需要等号前面的信息,只需要等号后面的信息,如:`12345678910xxxxxxxxxx`,然后将这段数据设置到对应的环境变量中去。 49 | ``` 50 | 51 | 如果不小心将该窗口关闭,可以点击`群设置-->机器人-->选择刚刚添加的机器人`就可找到信息了,在这里面还可以设置关键词、对机器人改名、删除机器人等操作。 52 | 53 | 成功案例: 54 | 55 |  56 | 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Java template 2 | # 排除测试文件夹 3 | src/main/java/cloud/ohiyou/test 4 | 5 | # Compiled class file 6 | *.class 7 | 8 | # Log file 9 | *.log 10 | 11 | # BlueJ files 12 | *.ctxt 13 | 14 | # Mobile Tools for Java (J2ME) 15 | .mtj.tmp/ 16 | 17 | # Package Files # 18 | *.jar 19 | *.war 20 | *.nar 21 | *.ear 22 | *.zip 23 | *.tar.gz 24 | *.rar 25 | 26 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 27 | hs_err_pid* 28 | replay_pid* 29 | 30 | ### JetBrains template 31 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 32 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 33 | 34 | # User-specific stuff 35 | .idea/**/workspace.xml 36 | .idea/**/tasks.xml 37 | .idea/**/usage.statistics.xml 38 | .idea/**/dictionaries 39 | .idea/**/shelf 40 | 41 | # AWS User-specific 42 | .idea/**/aws.xml 43 | 44 | # Generated files 45 | .idea/**/contentModel.xml 46 | 47 | # Sensitive or high-churn files 48 | .idea/**/dataSources/ 49 | .idea/**/dataSources.ids 50 | .idea/**/dataSources.local.xml 51 | .idea/**/sqlDataSources.xml 52 | .idea/**/dynamic.xml 53 | .idea/**/uiDesigner.xml 54 | .idea/**/dbnavigator.xml 55 | 56 | # Gradle 57 | .idea/**/gradle.xml 58 | .idea/**/libraries 59 | 60 | # Gradle and Maven with auto-import 61 | # When using Gradle or Maven with auto-import, you should exclude module files, 62 | # since they will be recreated, and may cause churn. Uncomment if using 63 | # auto-import. 64 | # .idea/artifacts 65 | # .idea/compiler.xml 66 | # .idea/jarRepositories.xml 67 | # .idea/modules.xml 68 | # .idea/*.iml 69 | # .idea/modules 70 | # *.iml 71 | # *.ipr 72 | 73 | # CMake 74 | cmake-build-*/ 75 | 76 | # Mongo Explorer plugin 77 | .idea/**/mongoSettings.xml 78 | 79 | # File-based project format 80 | *.iws 81 | 82 | # IntelliJ 83 | out/ 84 | 85 | # mpeltonen/sbt-idea plugin 86 | .idea_modules/ 87 | 88 | # JIRA plugin 89 | atlassian-ide-plugin.xml 90 | 91 | # Cursive Clojure plugin 92 | .idea/replstate.xml 93 | 94 | # SonarLint plugin 95 | .idea/sonarlint/ 96 | 97 | # Crashlytics plugin (for Android Studio and IntelliJ) 98 | com_crashlytics_export_strings.xml 99 | crashlytics.properties 100 | crashlytics-build.properties 101 | fabric.properties 102 | 103 | # Editor-based Rest Client 104 | .idea/httpRequests 105 | 106 | # Android studio 3.1+ serialized cache file 107 | .idea/caches/build_file_checksums.ser 108 | 109 | -------------------------------------------------------------------------------- /src/main/java/cloud/ohiyou/utils/WeChatWorkUtils.java: -------------------------------------------------------------------------------- 1 | package cloud.ohiyou.utils; 2 | 3 | 4 | import com.alibaba.fastjson.JSON; 5 | import com.alibaba.fastjson.JSONObject; 6 | import com.dingtalk.api.request.OapiRobotSendRequest; 7 | import okhttp3.*; 8 | 9 | import java.io.IOException; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | /** 13 | * 企业微信工具箱 14 | * @Author 银垚@mtouyao 15 | * @Date&Time 2024/3/7 16:40 16 | */ 17 | public class WeChatWorkUtils { 18 | 19 | private static final OkHttpClient client = new OkHttpClient.Builder() 20 | .connectTimeout(30, TimeUnit.SECONDS) 21 | .readTimeout(30, TimeUnit.SECONDS) 22 | .writeTimeout(30, TimeUnit.SECONDS) 23 | .build(); 24 | /** 25 | * 企业微信工具箱 26 | * @Author 银垚@mtouyao 27 | * @Date&Time 2024/3/7 16:40 28 | * @param WXWorkRobotKey 微信的机器人应用的 key 的值 29 | * @param messageText 签到信息 30 | * @param msgType (必选其一)text/markdown 31 | */ 32 | public static void pushBotMessage(String WXWorkRobotKey, String messageTitle, String messageText, String msgType){ 33 | 34 | if (WXWorkRobotKey == null || "".equals(WXWorkRobotKey)) { 35 | System.out.println("WXWORK_WEBHOOK 环境变量未设置"); 36 | return; 37 | } 38 | if (msgType == null) {msgType="markdown";} 39 | // 构建参数 40 | String jsonBody = ""; 41 | switch (msgType) { 42 | // 企业微信发送类型详解官网: https://developer.work.weixin.qq.com/document/path/91770 43 | // 发送text消息 44 | case "text": 45 | jsonBody = "{\"msgtype\": \"text\",\"text\": {\"content\":\"HiFiNi签到消息通知:"+messageTitle+messageText+"\"}}"; 46 | //定义文本内容 47 | break; 48 | //发送markdown消息 49 | case "markdown": 50 | jsonBody = "{\"msgtype\": \"markdown\",\"markdown\": {\"content\":\"# HiFiNi签到消息通知 \n ## "+messageTitle+" \n"+messageText+"\"}}"; 51 | // 定义markdown内容 52 | break; 53 | 54 | // 发送image消息(图片) 55 | case "image": 56 | System.out.println("[企业微信机器人]暂未开通image类型消息!"); 57 | break; 58 | // 发送news消息(图文) 59 | case "news": 60 | System.out.println("[企业微信机器人]暂未开通news类型消息!"); 61 | break; 62 | // 发送file消息(文件) 63 | case "file": 64 | System.out.println("[企业微信机器人]暂未开通file类型消息!"); 65 | break; 66 | // 发送voice消息(语音) 67 | case "voice": 68 | System.out.println("[企业微信机器人]暂未开通voice类型消息!"); 69 | break; 70 | 71 | /** 未匹配 */ 72 | default: 73 | System.out.println("[企业微信机器人]消息类型未匹配!请检查调用pushBotMessage传递的msgType参数"); 74 | break; 75 | 76 | } 77 | 78 | // 设置请求body 79 | RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8")); 80 | 81 | // 设置请求信息 82 | Request request = new Request.Builder() 83 | .url("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key="+WXWorkRobotKey) 84 | .post(body) 85 | .build(); 86 | 87 | // 发送请求 88 | try (Response response = client.newCall(request).execute()) { 89 | System.out.println("企业微信机器人返回信息:"+response.body().string()); 90 | } catch (IOException e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/cloud/ohiyou/utils/DingTalkUtils.java: -------------------------------------------------------------------------------- 1 | package cloud.ohiyou.utils; 2 | import com.dingtalk.api.DefaultDingTalkClient; 3 | import com.dingtalk.api.DingTalkClient; 4 | import com.dingtalk.api.request.OapiRobotSendRequest; 5 | import com.dingtalk.api.response.OapiRobotSendResponse; 6 | import com.taobao.api.ApiException; 7 | import org.apache.commons.codec.binary.Base64; 8 | 9 | import javax.crypto.Mac; 10 | import javax.crypto.spec.SecretKeySpec; 11 | import java.io.UnsupportedEncodingException; 12 | import java.net.URLEncoder; 13 | import java.security.InvalidKeyException; 14 | import java.security.NoSuchAlgorithmException; 15 | import java.util.Arrays; 16 | 17 | /** 18 | * 钉钉工具箱 19 | * @Author 银垚@mtouyao 20 | * @Date&Time 2024/3/7 10:25 21 | */ 22 | public class DingTalkUtils { 23 | 24 | /** 25 | * 钉钉机器人 26 | * @Author 银垚@mtouyao 27 | * @Date&Time 2024/3/7 10:25 28 | * @param customRobotToken 你的机器人应用的 access_token 的值/your custom robot token 29 | * @param messageText 签到信息 30 | * @param userIDs (可选)用户的 userId 信息[仅限钉钉内部群使用]/you need @ group user's userId 31 | * @param msgType (必选其一)text/markdown 32 | */ 33 | public static void pushBotMessage(String customRobotToken, String messageTitle, String messageText, String userIDs, String msgType){ 34 | try { 35 | if (customRobotToken == null || "".equals(customRobotToken)) { 36 | System.out.println("DINGTALK_WEBHOOK 环境变量未设置"); 37 | return; 38 | } 39 | if (msgType == null) {msgType="markdown";} 40 | Long timestamp = System.currentTimeMillis(); 41 | // System.out.println(timestamp); // 时间戳 42 | String secret = "messageKey"; // 安全设置,加签密钥。 43 | String stringToSign = timestamp + "\n" + secret; 44 | Mac mac = Mac.getInstance("HmacSHA256"); 45 | mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256")); 46 | byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); 47 | String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)),"UTF-8"); 48 | // System.out.println(sign); // 签名 49 | 50 | //sign字段和timestamp字段必须拼接到请求URL上,否则会出现 310000 的错误信息 51 | DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/robot/send?sign="+sign+"×tamp="+timestamp); 52 | OapiRobotSendRequest req = new OapiRobotSendRequest(); 53 | 54 | switch (msgType) { 55 | // 钉钉发送类型详解官网: https://open.dingtalk.com/document/orgapp/custom-robot-access 56 | // 发送text消息 57 | case "text": 58 | //定义文本内容 59 | OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text(); 60 | text.setContent("HiFiNi签到信息:"+messageTitle+messageText); 61 | //设置消息类型 62 | req.setMsgtype("text"); 63 | req.setText(text); 64 | break; 65 | //发送markdown消息 66 | case "markdown": 67 | // 定义markdown内容 68 | OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown(); 69 | markdown.setTitle("HiFiNiBot消息通知"); 70 | markdown.setText("# HiFiNi签到消息通知 \n ## "+messageTitle+" \n"+messageText); 71 | req.setMsgtype("markdown"); 72 | req.setMarkdown(markdown); 73 | break; 74 | 75 | // 发送link消息 76 | case "link": 77 | System.out.println("[钉钉机器人]暂未开通link类型消息!"); 78 | break; 79 | // 发送ActionCard消息 80 | case "ActionCard": 81 | System.out.println("[钉钉机器人]暂未开通ActionCard类型消息!"); 82 | break; 83 | // 发送FeedCard消息 84 | case "FeedCard": 85 | System.out.println("[钉钉机器人]暂未开通FeedCard类型消息!"); 86 | break; 87 | 88 | /** 未匹配 */ 89 | default: 90 | System.out.println("[钉钉机器人]消息类型未匹配!请检查调用pushBotMessage传递的msgType参数"); 91 | break; 92 | 93 | } 94 | 95 | //定义 @ 对象 96 | OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); 97 | at.setAtUserIds(Arrays.asList(userIDs)); 98 | req.setAt(at); 99 | OapiRobotSendResponse rsp = client.execute(req, customRobotToken); 100 | System.out.println("钉钉机器人返回信息:"+rsp.getBody()); 101 | } catch (ApiException e) { 102 | e.printStackTrace(); 103 | } catch (UnsupportedEncodingException e) { 104 | throw new RuntimeException(e); 105 | } catch (NoSuchAlgorithmException e) { 106 | throw new RuntimeException(e); 107 | } catch (InvalidKeyException e) { 108 | throw new RuntimeException(e); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/cloud/ohiyou/ObsoleteCode.java: -------------------------------------------------------------------------------- 1 | //package cloud.ohiyou; 2 | // 3 | //import cloud.ohiyou.vo.SignResultVO; 4 | //import okhttp3.MediaType; 5 | //import okhttp3.Request; 6 | //import okhttp3.RequestBody; 7 | //import okhttp3.Response; 8 | // 9 | //import java.io.IOException; 10 | //import java.util.regex.Matcher; 11 | //import java.util.regex.Pattern; 12 | // 13 | ///** 14 | // * 废弃的代码,先保留,以后可能会用到 15 | // */ 16 | //public class ObsoleteCode { 17 | // private static final String COOKIE = ""; 18 | // 19 | // 20 | // /** 21 | // * 获取签到的signKey 22 | // * 23 | // * @param result 24 | // * @return 25 | // * @throws IOException 26 | // */ 27 | // private static String getSignKey(String result) throws IOException { 28 | // String baseUrl = "https://www.hifini.com"; 29 | // // 获取 src 后的地址 30 | // Pattern patternSrc = Pattern.compile("src=\"([^\"]+)\""); 31 | // Matcher matcherSrc = patternSrc.matcher(result); 32 | // if (matcherSrc.find()) { 33 | // baseUrl += matcherSrc.group(1); 34 | // 35 | // // 发送renji请求 36 | // Request request = new Request.Builder() 37 | // .url(baseUrl) 38 | // .addHeader("Cookie", COOKIE) 39 | // .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)") 40 | // .build(); 41 | // 42 | // try (Response response = client.newCall(request).execute()) { 43 | // if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 44 | // 45 | // // 定义正则表达式模式 46 | // Pattern pattern = Pattern.compile("/renji_[a-f0-9]+_([a-f0-9]+)\\.js"); 47 | // Matcher matcher = pattern.matcher(result); 48 | // if (matcher.find()) { 49 | // return matcher.group(1); 50 | // } else { 51 | // throw new RuntimeException("未能通过人机校验"); 52 | // } 53 | // } 54 | // } else { 55 | // throw new RuntimeException("未能通过人机校验"); 56 | // } 57 | // } 58 | // 59 | // /** 60 | // * 发送签到请求 61 | // * 62 | // * @param cookieValue 63 | // * @param attempt 64 | // * @param maxAttempts 65 | // * @return 66 | // * @throws IOException 67 | // * @throws InterruptedException 68 | // */ 69 | // private static SignResultVO sendSignInRequest(String cookieValue, int attempt, int maxAttempts) throws IOException, InterruptedException { 70 | // if (attempt > maxAttempts) { 71 | // System.out.println("已达到最大尝试次数。正在停止执行。"); 72 | // return null; 73 | // } 74 | // 75 | // System.out.println("尝试第" + attempt + "次;最大:" + maxAttempts + "次"); 76 | // 77 | // Request request = new Request.Builder() 78 | // .url("https://www.hifini.com/sg_sign.htm") 79 | // .post(RequestBody.create("", MediaType.get("application/json; charset=utf-8"))) 80 | // .addHeader("Cookie", cookieValue) 81 | // .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36") 82 | // .addHeader("X-Requested-With", "XMLHttpRequest") 83 | // .build(); 84 | // 85 | // try (Response response = client.newCall(request).execute()) { 86 | // if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 87 | // 88 | // String result = readResponse(response); 89 | // if (result.contains("正在进行人机识别")) { 90 | // System.out.println("遇到CAPTCHA,正在尝试绕过。"); 91 | // 92 | // String key = getSignKey(result); 93 | // String token = getRenjiToken(key); 94 | // cookieValue = formatCookie(cookieValue) + " " + token; 95 | // 96 | // Thread.sleep(2000); 97 | // return sendSignInRequest(cookieValue, attempt + 1, maxAttempts); 98 | // } 99 | // 100 | // return stringToObject(result, SignResultVO.class); 101 | // } 102 | // } 103 | // 104 | // 105 | // /** 106 | // * 发送签到请求,最大五次尝试 107 | // * 108 | // * @param cookieValue cookieValue 109 | // * @return 110 | // * @throws IOException 111 | // * @throws InterruptedException 112 | // */ 113 | // private static SignResultVO initialSendSignInRequest(String cookieValue) throws IOException, InterruptedException { 114 | // return sendSignInRequest(cookieValue, 1, 5); 115 | // } 116 | // 117 | // private static String getRenjiToken(String key) throws IOException { 118 | // // MD5加密的字符串:renji 119 | // String baseUrl = "https://www.hifini.com/a20be899_96a6_40b2_88ba_32f1f75f1552_yanzheng_ip.php"; 120 | // String type = "96c4e20a0e951f471d32dae103e83881"; 121 | // String value = "05bb5aba7f3f54a677997f862f1a9020"; 122 | // 123 | // // 构建最终的 124 | // String urlWithParams = String.format("%s?type=%s&key=%s&value=%s", baseUrl, type, key, value); 125 | // 126 | // Request request = new Request.Builder() 127 | // .url(urlWithParams) 128 | // .addHeader("Cookie", COOKIE) 129 | // .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36") 130 | // .build(); 131 | // 132 | // try (Response response = client.newCall(request).execute()) { 133 | // if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 134 | // String header = response.header("Set-Cookie"); 135 | // if (header != null) { 136 | // String[] split = header.split(";"); 137 | // return split[0]; 138 | // } else { 139 | // throw new RuntimeException("未能通过人机校验"); 140 | // } 141 | // } 142 | // } 143 | // 144 | //} 145 | -------------------------------------------------------------------------------- /src/main/java/cloud/ohiyou/Main.java: -------------------------------------------------------------------------------- 1 | package cloud.ohiyou; 2 | 3 | /** 4 | * @author ohiyou 5 | * @since 2024/3/1 14:19 6 | */ 7 | 8 | import cloud.ohiyou.utils.DingTalkUtils; 9 | import cloud.ohiyou.utils.WeChatWorkUtils; 10 | import cloud.ohiyou.vo.CookieSignResult; 11 | import cloud.ohiyou.vo.SignResultVO; 12 | import com.alibaba.fastjson.JSON; 13 | import okhttp3.*; 14 | 15 | import java.io.BufferedReader; 16 | import java.io.IOException; 17 | import java.io.InputStreamReader; 18 | import java.net.URLEncoder; 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import java.util.concurrent.*; 22 | import java.util.regex.Matcher; 23 | import java.util.regex.Pattern; 24 | 25 | public class Main { 26 | private static final String COOKIE = System.getenv("COOKIE"); 27 | // private static final String COOKIE = cloud.ohiyou.test.TestEnum.COOKIE.getValue(); 28 | private static final String DINGTALK_WEBHOOK = System.getenv("DINGTALK_WEBHOOK"); // 钉钉机器人 access_token 的值 29 | private static final String WXWORK_WEBHOOK = System.getenv("WXWORK_WEBHOOK"); // 企业微信机器人 key 的值 30 | private static final String SERVER_CHAN_KEY = System.getenv("SERVER_CHAN"); 31 | private static final OkHttpClient client = new OkHttpClient.Builder() 32 | .connectTimeout(30, TimeUnit.SECONDS) 33 | .readTimeout(30, TimeUnit.SECONDS) 34 | .writeTimeout(30, TimeUnit.SECONDS) 35 | .build(); 36 | 37 | public static void main(String[] args) { 38 | List