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