commit 0b1d447622247ca55532d6983beea26adc41744e Author: bmy <2271608011@qq.com> Date: Thu May 28 00:34:22 2026 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..04c01ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d7e9df5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM node:25-alpine + +RUN apk update && \ + apk add --no-cache chromium && \ + rm -rf /var/cache/apk/* + +WORKDIR /app + +COPY package*.json ./ +RUN npm config set registry https://repo.huaweicloud.com/repository/npm/ && \ + npm config set fetch-retries 3 && \ + npm install + +COPY . . + +ENV CHROME_PATH=/usr/bin/chromium +ENV NODE_ENV=production + +CMD ["npm", "run", "dev"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..402c38d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +https://tsx.hirok.io/watch-mode + +docker compose down && docker compose up -d --build \ No newline at end of file diff --git a/db.json b/db.json new file mode 100644 index 0000000..a8c746e --- /dev/null +++ b/db.json @@ -0,0 +1,6 @@ +{ + "setting": { + "count": "46", + "time": "2026/5/27 23:37:18" + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..14ca5fe --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +services: + dy-monitor: + build: . + container_name: dy-monitor + restart: always + environment: + # 每30秒重新运行一次检查,默认每天早上8点 + # - CRON=*/30 * * * * * + # 每30秒重新运行一次检查,默认每天早上8点 + # - CRON=*/30 * * * * * + # - DOUYIN_PAGE=抖音主播主页地址 + - PAGE_TIMEOUT=30000 + # Chrome 路径 + - CHROME_PATH=/usr/bin/chromium + + # 可选:覆盖邮箱、URL + # - MAIL_HOST=xxx@qq.com + # - MAIL_PORT=xxx@qq.com + # - MAIL_SECURE=xxx@qq.com + # - MAIL_USER=xxx + # - MAIL_PASS=xxx + + # # 持久化数据库文件 + # volumes: + # - ./db.json:/app/db.json \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2a66e2c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1003 @@ +{ + "name": "dy-not", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "dy-not", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "node-schedule": "^2.1.1", + "nodemailer": "^8.0.9" + }, + "devDependencies": { + "@types/node": "^25.9.1", + "@types/node-schedule": "^2.1.8", + "@types/nodemailer": "^8.0.0", + "lowdb": "^7.0.1", + "puppeteer-core": "^25.1.0", + "tsx": "^4.22.3", + "typescript": "^6.0.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.4.tgz", + "integrity": "sha512-HGM8iAmGTf+Y7t0373szVbTmt3d7vPkYL/1bpOkOFO0YUYLgSeuYBCzESklogNPvOBnZ/MRD5f07OkpqH1trtA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "modern-tar": "^0.7.6", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/main-cli.js" + }, + "engines": { + "node": ">=22.12.0" + }, + "peerDependencies": { + "proxy-agent": ">=8.0.1" + }, + "peerDependenciesMeta": { + "proxy-agent": { + "optional": true + } + } + }, + "node_modules/@types/node": { + "version": "25.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", + "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/node-schedule": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@types/node-schedule/-/node-schedule-2.1.8.tgz", + "integrity": "sha512-k00g6Yj/oUg/CDC+MeLHUzu0+OFxWbIqrFfDiLi6OPKxTujvpv29mHGM8GtKr7B+9Vv92FcK/8mRqi1DK5f3hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/nodemailer": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.0.tgz", + "integrity": "sha512-fyf8jWULsCo0d0BuoQ75i6IeoHs47qcqxWc7yUdUcV0pOZGjUTTOvwdG1PRXUDqN/8A64yQdQdnA2pZgcdi+cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chromium-bidi": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-16.0.1.tgz", + "integrity": "sha512-J63PGu/9PpeCwLIcKYyzWP6yaVL5pxuBc0shlYCYM8BaAkmlwiQboXO1iNbOgSDbVklEyYFfNEcHD8oOAWacUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mitt": "^3.0.1", + "zod": "^3.24.1" + }, + "engines": { + "node": ">=20.19.0 <22.0.0 || >=22.12.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1624250", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1624250.tgz", + "integrity": "sha512-YFAat/lOiIk0ARmBweG+ygrEcbZrq5B9urRyUoeQKp53MlidHXE2TmTbxKcaXoQj7u/aX+jebDO4BW55rs0WwA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/long-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==", + "license": "MIT" + }, + "node_modules/lowdb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-7.0.1.tgz", + "integrity": "sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==", + "dev": true, + "license": "MIT", + "dependencies": { + "steno": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, + "node_modules/modern-tar": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.6.tgz", + "integrity": "sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/node-schedule": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz", + "integrity": "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==", + "license": "MIT", + "dependencies": { + "cron-parser": "^4.2.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nodemailer": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.9.tgz", + "integrity": "sha512-5ofa7BUN8+C+Hckh5V2GjeeOGRQBx0CJQA6KxrvuZfC8iU4/q7sLn8XrtEEhJkjV6HdyIiQs7Bba6bTao8JhkA==", + "license": "MIT-0", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/puppeteer-core": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.1.0.tgz", + "integrity": "sha512-jKzy5y4WG6uNuFbTWgW1D7mqoT9o0nllc/6a1DGF775T1mPmgw3scdFEtEq67yVFikavQmbYq6NLfbTfxHSlqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "3.0.4", + "chromium-bidi": "16.0.1", + "devtools-protocol": "0.0.1624250", + "typed-query-selector": "^2.12.2", + "webdriver-bidi-protocol": "0.4.2", + "ws": "^8.21.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sorted-array-functions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", + "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==", + "license": "MIT" + }, + "node_modules/steno": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/steno/-/steno-4.0.2.tgz", + "integrity": "sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsx": { + "version": "4.22.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.3.tgz", + "integrity": "sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/typed-query-selector": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz", + "integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "dev": true, + "license": "MIT" + }, + "node_modules/webdriver-bidi-protocol": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.2.tgz", + "integrity": "sha512-VSV+fzfChirL3e7jay2yUC7B4HQCGtEWEg/MSSQbK+qWbqeGlRLlXTzPpYr3XGUvbpDHumWZBJxgesg4N7dbtA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8d3aca6 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "dy-not", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "tsx watch src/index.ts" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "@types/node": "^25.9.1", + "@types/node-schedule": "^2.1.8", + "@types/nodemailer": "^8.0.0", + "lowdb": "^7.0.1", + "puppeteer-core": "^25.1.0", + "tsx": "^4.22.3", + "typescript": "^6.0.3", + "node-schedule": "^2.1.1", + "nodemailer": "^8.0.9" + } +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..7d8b2bf --- /dev/null +++ b/src/config.ts @@ -0,0 +1,33 @@ +import * as process from 'process'; + +export default { + // 默认每天早上8点 + cron: process.env.CRON || '0 0 8 * * *', + // 抖音主页:环境变量可覆盖 + page: process.env.DOUYIN_PAGE || "https://www.douyin.com/user/MS4wLjABAAAABo4tTG931ViZ26MXkJZfEEzT8N4XEccUMdlXKqi2STTeaElZTpSyEddCgqHbJ8K9", + // 加载上面页面的等待时间,默认30秒 + pageTimeOut: process.env.PAGE_TIMEOUT || 30000, + // 浏览器配置(Docker 自动切换路径) + launchConfig: { + executablePath: process.env.CHROME_PATH || "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", + headless: true, // 设为 false 可看到浏览器窗口 + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage', + '--disable-gpu' + ] + }, + httpHeaders: { + 'cookie': 'enter_pc_once=1; UIFID_TEMP=ad3b4f3f15a567c9e310e1bce511e73b70473c6974ec0d30dd14ac972f2b42bdcd14fab4b0d0371c418f43e9c75ef618836849742441b7153b78a359359b121be680d966dd154fe8112d46363c4995b15945bf4d4ecca47e011ae4ce43bafb2008cc071ada54dbc49d08d1ccb0dc230d; s_v_web_id=verify_mojdr0fs_M1xDSwB3_Yefg_4tXG_8Mry_iZq0uCrHBCFk; hevc_supported=true; fpk1=U2FsdGVkX189U3M9zn6L0qCfKWqoz9Gxfely8YzUV9gnftJbsQQGC3FJWDinUjH6voY7QiPiy7hN5pp0VqtCbw==; fpk2=562dfcd5b68c64c48b5e26801777ec72; passport_csrf_token=7f6c42b91a77d8b20f029a63a8e0922c; passport_csrf_token_default=7f6c42b91a77d8b20f029a63a8e0922c; bd_ticket_guard_client_web_domain=2; passport_assist_user=CkGXPn1SeU1WZkcNwJsWSCLk9g69aIeFCe45m2Q3FSTMi7jUoYr4L_X40goHIkEAyfwi3cNNVg3glwQBurxWRKZT5BpKCjwAAAAAAAAAAAAAUFshLcZea1oR-bOBxF5aJhTdflLdipRcemmjfYjy1dlG3BmqUCq7xYMDQqXpVU6bNWcQl4mQDhiJr9ZUIAEiAQNTYE19; n_mh=JnGoU8D8B-xK1WRI45o6T_5OpHAszLRmEa6uYPXUkK0; uid_tt=b28cb5e6a3583ef5e38f0a82b9802403; uid_tt_ss=b28cb5e6a3583ef5e38f0a82b9802403; sid_tt=5ce3bf8850d71e863326084bb3e43538; sessionid=5ce3bf8850d71e863326084bb3e43538; sessionid_ss=5ce3bf8850d71e863326084bb3e43538; is_staff_user=false; has_biz_token=false; _bd_ticket_crypt_cookie=14d0afbb0a6f56e2fdcb1803658e48da; __security_server_data_status=1; login_time=1777426367344; UIFID=ad3b4f3f15a567c9e310e1bce511e73b70473c6974ec0d30dd14ac972f2b42bdcd14fab4b0d0371c418f43e9c75ef618836849742441b7153b78a359359b121b1af9ee141240af78559810da16c0d19f40f840f96e6c86430633d7da3fe1d71f33f472a22a634a6f32b15274aa32c39e4141f6bdd51ba6b2dd95205ad4559ed05a9e4febb4084e7f53009a83a6b0ecc9df7c925aebacd7c959507507b7d1a9c2f88f1b0c0f04c52f855be9f6a7c6f0e0dfbe6d0d859f3d7baf985a5bc4e501c4; SelfTabRedDotControl=%5B%5D; __druidClientInfo=JTdCJTIyY2xpZW50V2lkdGglMjIlM0E1NDklMkMlMjJjbGllbnRIZWlnaHQlMjIlM0E4NzYlMkMlMjJ3aWR0aCUyMiUzQTU0OSUyQyUyMmhlaWdodCUyMiUzQTg3NiUyQyUyMmRldmljZVBpeGVsUmF0aW8lMjIlM0ExJTJDJTIydXNlckFnZW50JTIyJTNBJTIyTW96aWxsYSUyRjUuMCUyMChNYWNpbnRvc2glM0IlMjBJbnRlbCUyME1hYyUyME9TJTIwWCUyMDEwXzE1XzcpJTIwQXBwbGVXZWJLaXQlMkY1MzcuMzYlMjAoS0hUTUwlMkMlMjBsaWtlJTIwR2Vja28pJTIwQ2hyb21lJTJGMTQ3LjAuMC4wJTIwU2FmYXJpJTJGNTM3LjM2JTIyJTdE; my_rd=2; __security_mc_1_s_sdk_crypt_sdk=5b0aaac5-4748-b594; __security_mc_1_s_sdk_cert_key=30322fd4-476f-b721; __security_mc_1_s_sdk_sign_data_key_web_protect=62470610-48fa-b2b7; SEARCH_RESULT_LIST_TYPE=%22single%22; douyin.com; device_web_cpu_core=6; device_web_memory_size=16; is_support_rtm_web_ts=1; is_dash_user=1; publish_badge_show_info=%220%2C0%2C0%2C1779247161279%22; volume_info=%7B%22isMute%22%3Afalse%2C%22isUserMute%22%3Afalse%2C%22volume%22%3A0.82%7D; sid_guard=5ce3bf8850d71e863326084bb3e43538%7C1779522953%7C5184000%7CWed%2C+22-Jul-2026+07%3A55%3A53+GMT; session_tlb_tag=sttt%7C17%7CXOO_iFDXHoYzJghLs-Q1OP_________cpwSeKY3iV2jpHMqtGuaYWqz7CA5ni4ShcLxubuK4dTU%3D; sid_ucp_v1=1.0.0-KDA2OTI1YTYzMGI2NzUwOGU3MDU5NGU1ZTU1NjI0NWNiOTI2M2ViZDYKIQjT9IDf2My9AhCJu8XQBhjvMSAMMPf-4rIGOAdA9AdIBBoCbHEiIDVjZTNiZjg4NTBkNzFlODYzMzI2MDg0YmIzZTQzNTM4; ssid_ucp_v1=1.0.0-KDA2OTI1YTYzMGI2NzUwOGU3MDU5NGU1ZTU1NjI0NWNiOTI2M2ViZDYKIQjT9IDf2My9AhCJu8XQBhjvMSAMMPf-4rIGOAdA9AdIBBoCbHEiIDVjZTNiZjg4NTBkNzFlODYzMzI2MDg0YmIzZTQzNTM4; __ac_nonce=06a15c1e1004efc21fa8e; __ac_signature=_02B4Z6wo00f01OfrVVQAAIDC1H6jFdV63wzny1HAAFP0a9; dy_swidth=2560; dy_sheight=1440; FOLLOW_NUMBER_YELLOW_POINT_INFO=%22MS4wLjABAAAARJAVrJ6pk0dTTarp4Nl92EDW6Ezd3K1IqIobdwGEQtpIagJglrZmanMZBWyxippq%2F1779811200000%2F1779810792099%2F1779810789922%2F0%22; playRecommendGuideTagCount=6; totalRecommendGuideTagCount=6; download_guide=%220%2F%2F1%22; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A2560%2C%5C%22screen_height%5C%22%3A1440%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A6%2C%5C%22device_memory%5C%22%3A16%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A50%7D%22; strategyABtestKey=%221779810843.495%22; ttwid=1%7CUns-G53qOEIXJ4BY75EZ8Y9ArgyKelHizMVJ2cTbqpc%7C1779810843%7C809d7108c030ecfaacb104858e0677367ed2b846ffa7cf51b76379f34d8f5af9; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCRm52RzBZZnU1aXI3NmtnQVJET0drWFNORVl4SFJhQUgxZTZQOUQ4bm5mNzhta0hNSzFWQ0MzR1haY1phWHpwTDArZkErK0xtZU1nSHdMVUsxZ1F3a3c9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; home_can_add_dy_2_desktop=%221%22; odin_tt=47bb700311cd15bb211a5fea9ea654f370e53a725d8f712bdf43ef034ac5e4cd5e5614fd396c7001fd7a7044d4113f51c590157e26f5514457ae6f30e3a70d9577952a9dfbb3d09f6de8518a9e516d54; biz_trace_id=1ee5193a; gulu_source_res=eyJwX2luIjoiOGNjNTVmMWNlMjRmYWNlYjQ4OWEzNGZlMjg3OTQ4ZWJlNzUyZTIyN2RjYzkwZjBmMjdiYzU0NDM0YmY0ZGJlMSJ9; bd_ticket_guard_client_data_v2=eyJyZWVfcHVibGljX2tleSI6IkJGbnZHMFlmdTVpcjc2a2dBUkRPR2tYU05FWXhIUmFBSDFlNlA5RDhubmY3OG1rSE1LMVZDQzNHWFpjWmFYenBMMCtmQSsrTG1lTWdId0xVSzFnUXdrdz0iLCJ0c19zaWduIjoidHMuMi5jMzA1MjdlMmIwYmQ0ZmJlMzAxZmJjMDdhYTRiMTBmOTk2ZDhmNzE3NjAzODU5Nzc2YzcxYTU0ODcwZmQ1ZWFiYzRmYmU4N2QyMzE5Y2YwNTMxODYyNGNlZGExNDkxMWNhNDA2ZGVkYmViZWRkYjJlMzBmY2U4ZDRmYTAyNTc1ZCIsInJlcV9jb250ZW50Ijoic2VjX3RzIiwicmVxX3NpZ24iOiJJNURvZFhobWVWL3FSWnp6TmloWE1wd2lyeHN3Wm5zaFYrUHBKSWNhNk1rPSIsInNlY190cyI6IiNiQ21PRGdzNXViTFUzQ1ZxWVliQWhTZ3U2NHhubXgwVnQ4U203cTN1WnMrWGF6eTFhZXRNN0IvV0pEazYifQ%3D%3D; sdk_source_info=7e276470716a68645a606960273f276364697660272927676c715a6d6069756077273f276364697660272927666d776a68605a607d71606b766c6a6b5a7666776c7571273f275e58272927666a6b766a69605a696c6061273f27636469766027292762696a6764695a7364776c6467696076273f275e582729277672715a646971273f2763646976602729277f6b5a666475273f2763646976602729276d6a6e5a6b6a716c273f2763646976602729276c6b6f5a7f6367273f27636469766027292771273f27313d3c36313c34343d3c323234272927676c715a75776a716a666a69273f2763646976602778; bit_env=1526bTD1CoiS-ar8g3QRBiyWw8Vr2A9u_ItZlX3KfgTEm2XVXl4OlbIN6Dz1A99I2YxU24QOTfWFBkdm7TByIXqlWqsoDer1W5qECkYqOIT1C9EmIC1n-rHbt3CspumMH2pAS_MIXqzACCx67xyFbigAkr6nqBG1s5DUao4MNgUYMSUsT6l_POd_QeIrrwC2rnpMCP3F8wu7jOtZuzP9n7ivtPyineTUW24DV9zPpvdVhgtsyWHXo6w8OnIxqXH9d5TFFXZwSVTXYSqZjTj8MSldQahlPKHllHmB34L3kYgvYNP6WqK_u9WcgXFt4FQok57PLbY7Mm3jRu226n6B2qbooxqz6-9RZOJde0Y4BYGhyOOqPK_qimJu0EZ3rVGJDyIMqb2LxsB429fo869lyXRrSNPYEAgXYODH-u9Kh_8NYymZ15ohOrsOG4vAU-cmGHYi19t4iqjk_d5VqB2vd93Pp31MbsjyAl7jqntNs4ooWQHUL5xPITgP7EraPS5y6JGmpWlh604rw9qhR6N3NKPpUy1-1tYCDXqf2LSsvcc%3D; passport_auth_mix_state=8nd1ikc8cniuxp4w5wqbqbpgx3psxjqca3gr8pndn2wpy5py; IsDouyinActive=true' + }, + mailer: { + host: process.env.MAIL_HOST || "smtp.qq.com", + port: parseInt(process.env.MAIL_PORT || '465'), + secure: (process.env.MAIL_SECURE || 'true') === 'true', + auth: { + user: process.env.MAIL_USER || "2271608011@qq.com", + pass: process.env.MAIL_PASS || "vpringrkzgbidjfj", + }, + } +} \ No newline at end of file diff --git a/src/db/index.ts b/src/db/index.ts new file mode 100644 index 0000000..7b26cf4 --- /dev/null +++ b/src/db/index.ts @@ -0,0 +1,42 @@ +import { JSONFilePreset, } from 'lowdb/node' +import { Low } from 'lowdb' + +// 定义数据结构:setting 是对象,不是数组 +type Data = { + setting: { + count: string | number; + time: string; + [key: string]: any; + }; +}; + +class DbJson { + private defaultData: Data = { + setting: { + count: 0, + time: '' + } + } + + db!: Low; + + constructor () { + this.init(); + } + + async init () { + this.db = await JSONFilePreset('db.json', this.defaultData) + } + + async set(params: Data['setting']) { + this.db.data.setting = params + await this.db.write() + } + + // 读取当前保存的 setting + async get() { + return this.db.data.setting; + } +} + +export default new DbJson \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6f69d0c --- /dev/null +++ b/src/index.ts @@ -0,0 +1,68 @@ +import puppeteer from 'puppeteer-core'; +import config from "./config"; +import db from "./db/index"; +import mailer from "./utils/mailer"; +import schedule from 'node-schedule'; + +// 把你的逻辑封装成函数 +async function startTask() { + console.log(''); + console.log('===================================='); + console.log('⏰ 定时任务开始执行:', new Date().toLocaleString()); + console.log('===================================='); + console.log(''); + + try { + // 1. 启动无头浏览器 + const browser = await puppeteer.launch(config.launchConfig); + const page = await browser.newPage(); + await page.setExtraHTTPHeaders(config.httpHeaders); + + // 访问页面 + await page.goto(config.page, { + waitUntil: 'networkidle2', + timeout: config.pageTimeOut + }); + + await page.setViewport({ width: 1080, height: 1024 }); + + // 抓取数量 + const number = await page.$eval( + '#semiTabpost h2 span:last-child', + el => el.textContent.trim() + ); + console.log('1 抓取到主播最新作品数:', number); + + // 获取旧值 + const { count } = await db.get(); + console.log('2 数据库里的旧值:', count); + + // 判断是否更新 + if (String(count) !== String(number)) { + console.log('✅ 主播更新作品了'); + await mailer.send(); + await db.set({ + count: number, + time: new Date().toLocaleString() + }); + console.log('✅ 已更新到数据库'); + } else { + console.log('❌ 主播没有更新作品'); + } + + await browser.close(); + console.log('✅ 本次任务执行完成\n'); + + } catch (err) { + console.error('❌ 任务执行出错:', err); + } +} + + +console.log('✅ 程序已启动,执行任务,定时规则:', config.cron); + +schedule.scheduleJob(config.cron, async () => { + await startTask(); +}); + +// startTask() \ No newline at end of file diff --git a/src/utils/mailer.ts b/src/utils/mailer.ts new file mode 100644 index 0000000..3d275c1 --- /dev/null +++ b/src/utils/mailer.ts @@ -0,0 +1,41 @@ +import nodemailer from 'nodemailer'; +import config from '../config'; + + +class Mailer { + transporter: any; + + constructor() { + this.transporter = nodemailer.createTransport(config.mailer); + this.verify(); + } + + + async verify() { + try { + await this.transporter.verify(); + console.log("✅ 邮件服务已经初始化成功..."); + } catch (err) { + console.error("❌ 邮件服务初始化失败: ", err); + } + } + + async send() { + console.log('准备发送邮件通知!'); + try { + const result = await this.transporter.sendMail({ + from: '2271608011@qq.com', // sender address + to: "2271608011@qq.com", // list of recipients + subject: "小🐰碎碎念 - 更新了!", // subject line + html: `您关注的博主,更新啦!抖音主页` + }); + + console.log('✅ 邮件发送成功:', result); + } catch (err) { + console.error('❌ 邮件发送失败:', err); + throw err; + } + } +} + +export default new Mailer \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..0d82925 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + + // Treat files as modules even if it doesn't use import/export + "moduleDetection": "force", + + // Ignore module structure + "module": "Preserve", + + // Allow JSON modules to be imported + "resolveJsonModule": true, + + // Allow JS files to be imported from TS and vice versa + "allowJs": true, + + // Use correct ESM import behavior + "esModuleInterop": true, + + // Disallow features that require cross-file awareness + "isolatedModules": true, + }, +} \ No newline at end of file