diff --git a/.github/workflows/enshan.yml b/.github/workflows/enshan.yml new file mode 100644 index 0000000..3ae0496 --- /dev/null +++ b/.github/workflows/enshan.yml @@ -0,0 +1,21 @@ +name: enshan +on: + workflow_dispatch: + # push: + schedule: + - cron: 40 16 * * * +jobs: + run: + runs-on: ubuntu-latest + timeout-minutes: 50 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm run install + - run: npm run enshan + env: + ENSHAN_COOKIE: ${{ secrets.ENSHAN_COOKIE }} + DINGTALK_WEBHOOK: ${{ secrets.DINGTALK_WEBHOOK }} + DINGTALK_SECRET: ${{ secrets.DINGTALK_SECRET }} \ No newline at end of file diff --git a/.github/workflows/passnat.yml b/.github/workflows/passnat.yml new file mode 100644 index 0000000..faa4d98 --- /dev/null +++ b/.github/workflows/passnat.yml @@ -0,0 +1,22 @@ +name: passnat +on: + workflow_dispatch: + # push: + schedule: + - cron: 30 16 * * * +jobs: + run: + runs-on: ubuntu-latest + timeout-minutes: 50 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm run install + - run: npm run passnat + env: + PASSNAT_PHONE: ${{ secrets.PASSNAT_PHONE }} + PASSNAT_PASSWORD: ${{ secrets.PASSNAT_PASSWORD }} + DINGTALK_WEBHOOK: ${{ secrets.DINGTALK_WEBHOOK }} + DINGTALK_SECRET: ${{ secrets.DINGTALK_SECRET }} \ No newline at end of file diff --git a/.github/workflows/run.yml b/.github/workflows/run.yml new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10a2cf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# 忽略 sow.html 文件 +sow.html \ No newline at end of file diff --git a/enshan.js b/enshan.js new file mode 100644 index 0000000..a7307aa --- /dev/null +++ b/enshan.js @@ -0,0 +1,54 @@ +import { check_in } from "./utils/enshan_api.js"; +import { delay } from "./utils/utils.js"; +import DingTalkNotifier from "./utils/dingtalk.js"; +async function passnat() { + const cookie = process.env.ENSHAN_COOKIE + + // 获取钉钉webhook地址和密钥(从环境变量中获取) + const dingtalkWebhook = process.env.DINGTALK_WEBHOOK + const dingtalkSecret = process.env.DINGTALK_SECRET + // 创建钉钉通知实例(仅在配置了webhook时创建) + const dingtalkNotifier = dingtalkWebhook ? new DingTalkNotifier(dingtalkWebhook, dingtalkSecret) : null; + + + + const headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0', + 'Connection' : 'keep-alive', + 'Host' : 'www.right.com.cn', + 'Upgrade-Insecure-Requests' : '1', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'Accept-Language' : 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', + 'Accept-Encoding' : 'gzip, deflate, br', + 'Cookie': cookie + } + + // 先登录 + + let res = await check_in(headers) + console.log(res) + // // 如果登录成功,执行签到 + // if (res.code === 10000) { + // console.log("登录成功") + // await delay(5 * 1000) + // const auth_token = res.data.auth_token + // // 设置token到环境变量或请求头中 + // const checkin = await get("/user/checkIn", { "authorization": 'Bearer ' + auth_token}) + // console.log(checkin) + + // }else { + // console.log("登录失败") + // if (dingtalkNotifier) { + // try { + // await dingtalkNotifier.sendWithTitle( + // "注意!", + // "passnat登陆失败!" + // ); + // } catch (notifyError) { + // console.error("钉钉通知发送失败:", notifyError); + // } + // } + // } +} + +passnat() \ No newline at end of file diff --git a/main.js b/main.js index d69eff6..d573d81 100644 --- a/main.js +++ b/main.js @@ -1,5 +1,6 @@ import { printBlue, printGreen, printMagenta, printRed, printYellow } from "./utils/colorOut.js"; import { close_api, delay, send, startService } from "./utils/utils.js"; +import DingTalkNotifier from "./utils/dingtalk.js"; async function main() { @@ -99,4 +100,3 @@ async function main() { } main() - diff --git a/package.json b/package.json index da8c6cd..2dfc70a 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "apiService": "cd api && npm run start", "phoneLogin": "node phoneLogin.js", "sent": "node sent.js", + "passnat": "node passnat.js", "qrcodeLogin": "node qrcodeLogin.js" } } diff --git a/passnat.js b/passnat.js new file mode 100644 index 0000000..9c0331e --- /dev/null +++ b/passnat.js @@ -0,0 +1,42 @@ +import { post, get } from "./utils/passnat_api.js"; +import { delay } from "./utils/utils.js"; +import DingTalkNotifier from "./utils/dingtalk.js"; +async function passnat() { + const phone = process.env.PASSNAT_PHONE + const password = process.env.PASSNAT_PASSWORD + // 获取钉钉webhook地址和密钥(从环境变量中获取) + const dingtalkWebhook = process.env.DINGTALK_WEBHOOK + const dingtalkSecret = process.env.DINGTALK_SECRET + + // 创建钉钉通知实例(仅在配置了webhook时创建) + const dingtalkNotifier = dingtalkWebhook ? new DingTalkNotifier(dingtalkWebhook, dingtalkSecret) : null; + + // 先登录 + const res = await post("/public/login", { "password": password, "phone_number": phone, "platform": 1 }) + + + // // 如果登录成功,执行签到 + if (res.code === 10000) { + console.log("登录成功") + await delay(5 * 1000) + const auth_token = res.data.auth_token + // 设置token到环境变量或请求头中 + const checkin = await get("/user/checkIn", { "authorization": 'Bearer ' + auth_token}) + console.log(checkin) + + }else { + console.log("登录失败") + if (dingtalkNotifier) { + try { + await dingtalkNotifier.sendWithTitle( + "注意!", + "passnat登陆失败!" + ); + } catch (notifyError) { + console.error("钉钉通知发送失败:", notifyError); + } + } + } +} + +passnat() \ No newline at end of file diff --git a/utils/dingtalk.js b/utils/dingtalk.js new file mode 100644 index 0000000..4250587 --- /dev/null +++ b/utils/dingtalk.js @@ -0,0 +1,93 @@ +import crypto from 'crypto'; + +/** + * 钉钉通知类 + * 用于发送钉钉机器人消息 + */ +class DingTalkNotifier { + /** + * 构造函数 + * @param {string} webhookUrl - 钉钉机器人的webhook地址 + * @param {string} secret - 钉钉机器人的加签密钥 + */ + constructor(webhookUrl, secret) { + this.webhookUrl = webhookUrl; + this.secret = secret; + } + + /** + * 生成签名(Node.js环境兼容版本) + * @param {number} timestamp - 时间戳 + * @returns {string} 签名 + */ + generateSign(timestamp) { + if (!this.secret) { + return ''; + } + + const stringToSign = timestamp + '\n' + this.secret; + const sign = crypto.createHmac('sha256', this.secret) + .update(stringToSign, 'utf8') + .digest('base64'); + return encodeURIComponent(sign); + } + + /** + * 发送文本消息 + * @param {string} content - 消息内容 + * @returns {Promise} 响应结果 + */ + async sendText(content) { + if (!this.webhookUrl) { + console.warn('钉钉webhook地址未配置,跳过消息发送'); + return; + } + + const timestamp = Date.now(); + let url = this.webhookUrl + '×tamp=' + timestamp; + + // 如果配置了密钥,则添加签名 + if (this.secret) { + const sign = this.generateSign(timestamp); + if (sign) { + url += '&sign=' + sign; + } + } + + const message = { + msgtype: 'text', + text: { + content: content + } + }; + + try { + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(message) + }); + + const result = await response.json(); + return result; + } catch (error) { + console.error('钉钉消息发送失败:', error); + throw new Error('钉钉消息发送失败: ' + error.message); + } + } + + /** + * 发送带标题和内容的消息 + * @param {string} title - 标题 + * @param {string} content - 内容 + * @returns {Promise} 响应结果 + */ + async sendWithTitle(title, content) { + const fullContent = `${title}\n\n${content}`; + return await this.sendText(fullContent); + } +} + +export default DingTalkNotifier; \ No newline at end of file diff --git a/utils/enshan_api.js b/utils/enshan_api.js new file mode 100644 index 0000000..18de116 --- /dev/null +++ b/utils/enshan_api.js @@ -0,0 +1,14 @@ + +// 发送请求 +async function check_in(headers) { + const result = await fetch("https://www.right.com.cn/forum/home.php?mod=spacecp&ac=credit&op=log&suboperation=creditrulelog", { + method: "GET", + headers: headers + }).then(r => r.text) + // console.log(result) + return result +} + + + +export { check_in } diff --git a/utils/passnat_api.js b/utils/passnat_api.js new file mode 100644 index 0000000..9761173 --- /dev/null +++ b/utils/passnat_api.js @@ -0,0 +1,24 @@ + +// 发送请求 +async function get(path, headers) { + const result = await fetch("https://api.passnat.com" + path, { + method: "GET", + headers: headers + }).then(r => r.json()) + // console.log(result) + return result +} + + +async function post(path, body) { + const result = await fetch("https://api.passnat.com" + path, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(body) + }).then(r => r.json()) + return result +} + +export { get, post } diff --git a/utils/utils.js b/utils/utils.js index 97e1e88..672c7ff 100644 --- a/utils/utils.js +++ b/utils/utils.js @@ -41,4 +41,4 @@ async function send(path, method, headers) { return result } -export { delay, startService, close_api, send } +export { delay, startService, close_api, send } \ No newline at end of file