first comit
This commit is contained in:
commit
5d03218cd9
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
*.toml
|
35
app.js
Executable file
35
app.js
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
const schedule = require('node-schedule')
|
||||||
|
const { request } = require('./js/request')
|
||||||
|
const { getNowTime, configPaths, getConfig, isExpire } = require('./js/tools')
|
||||||
|
const { login } = require('./js/login')
|
||||||
|
|
||||||
|
const checkin = async () => {
|
||||||
|
// 遍历配置文件
|
||||||
|
const paths = await configPaths()
|
||||||
|
for (const path of paths) {
|
||||||
|
// 读取配置文件, 并转成对象
|
||||||
|
const config = await getConfig(path)
|
||||||
|
// 判断是否过期
|
||||||
|
if (isExpire(config)) {
|
||||||
|
const newCnfig = await login(config)
|
||||||
|
await request(newCnfig.checkinUrl, newCnfig.headers)
|
||||||
|
} else {
|
||||||
|
await request(config.checkinUrl, config.headers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('全部签到完成!')
|
||||||
|
}
|
||||||
|
|
||||||
|
const main = () => {
|
||||||
|
// 定时任务
|
||||||
|
schedule.scheduleJob('0 0 7 * * *', () => {
|
||||||
|
// 随机10分钟
|
||||||
|
setTimeout(() => {
|
||||||
|
checkin()
|
||||||
|
}, Math.random() * 10 * 60 * 1000)
|
||||||
|
})
|
||||||
|
// .invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`开始执行任务-${getNowTime()}`)
|
||||||
|
main()
|
19
config/test.toml.example
Normal file
19
config/test.toml.example
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
fileName = "test"
|
||||||
|
loginUrl = "https://test/auth/login"
|
||||||
|
checkinUrl = "https://test/user/checkin"
|
||||||
|
email = "xxx@gmail.com"
|
||||||
|
password = "xxx"
|
||||||
|
expire_in = "xxx"
|
||||||
|
|
||||||
|
[headers]
|
||||||
|
Cookie = "uid=xxx; email=xxx%40gmail.com; key=xxx; ip=xxx; expire_in=xxx"
|
||||||
|
Host = "test"
|
||||||
|
Origin = "https://test"
|
||||||
|
Referer = "https://test/user"
|
||||||
|
sec-ch-ua = '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"'
|
||||||
|
sec-ch-ua-platform = "macOS"
|
||||||
|
User-Agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"
|
||||||
|
expire_in = "xxx"
|
||||||
|
Accept = "*/*"
|
||||||
|
Accept-Encoding = "gzip, deflate, br"
|
||||||
|
Connection = "keep-alive"
|
72
js/login.js
Normal file
72
js/login.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
const axios = require('axios')
|
||||||
|
const qs = require('qs')
|
||||||
|
const cookie = require('cookie')
|
||||||
|
const fs = require('node:fs/promises')
|
||||||
|
const path = require('node:path')
|
||||||
|
const toml = require('@iarna/toml')
|
||||||
|
|
||||||
|
// 登录成功后, 更新config文件, 同时返回新的config对象
|
||||||
|
const login = async oldConfig => {
|
||||||
|
console.log('登录过期, 重新登录中...')
|
||||||
|
const { loginUrl, email, password } = oldConfig
|
||||||
|
const data = qs.stringify({ email, passwd: password })
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
'sec-ch-ua': oldConfig.headers['sec-ch-ua'],
|
||||||
|
'sec-ch-ua-platform': oldConfig.headers['sec-ch-ua-platform'],
|
||||||
|
'User-Agent': oldConfig.headers['User-Agent'],
|
||||||
|
}
|
||||||
|
let res
|
||||||
|
res = await axios({
|
||||||
|
url: loginUrl,
|
||||||
|
method: 'post',
|
||||||
|
headers,
|
||||||
|
data,
|
||||||
|
maxRedirects: 0,
|
||||||
|
timeout: 10000,
|
||||||
|
})
|
||||||
|
console.log('res', res)
|
||||||
|
if (res.status == 200) {
|
||||||
|
console.log('res.data.msg', res.data.msg)
|
||||||
|
let cookieObj = {}
|
||||||
|
const setCookie = res.headers['set-cookie'] // array
|
||||||
|
setCookie.forEach(item => {
|
||||||
|
cookieObj = Object.assign(cookieObj, cookie.parse(item))
|
||||||
|
})
|
||||||
|
const cookieStr = qs.stringify(
|
||||||
|
{
|
||||||
|
lang: 'zh-cn',
|
||||||
|
udi: cookieObj.uid,
|
||||||
|
email: cookieObj.email,
|
||||||
|
key: cookieObj.key,
|
||||||
|
ip: cookieObj.ip,
|
||||||
|
expire_in: cookieObj['expire_in'],
|
||||||
|
},
|
||||||
|
{ delimiter: '; ' }
|
||||||
|
)
|
||||||
|
const newConfig = JSON.parse(JSON.stringify(oldConfig))
|
||||||
|
newConfig.headers.Cookie = cookieStr
|
||||||
|
newConfig['expire_in'] = cookieObj['expire_in']
|
||||||
|
// 如果 headers里还有expire_in, 也要更新
|
||||||
|
if (newConfig.headers.expire_in) {
|
||||||
|
newConfig.headers['expire_in'] = cookieObj['expire_in']
|
||||||
|
}
|
||||||
|
console.log('newConfig', newConfig)
|
||||||
|
updateConfig(newConfig) // 异步更新
|
||||||
|
return newConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新config文件
|
||||||
|
const updateConfig = async newConfig => {
|
||||||
|
const filePath = path.resolve(
|
||||||
|
__dirname,
|
||||||
|
'../config',
|
||||||
|
newConfig.fileName + (newConfig.fileName.endsWith('.toml') ? '' : '.toml')
|
||||||
|
)
|
||||||
|
console.log('filePath', filePath)
|
||||||
|
await fs.writeFile(filePath, toml.stringify(newConfig), 'utf8')
|
||||||
|
console.log(`更新 ${newConfig.fileName} 文件成功`)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { login }
|
27
js/request.js
Normal file
27
js/request.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const axios = require('axios')
|
||||||
|
const { getNowTime } = require('./tools')
|
||||||
|
|
||||||
|
const request = async (url, headers) => {
|
||||||
|
console.log(`\n\n------${getNowTime()} - ${url}:开始签到------\n`)
|
||||||
|
try {
|
||||||
|
const res = await axios({
|
||||||
|
url,
|
||||||
|
method: 'post',
|
||||||
|
headers,
|
||||||
|
timeout: 10000,
|
||||||
|
})
|
||||||
|
if (res?.data?.ret === 0) {
|
||||||
|
console.log(`------ ${getNowTime()} 签到成功 ------\n`)
|
||||||
|
console.log(res.data.msg)
|
||||||
|
} else {
|
||||||
|
console.log(`------ ${getNowTime()} 签到失败 ------\n`)
|
||||||
|
console.log(JSON.stringify(res))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error?.message)
|
||||||
|
} finally{
|
||||||
|
return new Promise(resolve => resolve())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { request }
|
48
js/tools.js
Normal file
48
js/tools.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
const fs = require('node:fs/promises')
|
||||||
|
const path = require('node:path')
|
||||||
|
const TOML = require('@iarna/toml')
|
||||||
|
|
||||||
|
const getNowTime = () => {
|
||||||
|
return new Date()['toLocaleDateString']()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听文件变化
|
||||||
|
|
||||||
|
// 遍历配置文件目录下有多少个配置文件, 返回数组
|
||||||
|
const configPaths = async () => {
|
||||||
|
try {
|
||||||
|
let list = []
|
||||||
|
const files = await fs.readdir(path.resolve(__dirname, '../config'))
|
||||||
|
files.forEach(file => {
|
||||||
|
if (file.endsWith('.toml')) {
|
||||||
|
list.push(path.join(__dirname, '../config', file))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return list
|
||||||
|
} catch (error) {
|
||||||
|
console.log('遍历配置文件失败:\n', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步读取toml文件并返回对象
|
||||||
|
const getConfig = async path => {
|
||||||
|
try {
|
||||||
|
const tomlData = await fs.readFile(path, 'utf8')
|
||||||
|
const parsedData = TOML.parse(tomlData)
|
||||||
|
return parsedData
|
||||||
|
} catch (err) {
|
||||||
|
console.log('读取toml失败:\n', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否登录过期
|
||||||
|
const isExpire = config => {
|
||||||
|
const now = Math.floor(Date.now() / 1000)
|
||||||
|
if (+config.expire_in < now) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports= {isExpire, configPaths, getConfig, getNowTime}
|
19
package.json
Normal file
19
package.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "autoCheckin",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node ./app.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@iarna/toml": "^2.2.5",
|
||||||
|
"axios": "^1.3.4",
|
||||||
|
"cookie": "^0.5.0",
|
||||||
|
"node-schedule": "^2.1.1",
|
||||||
|
"qs": "^6.11.1"
|
||||||
|
}
|
||||||
|
}
|
166
pnpm-lock.yaml
Normal file
166
pnpm-lock.yaml
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
lockfileVersion: 5.4
|
||||||
|
|
||||||
|
specifiers:
|
||||||
|
'@iarna/toml': ^2.2.5
|
||||||
|
axios: ^1.3.4
|
||||||
|
cookie: ^0.5.0
|
||||||
|
node-schedule: ^2.1.1
|
||||||
|
qs: ^6.11.1
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
'@iarna/toml': 2.2.5
|
||||||
|
axios: 1.3.4
|
||||||
|
cookie: 0.5.0
|
||||||
|
node-schedule: 2.1.1
|
||||||
|
qs: 6.11.1
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
/@iarna/toml/2.2.5:
|
||||||
|
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/asynckit/0.4.0:
|
||||||
|
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/axios/1.3.4:
|
||||||
|
resolution: {integrity: sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==}
|
||||||
|
dependencies:
|
||||||
|
follow-redirects: 1.15.2
|
||||||
|
form-data: 4.0.0
|
||||||
|
proxy-from-env: 1.1.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- debug
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/call-bind/1.0.2:
|
||||||
|
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
|
||||||
|
dependencies:
|
||||||
|
function-bind: 1.1.1
|
||||||
|
get-intrinsic: 1.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/combined-stream/1.0.8:
|
||||||
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
|
engines: {node: '>= 0.8'}
|
||||||
|
dependencies:
|
||||||
|
delayed-stream: 1.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/cookie/0.5.0:
|
||||||
|
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/cron-parser/4.8.1:
|
||||||
|
resolution: {integrity: sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==}
|
||||||
|
engines: {node: '>=12.0.0'}
|
||||||
|
dependencies:
|
||||||
|
luxon: 3.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/delayed-stream/1.0.0:
|
||||||
|
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/follow-redirects/1.15.2:
|
||||||
|
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
||||||
|
engines: {node: '>=4.0'}
|
||||||
|
peerDependencies:
|
||||||
|
debug: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
debug:
|
||||||
|
optional: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/form-data/4.0.0:
|
||||||
|
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
dependencies:
|
||||||
|
asynckit: 0.4.0
|
||||||
|
combined-stream: 1.0.8
|
||||||
|
mime-types: 2.1.35
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/function-bind/1.1.1:
|
||||||
|
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/get-intrinsic/1.2.0:
|
||||||
|
resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==}
|
||||||
|
dependencies:
|
||||||
|
function-bind: 1.1.1
|
||||||
|
has: 1.0.3
|
||||||
|
has-symbols: 1.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/has-symbols/1.0.3:
|
||||||
|
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/has/1.0.3:
|
||||||
|
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
|
||||||
|
engines: {node: '>= 0.4.0'}
|
||||||
|
dependencies:
|
||||||
|
function-bind: 1.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/long-timeout/0.1.1:
|
||||||
|
resolution: {integrity: sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/luxon/3.3.0:
|
||||||
|
resolution: {integrity: sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/mime-db/1.52.0:
|
||||||
|
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/mime-types/2.1.35:
|
||||||
|
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
dependencies:
|
||||||
|
mime-db: 1.52.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/node-schedule/2.1.1:
|
||||||
|
resolution: {integrity: sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
cron-parser: 4.8.1
|
||||||
|
long-timeout: 0.1.1
|
||||||
|
sorted-array-functions: 1.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/object-inspect/1.12.3:
|
||||||
|
resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/proxy-from-env/1.1.0:
|
||||||
|
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/qs/6.11.1:
|
||||||
|
resolution: {integrity: sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==}
|
||||||
|
engines: {node: '>=0.6'}
|
||||||
|
dependencies:
|
||||||
|
side-channel: 1.0.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/side-channel/1.0.4:
|
||||||
|
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.2
|
||||||
|
get-intrinsic: 1.2.0
|
||||||
|
object-inspect: 1.12.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/sorted-array-functions/1.3.0:
|
||||||
|
resolution: {integrity: sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==}
|
||||||
|
dev: false
|
Loading…
Reference in New Issue
Block a user