@whyour/qinglong 2.20.2-3 → 2.21.0-10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -0
- package/AGENTS.md +43 -0
- package/README-en.md +11 -0
- package/README.md +11 -0
- package/back/protos/api.proto +3 -0
- package/deploy/kubernetes/README.md +81 -0
- package/deploy/kubernetes/base/kustomization.yaml +5 -0
- package/deploy/kubernetes/base/qinglong.yaml +95 -0
- package/deploy/kubernetes/overlays/example/kustomization.yaml +10 -0
- package/docker/Dockerfile +51 -69
- package/docker/Dockerfile.310 +94 -0
- package/docker/Dockerfile.debian +120 -0
- package/docker/{310.Dockerfile → Dockerfile.debian310} +13 -5
- package/docker/docker-entrypoint.sh +95 -3
- package/docs/PROJECT_ARCHITECTURE.md +550 -0
- package/package.json +29 -28
- package/sample/config.sample.sh +19 -3
- package/sample/notify.js +145 -9
- package/sample/notify.py +110 -11
- package/shell/api.sh +51 -21
- package/shell/bot.sh +30 -16
- package/shell/check.sh +21 -19
- package/shell/lang/en.sh +105 -0
- package/shell/lang/zh.sh +105 -0
- package/shell/otask.sh +117 -28
- package/shell/preload/client.js +20 -2
- package/shell/preload/esm-loader.mjs +41 -0
- package/shell/preload/sitecustomize.js +36 -0
- package/shell/pub.sh +8 -8
- package/shell/rmlog.sh +5 -5
- package/shell/share.sh +50 -31
- package/shell/start.sh +40 -27
- package/shell/task.sh +10 -2
- package/shell/update.sh +22 -22
- package/static/build/api/config.js +17 -7
- package/static/build/api/cron.js +40 -3
- package/static/build/api/dashboard.js +344 -0
- package/static/build/api/env.js +40 -2
- package/static/build/api/index.js +2 -0
- package/static/build/api/log.js +15 -5
- package/static/build/api/script.js +34 -9
- package/static/build/api/system.js +22 -8
- package/static/build/api/user.js +6 -5
- package/static/build/app.js +22 -19
- package/static/build/config/const.js +8 -6
- package/static/build/config/container.js +12 -0
- package/static/build/config/grpcCerts.js +150 -0
- package/static/build/config/index.js +6 -4
- package/static/build/config/util.js +69 -18
- package/static/build/data/cron.js +3 -1
- package/static/build/data/cronStats.js +59 -0
- package/static/build/data/env.js +2 -0
- package/static/build/data/notify.js +18 -1
- package/static/build/data/runningInstance.js +57 -0
- package/static/build/data/sock.js +1 -0
- package/static/build/loaders/app.js +7 -7
- package/static/build/loaders/db.js +8 -2
- package/static/build/loaders/deps.js +1 -22
- package/static/build/loaders/express.js +19 -15
- package/static/build/loaders/initData.js +20 -2
- package/static/build/loaders/initFile.js +3 -1
- package/static/build/loaders/initTask.js +3 -2
- package/static/build/loaders/server.js +1 -1
- package/static/build/protos/api.js +23 -1
- package/static/build/schedule/addCron.js +67 -10
- package/static/build/schedule/api.js +1 -1
- package/static/build/schedule/client.js +9 -1
- package/static/build/schedule/delCron.js +11 -1
- package/static/build/schedule/health.js +1 -1
- package/static/build/services/config.js +19 -5
- package/static/build/services/cron.js +198 -38
- package/static/build/services/dependence.js +19 -18
- package/static/build/services/env.js +31 -3
- package/static/build/services/grpc.js +32 -6
- package/static/build/services/http.js +33 -18
- package/static/build/services/notify.js +87 -8
- package/static/build/services/open.js +2 -1
- package/static/build/services/sshKey.js +6 -3
- package/static/build/services/subscription.js +8 -5
- package/static/build/services/system.js +34 -9
- package/static/build/services/user.js +39 -13
- package/static/build/shared/auth.js +7 -1
- package/static/build/shared/i18n.js +160 -0
- package/static/build/shared/pLimit.js +15 -3
- package/static/build/shared/runCron.js +5 -0
- package/static/build/shared/store.js +7 -0
- package/static/build/validation/schedule.js +10 -0
- package/static/dist/1089.0ecc5383.async.js +1 -0
- package/static/dist/1147.62793604.async.js +1 -0
- package/static/dist/1192.4e5740f2.async.js +1 -0
- package/static/dist/1214.c6469b53.async.js +1 -0
- package/static/dist/134.54df9e38.async.js +1 -0
- package/static/dist/1352.96a77e1d.async.js +1 -0
- package/static/dist/{1765.d8e002d7.async.js → 1765.5ac01a93.async.js} +1 -1
- package/static/dist/1836.f0b74cf1.async.js +1 -0
- package/static/dist/{1885.e0d00d2d.async.js → 1885.e1ea09f6.async.js} +1 -1
- package/static/dist/1967.3f3945d0.async.js +1 -0
- package/static/dist/{2096.383c1047.async.js → 2096.6d98fd12.async.js} +1 -1
- package/static/dist/2208.85285476.async.js +1 -0
- package/static/dist/2286.f371c743.async.js +1 -0
- package/static/dist/2476.4e9b0992.async.js +1 -0
- package/static/dist/2537.2b262ee0.async.js +1 -0
- package/static/dist/{255.12f03ab2.async.js → 255.8a80b983.async.js} +1 -1
- package/static/dist/2635.d4c59d23.async.js +1 -0
- package/static/dist/2808.cdc0995c.async.js +1 -0
- package/static/dist/{2821.be3dc88e.async.js → 2821.651f31e5.async.js} +1 -1
- package/static/dist/2986.4c49eef7.async.js +1 -0
- package/static/dist/300.08ac9875.async.js +1 -0
- package/static/dist/3191.545ab873.async.js +1 -0
- package/static/dist/3714.8d6dba9e.async.js +1 -0
- package/static/dist/3906.a5eee612.async.js +1 -0
- package/static/dist/{6541.a6d499de.async.js → 3948.4fe809fd.async.js} +1 -1
- package/static/dist/{5171.7fc6d0a2.async.js → 4573.16f19278.async.js} +1 -1
- package/static/dist/{4859.93e63ea6.async.js → 4859.6592cebb.async.js} +1 -1
- package/static/dist/4887.8e3ae573.async.js +1 -0
- package/static/dist/{4902.54ecbdb5.async.js → 4902.555f92ab.async.js} +1 -1
- package/static/dist/{4934.1ca6b6b0.async.js → 4934.f3539d08.async.js} +1 -1
- package/static/dist/5077.cbd111cd.async.js +1 -0
- package/static/dist/{6247.b550d996.async.js → 5157.7c5af144.async.js} +1 -1
- package/static/dist/{540.481d4708.async.js → 540.19ddf020.async.js} +1 -1
- package/static/dist/{5970.10ac4f16.async.js → 5970.d3a6e7bd.async.js} +1 -1
- package/static/dist/{6013.2d7bb12a.async.js → 6013.4e38de36.async.js} +1 -1
- package/static/dist/{6016.9c379049.async.js → 6016.1e6574b6.async.js} +1 -1
- package/static/dist/{6035.5889ddc7.async.js → 6035.32ebfad9.async.js} +1 -1
- package/static/dist/6339.ab305e96.async.js +1 -0
- package/static/dist/6569.55177f6a.async.js +1 -0
- package/static/dist/6610.c111af7e.async.js +1 -0
- package/static/dist/{3034.6413c38e.async.js → 6638.87a163d2.async.js} +1 -1
- package/static/dist/{6646.5fc37228.async.js → 6646.95e92533.async.js} +1 -1
- package/static/dist/6665.1d099ad1.async.js +1 -0
- package/static/dist/{7355.b7c0562f.async.js → 7355.f9f263d8.async.js} +1 -1
- package/static/dist/{7384.065ccae2.async.js → 7384.1bb449d5.async.js} +1 -1
- package/static/dist/7441.ee1bf2bb.async.js +1 -0
- package/static/dist/{7508.a31662a3.async.js → 7508.7dcee91c.async.js} +1 -1
- package/static/dist/{7802.6b73f16a.async.js → 7802.34255805.async.js} +1 -1
- package/static/dist/{7984.e6bb9378.async.js → 7984.594296a5.async.js} +1 -1
- package/static/dist/{5653.4fce7ce8.async.js → 8033.5cb31493.async.js} +1 -1
- package/static/dist/8147.2fb55202.async.js +1 -0
- package/static/dist/8187.48c130d6.async.js +1 -0
- package/static/dist/8495.d53e15ca.async.js +1 -0
- package/static/dist/8587.315b06c0.async.js +1 -0
- package/static/dist/8826.db34ad8d.async.js +1 -0
- package/static/dist/{2742.4852aac8.async.js → 8865.ed665d31.async.js} +1 -1
- package/static/dist/901.7ee5c6d3.async.js +1 -0
- package/static/dist/9271.231db2ce.async.js +1 -0
- package/static/dist/9323.a33f47da.async.js +1 -0
- package/static/dist/{9730.30083c91.async.js → 9730.801665a3.async.js} +1 -1
- package/static/dist/{9761.627ca3b5.async.js → 9761.360a19d8.async.js} +1 -1
- package/static/dist/index.html +2 -2
- package/static/dist/layouts__index.a7a2bfe0.async.js +1 -0
- package/static/dist/layouts__index.adf0692f.chunk.css +1 -0
- package/static/dist/preload_helper.3048fe5b.js +1 -0
- package/static/dist/{src__pages__config__index.622b6ee8.async.js → src__pages__config__index.a22ff7dc.async.js} +1 -1
- package/static/dist/{src__pages__crontab__const.323d5124.async.js → src__pages__crontab__const.aba07deb.async.js} +1 -1
- package/static/dist/src__pages__crontab__detail.b98f0084.async.js +1 -0
- package/static/dist/src__pages__crontab__index.68e78a33.async.js +1 -0
- package/static/dist/{src__pages__crontab__logModal.5e6a4bf2.async.js → src__pages__crontab__logModal.831d5e4b.async.js} +1 -1
- package/static/dist/src__pages__crontab__modal.f7041c7c.async.js +1 -0
- package/static/dist/src__pages__crontab__type.d7af36e5.async.js +1 -0
- package/static/dist/{src__pages__crontab__viewCreateModal.ffcf7a24.async.js → src__pages__crontab__viewCreateModal.4d589f66.async.js} +1 -1
- package/static/dist/{src__pages__crontab__viewManageModal.c2724575.async.js → src__pages__crontab__viewManageModal.0e317746.async.js} +1 -1
- package/static/dist/src__pages__dashboard__index.58177357.async.js +1 -0
- package/static/dist/src__pages__dependence__index.b7bbc795.async.js +1 -0
- package/static/dist/{src__pages__dependence__logModal.f123e2ac.async.js → src__pages__dependence__logModal.0681830b.async.js} +1 -1
- package/static/dist/src__pages__dependence__modal.f7bb47ba.async.js +1 -0
- package/static/dist/src__pages__env__editNameModal.48715576.async.js +1 -0
- package/static/dist/src__pages__env__index.452cdc47.async.js +1 -0
- package/static/dist/src__pages__env__modal.e1234834.async.js +1 -0
- package/static/dist/src__pages__error__index.dedb2b90.async.js +1 -0
- package/static/dist/src__pages__initialization__index.22620a77.async.js +1 -0
- package/static/dist/src__pages__log__index.9c66639f.async.js +1 -0
- package/static/dist/{src__pages__login__index.cd6e3152.async.js → src__pages__login__index.8c813eb1.async.js} +1 -1
- package/static/dist/{src__pages__script__components__UnsupportedFilePreview__index.39074c68.async.js → src__pages__script__components__UnsupportedFilePreview__index.c347a13a.async.js} +1 -1
- package/static/dist/src__pages__script__editNameModal.532a3044.async.js +1 -0
- package/static/dist/src__pages__script__index.1fc20f22.async.js +1 -0
- package/static/dist/src__pages__script__renameModal.5cdde919.async.js +1 -0
- package/static/dist/src__pages__script__saveModal.5ffed35f.async.js +1 -0
- package/static/dist/src__pages__script__setting.1a82c6d7.async.js +1 -0
- package/static/dist/src__pages__setting__appModal.43b7758a.async.js +1 -0
- package/static/dist/src__pages__setting__checkUpdate.34d773f2.async.js +1 -0
- package/static/dist/src__pages__setting__dependence.9c04c79a.async.js +1 -0
- package/static/dist/src__pages__setting__index.7e070838.async.js +1 -0
- package/static/dist/src__pages__setting__notification.bac481c2.async.js +1 -0
- package/static/dist/src__pages__setting__other.707cfafe.async.js +1 -0
- package/static/dist/src__pages__setting__security.b7235753.async.js +1 -0
- package/static/dist/src__pages__setting__systemLog.b81a8c1d.async.js +1 -0
- package/static/dist/{src__pages__subscription__logModal.0caa7283.async.js → src__pages__subscription__logModal.3864b37f.async.js} +1 -1
- package/static/dist/src__pages__subscription__modal.562448e2.async.js +1 -0
- package/static/dist/{umi.ef8199a4.js → umi.a54a59f6.js} +1 -1
- package/version.yaml +33 -4
- package/sample/notify.py.save +0 -1010
- package/static/dist/105.85a5c47a.async.js +0 -1
- package/static/dist/1083.f86ce804.async.js +0 -1
- package/static/dist/1147.32f41a88.async.js +0 -1
- package/static/dist/1352.ab6da08e.async.js +0 -1
- package/static/dist/1690.f0290540.async.js +0 -1
- package/static/dist/1742.6cbe5aca.async.js +0 -1
- package/static/dist/2208.8e3a7325.async.js +0 -1
- package/static/dist/3191.70bc19db.async.js +0 -1
- package/static/dist/5312.74b95311.async.js +0 -1
- package/static/dist/5691.931f59c5.async.js +0 -1
- package/static/dist/6159.55cb068a.async.js +0 -1
- package/static/dist/7025.f4080d63.async.js +0 -1
- package/static/dist/739.6be5552a.async.js +0 -1
- package/static/dist/7571.4f6240b1.async.js +0 -1
- package/static/dist/786.59fc381c.async.js +0 -1
- package/static/dist/8317.c44c1ebd.async.js +0 -1
- package/static/dist/8826.0291edfd.async.js +0 -1
- package/static/dist/955.3c9481f7.async.js +0 -1
- package/static/dist/layouts__index.1fce90e0.chunk.css +0 -1
- package/static/dist/layouts__index.8dcf1576.async.js +0 -1
- package/static/dist/preload_helper.116a62f6.js +0 -1
- package/static/dist/src__pages__crontab__detail.b07f0c0a.async.js +0 -1
- package/static/dist/src__pages__crontab__index.2e2e1096.async.js +0 -1
- package/static/dist/src__pages__crontab__modal.4d8c2a22.async.js +0 -1
- package/static/dist/src__pages__crontab__type.db7c1858.async.js +0 -1
- package/static/dist/src__pages__dependence__index.3d87ceac.async.js +0 -1
- package/static/dist/src__pages__dependence__modal.631ffb5b.async.js +0 -1
- package/static/dist/src__pages__env__editNameModal.ff85ef8c.async.js +0 -1
- package/static/dist/src__pages__env__index.a0a2fece.async.js +0 -1
- package/static/dist/src__pages__env__modal.d1004662.async.js +0 -1
- package/static/dist/src__pages__error__index.1bc3c90b.async.js +0 -1
- package/static/dist/src__pages__initialization__index.8b1cbaf9.async.js +0 -1
- package/static/dist/src__pages__log__index.cf00c9af.async.js +0 -1
- package/static/dist/src__pages__script__editNameModal.53424d49.async.js +0 -1
- package/static/dist/src__pages__script__index.e65df827.async.js +0 -1
- package/static/dist/src__pages__script__renameModal.4bbe7fb1.async.js +0 -1
- package/static/dist/src__pages__script__saveModal.cf449f3c.async.js +0 -1
- package/static/dist/src__pages__script__setting.b345d59a.async.js +0 -1
- package/static/dist/src__pages__setting__appModal.03faec89.async.js +0 -1
- package/static/dist/src__pages__setting__checkUpdate.46efe057.async.js +0 -1
- package/static/dist/src__pages__setting__dependence.4495c7b6.async.js +0 -1
- package/static/dist/src__pages__setting__index.6919c399.async.js +0 -1
- package/static/dist/src__pages__setting__notification.d6a3884f.async.js +0 -1
- package/static/dist/src__pages__setting__other.0d931d6f.async.js +0 -1
- package/static/dist/src__pages__setting__security.91cb545f.async.js +0 -1
- package/static/dist/src__pages__setting__systemLog.1d433a48.async.js +0 -1
- package/static/dist/src__pages__subscription__modal.0b84f6cf.async.js +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whyour/qinglong",
|
|
3
3
|
"packageManager": "pnpm@8.3.1",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.21.0-10",
|
|
5
5
|
"description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -21,9 +21,7 @@
|
|
|
21
21
|
"panel": "npm run build:back && node static/build/app.js",
|
|
22
22
|
"gen:proto": "protoc --experimental_allow_proto3_optional --plugin=./node_modules/.bin/protoc-gen-ts_proto ./back/protos/*.proto --ts_proto_out=./ --ts_proto_opt=outputServices=grpc-js,env=node,esModuleInterop=true,snakeToCamel=false",
|
|
23
23
|
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
|
24
|
-
"postinstall": "max setup 2>/dev/null || true"
|
|
25
|
-
"test": "umi-test",
|
|
26
|
-
"test:coverage": "umi-test --coverage"
|
|
24
|
+
"postinstall": "max setup 2>/dev/null || true"
|
|
27
25
|
},
|
|
28
26
|
"gitHooks": {
|
|
29
27
|
"pre-commit": "lint-staged"
|
|
@@ -67,16 +65,22 @@
|
|
|
67
65
|
}
|
|
68
66
|
},
|
|
69
67
|
"overrides": {
|
|
70
|
-
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3"
|
|
68
|
+
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3",
|
|
69
|
+
"@codemirror/state": "6.5.4",
|
|
70
|
+
"@codemirror/view": "6.39.16"
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
|
+
"@ant-design/plots": "^2.6.8",
|
|
75
|
+
"@bufbuild/protobuf": "^2.10.0",
|
|
74
76
|
"@grpc/grpc-js": "^1.14.0",
|
|
75
77
|
"@grpc/proto-loader": "^0.8.0",
|
|
78
|
+
"@keyv/sqlite": "^4.0.1",
|
|
76
79
|
"@otplib/preset-default": "^12.0.1",
|
|
77
80
|
"body-parser": "^1.20.3",
|
|
78
81
|
"celebrate": "^15.0.3",
|
|
79
82
|
"chokidar": "^4.0.1",
|
|
83
|
+
"compression": "^1.7.4",
|
|
80
84
|
"cors": "^2.8.5",
|
|
81
85
|
"cron-parser": "^5.4.0",
|
|
82
86
|
"cross-spawn": "^7.0.6",
|
|
@@ -86,51 +90,48 @@
|
|
|
86
90
|
"express-jwt": "^8.4.1",
|
|
87
91
|
"express-rate-limit": "^7.4.1",
|
|
88
92
|
"express-urlrewrite": "^2.0.3",
|
|
89
|
-
"
|
|
93
|
+
"helmet": "^8.1.0",
|
|
90
94
|
"hpagent": "^1.2.0",
|
|
91
95
|
"http-proxy-middleware": "^3.0.3",
|
|
92
96
|
"iconv-lite": "^0.6.3",
|
|
97
|
+
"ip2region": "2.3.0",
|
|
93
98
|
"js-yaml": "^4.1.0",
|
|
94
99
|
"jsonwebtoken": "^9.0.2",
|
|
100
|
+
"keyv": "^5.2.3",
|
|
95
101
|
"lodash": "^4.17.21",
|
|
96
|
-
"multer": "1.
|
|
102
|
+
"multer": "2.1.1",
|
|
97
103
|
"node-schedule": "^2.1.0",
|
|
98
|
-
"nodemailer": "^
|
|
104
|
+
"nodemailer": "^8.0.1",
|
|
99
105
|
"p-queue-cjs": "7.3.4",
|
|
100
|
-
"
|
|
106
|
+
"proper-lockfile": "^4.1.2",
|
|
101
107
|
"ps-tree": "^1.2.0",
|
|
102
108
|
"reflect-metadata": "^0.2.2",
|
|
109
|
+
"request-ip": "3.3.0",
|
|
103
110
|
"sequelize": "^6.37.5",
|
|
104
111
|
"sockjs": "^0.3.24",
|
|
105
112
|
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3",
|
|
106
113
|
"toad-scheduler": "^3.0.1",
|
|
107
114
|
"typedi": "^0.10.0",
|
|
115
|
+
"undici": "^7.9.0",
|
|
108
116
|
"uuid": "^11.0.3",
|
|
109
117
|
"winston": "^3.17.0",
|
|
110
|
-
"winston-daily-rotate-file": "^5.0.0"
|
|
111
|
-
"request-ip": "3.3.0",
|
|
112
|
-
"ip2region": "2.3.0",
|
|
113
|
-
"keyv": "^5.2.3",
|
|
114
|
-
"@keyv/sqlite": "^4.0.1",
|
|
115
|
-
"proper-lockfile": "^4.1.2",
|
|
116
|
-
"compression": "^1.7.4",
|
|
117
|
-
"helmet": "^8.1.0"
|
|
118
|
+
"winston-daily-rotate-file": "^5.0.0"
|
|
118
119
|
},
|
|
119
120
|
"devDependencies": {
|
|
120
|
-
"moment": "2.30.1",
|
|
121
121
|
"@ant-design/icons": "^5.0.1",
|
|
122
122
|
"@ant-design/pro-layout": "6.38.22",
|
|
123
|
-
"@codemirror/
|
|
124
|
-
"@codemirror/
|
|
123
|
+
"@codemirror/state": "6.5.4",
|
|
124
|
+
"@codemirror/view": "6.39.16",
|
|
125
125
|
"@monaco-editor/react": "4.2.1",
|
|
126
126
|
"@react-hook/resize-observer": "^2.0.2",
|
|
127
|
-
"react-router-dom": "6.26.1",
|
|
128
127
|
"@types/body-parser": "^1.19.2",
|
|
128
|
+
"@types/compression": "^1.7.2",
|
|
129
129
|
"@types/cors": "^2.8.12",
|
|
130
130
|
"@types/cross-spawn": "^6.0.2",
|
|
131
131
|
"@types/express": "^4.17.13",
|
|
132
132
|
"@types/express-jwt": "^6.0.4",
|
|
133
133
|
"@types/file-saver": "2.0.2",
|
|
134
|
+
"@types/helmet": "^4.0.0",
|
|
134
135
|
"@types/js-yaml": "^4.0.5",
|
|
135
136
|
"@types/jsonwebtoken": "^8.5.8",
|
|
136
137
|
"@types/lodash": "^4.14.185",
|
|
@@ -138,17 +139,17 @@
|
|
|
138
139
|
"@types/node": "^17.0.21",
|
|
139
140
|
"@types/node-schedule": "^1.3.2",
|
|
140
141
|
"@types/nodemailer": "^6.4.4",
|
|
142
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
143
|
+
"@types/ps-tree": "^1.1.6",
|
|
141
144
|
"@types/qrcode.react": "^1.0.2",
|
|
142
145
|
"@types/react": "^18.0.20",
|
|
143
146
|
"@types/react-copy-to-clipboard": "^5.0.4",
|
|
144
147
|
"@types/react-dom": "^18.0.6",
|
|
148
|
+
"@types/request-ip": "0.0.41",
|
|
145
149
|
"@types/serve-handler": "^6.1.1",
|
|
146
150
|
"@types/sockjs": "^0.3.33",
|
|
147
151
|
"@types/sockjs-client": "^1.5.1",
|
|
148
152
|
"@types/uuid": "^8.3.4",
|
|
149
|
-
"@types/request-ip": "0.0.41",
|
|
150
|
-
"@types/proper-lockfile": "^4.1.4",
|
|
151
|
-
"@types/ps-tree": "^1.1.6",
|
|
152
153
|
"@uiw/codemirror-extensions-langs": "^4.21.9",
|
|
153
154
|
"@uiw/react-codemirror": "^4.21.9",
|
|
154
155
|
"@umijs/max": "^4.4.4",
|
|
@@ -160,9 +161,9 @@
|
|
|
160
161
|
"axios": "^1.4.0",
|
|
161
162
|
"compression-webpack-plugin": "9.2.0",
|
|
162
163
|
"concurrently": "^7.0.0",
|
|
163
|
-
"react-hotkeys-hook": "^4.6.1",
|
|
164
164
|
"file-saver": "2.0.2",
|
|
165
165
|
"lint-staged": "^13.0.3",
|
|
166
|
+
"moment": "2.30.1",
|
|
166
167
|
"monaco-editor": "0.33.0",
|
|
167
168
|
"nodemon": "^3.0.1",
|
|
168
169
|
"prettier": "^2.5.1",
|
|
@@ -178,7 +179,9 @@
|
|
|
178
179
|
"react-dnd": "^16.0.1",
|
|
179
180
|
"react-dnd-html5-backend": "^16.0.1",
|
|
180
181
|
"react-dom": "18.3.1",
|
|
182
|
+
"react-hotkeys-hook": "^4.6.1",
|
|
181
183
|
"react-intl-universal": "^2.12.0",
|
|
184
|
+
"react-router-dom": "6.26.1",
|
|
182
185
|
"react-split-pane": "^0.1.92",
|
|
183
186
|
"sockjs-client": "^1.6.0",
|
|
184
187
|
"ts-node": "^10.9.2",
|
|
@@ -186,8 +189,6 @@
|
|
|
186
189
|
"tslib": "^2.4.0",
|
|
187
190
|
"typescript": "5.2.2",
|
|
188
191
|
"vh-check": "^2.0.5",
|
|
189
|
-
"virtualizedtableforantd4": "1.3.0"
|
|
190
|
-
"@types/compression": "^1.7.2",
|
|
191
|
-
"@types/helmet": "^4.0.0"
|
|
192
|
+
"virtualizedtableforantd4": "1.3.0"
|
|
192
193
|
}
|
|
193
194
|
}
|
package/sample/config.sample.sh
CHANGED
|
@@ -195,12 +195,14 @@ export SMTP_SERVER=""
|
|
|
195
195
|
## SMTP 发送邮件服务器是否使用 SSL,填写 true 或 false
|
|
196
196
|
export SMTP_SSL=""
|
|
197
197
|
|
|
198
|
-
## smtp_email 填写 SMTP
|
|
198
|
+
## smtp_email 填写 SMTP 发件邮箱
|
|
199
199
|
export SMTP_EMAIL=""
|
|
200
200
|
## smtp_password 填写 SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定
|
|
201
201
|
export SMTP_PASSWORD=""
|
|
202
202
|
## smtp_name 填写 SMTP 收发件人姓名,可随意填写
|
|
203
203
|
export SMTP_NAME=""
|
|
204
|
+
## smtp_email_to 填写 SMTP 收件邮箱,多个用英文;分隔,不填默认发给发件邮箱
|
|
205
|
+
export SMTP_EMAIL_TO=""
|
|
204
206
|
|
|
205
207
|
## 17. PushMe
|
|
206
208
|
## 官方说明文档:https://push.i-i.me/
|
|
@@ -239,14 +241,19 @@ export NTFY_PASSWORD=""
|
|
|
239
241
|
export NTFY_ACTIONS=""
|
|
240
242
|
|
|
241
243
|
## 21. wxPusher
|
|
242
|
-
|
|
243
|
-
|
|
244
|
+
### 方式一:标准发送(更强大)
|
|
245
|
+
#### 官方文档: https://wxpusher.zjiecode.com/docs/
|
|
246
|
+
#### 管理后台: https://wxpusher.zjiecode.com/admin/
|
|
244
247
|
## wxPusher 的 appToken
|
|
245
248
|
export WXPUSHER_APP_TOKEN=""
|
|
246
249
|
## wxPusher 的 topicIds,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
|
|
247
250
|
export WXPUSHER_TOPIC_IDS=""
|
|
248
251
|
## wxPusher 的 用户ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
|
|
249
252
|
export WXPUSHER_UIDS=""
|
|
253
|
+
### 方式二:极简发送(最简单,简单好用,一键配置,更推荐)
|
|
254
|
+
#### wxPusher 的 SPT(极简推送),扫码获取 https://wxpusher.zjiecode.com/docs/#/?id=spt
|
|
255
|
+
#### 多个用英文逗号,分隔,最多10个;与上面的 appToken 方式二选一即可
|
|
256
|
+
export WXPUSHER_SPT_LIST=""
|
|
250
257
|
|
|
251
258
|
## 22. 自定义通知
|
|
252
259
|
## 自定义通知 接收回调的URL
|
|
@@ -259,4 +266,13 @@ export WEBHOOK_METHOD=""
|
|
|
259
266
|
## 支持 text/plain、application/json、multipart/form-data、application/x-www-form-urlencoded
|
|
260
267
|
export WEBHOOK_CONTENT_TYPE=""
|
|
261
268
|
|
|
269
|
+
## 23. OpeniLink
|
|
270
|
+
## 官方文档: https://openilink.com/docs/hub/apps
|
|
271
|
+
## 在 OpeniLink Hub 后台安装 App 后获取 app_token
|
|
272
|
+
export OPENILINK_APP_TOKEN=""
|
|
273
|
+
## OpeniLink Hub 地址,默认为 https://hub.openilink.com,自建 Hub 时填写自己的地址
|
|
274
|
+
export OPENILINK_HUB_URL=""
|
|
275
|
+
## OpeniLink 的 context_token,用于标识消息会话上下文,可从消息事件中获取
|
|
276
|
+
export OPENILINK_CONTEXT_TOKEN=""
|
|
277
|
+
|
|
262
278
|
## 其他需要的变量,脚本中需要的变量使用 export 变量名= 声明即可
|
package/sample/notify.js
CHANGED
|
@@ -108,8 +108,8 @@ const push_config = {
|
|
|
108
108
|
|
|
109
109
|
QYWX_KEY: '', // 企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
|
|
110
110
|
|
|
111
|
-
TG_BOT_TOKEN: '', // tg 机器人的 TG_BOT_TOKEN,例:
|
|
112
|
-
TG_USER_ID: '', // tg 机器人的 TG_USER_ID,例:
|
|
111
|
+
TG_BOT_TOKEN: '', // tg 机器人的 TG_BOT_TOKEN,例:1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
|
|
112
|
+
TG_USER_ID: '', // tg 机器人的 TG_USER_ID,例:1234567890
|
|
113
113
|
TG_API_HOST: 'https://api.telegram.org', // tg 代理 api
|
|
114
114
|
TG_PROXY_AUTH: '', // tg 代理认证参数
|
|
115
115
|
TG_PROXY_HOST: '', // tg 机器人的 TG_PROXY_HOST
|
|
@@ -121,7 +121,8 @@ const push_config = {
|
|
|
121
121
|
|
|
122
122
|
SMTP_SERVICE: '', // 邮箱服务名称,比如 126、163、Gmail、QQ 等,支持列表 https://github.com/nodemailer/nodemailer/blob/master/lib/well-known/services.json
|
|
123
123
|
SMTP_EMAIL: '', // SMTP 发件邮箱
|
|
124
|
-
SMTP_TO: '', // SMTP
|
|
124
|
+
SMTP_TO: '', // SMTP 收件邮箱,兼容旧参数名,默认通知将会发给发件邮箱
|
|
125
|
+
SMTP_EMAIL_TO: '', // SMTP 收件邮箱,多个分号分隔,默认发给发件邮箱
|
|
125
126
|
SMTP_PASSWORD: '', // SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定
|
|
126
127
|
SMTP_NAME: '', // SMTP 收发件人姓名,可随意填写
|
|
127
128
|
|
|
@@ -146,11 +147,21 @@ const push_config = {
|
|
|
146
147
|
NTFY_PASSWORD: '', // 推送用户密码,可选
|
|
147
148
|
NTFY_ACTIONS: '', // 推送用户动作,可选
|
|
148
149
|
|
|
150
|
+
// 方式一:标准发送(更强大)
|
|
149
151
|
// 官方文档: https://wxpusher.zjiecode.com/docs/
|
|
150
152
|
// 管理后台: https://wxpusher.zjiecode.com/admin/
|
|
151
153
|
WXPUSHER_APP_TOKEN: '', // wxpusher 的 appToken
|
|
152
154
|
WXPUSHER_TOPIC_IDS: '', // wxpusher 的 主题ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
|
|
153
155
|
WXPUSHER_UIDS: '', // wxpusher 的 用户ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
|
|
156
|
+
// 方式二:极简发送(最简单,简单好用,一键配置,更推荐)
|
|
157
|
+
// wxPusher 的 SPT(极简推送),扫码获取 https://wxpusher.zjiecode.com/docs/#/?id=spt
|
|
158
|
+
// 多个用英文逗号,分隔,最多10个;与上面的 appToken 方式二选一即可
|
|
159
|
+
WXPUSHER_SPT_LIST: '', // wxpusher 的 SPT(极简推送),多个用英文逗号,分隔,最多10个
|
|
160
|
+
|
|
161
|
+
// 官方文档: https://openilink.com/docs/hub/apps
|
|
162
|
+
OPENILINK_APP_TOKEN: '', // OpeniLink 的 app_token,在 OpeniLink Hub 后台安装 App 后获取
|
|
163
|
+
OPENILINK_HUB_URL: '', // OpeniLink Hub 地址,默认为 https://hub.openilink.com,自建 Hub 时填写自己的地址
|
|
164
|
+
OPENILINK_CONTEXT_TOKEN: '', // OpeniLink 的 context_token,用于标识消息会话上下文,可从消息事件中获取
|
|
154
165
|
};
|
|
155
166
|
|
|
156
167
|
for (const key in push_config) {
|
|
@@ -301,7 +312,7 @@ function serverNotify(text, desp) {
|
|
|
301
312
|
console.log('Server 酱发送通知调用API失败😞\n', err);
|
|
302
313
|
} else {
|
|
303
314
|
// server酱和Server酱·Turbo版的返回json格式不太一样
|
|
304
|
-
if (data.errno === 0 || data.
|
|
315
|
+
if (data.errno === 0 || data.code === 0) {
|
|
305
316
|
console.log('Server 酱发送通知消息成功🎉\n');
|
|
306
317
|
} else if (data.errno === 1024) {
|
|
307
318
|
// 一分钟内发送相同的内容会触发
|
|
@@ -1046,8 +1057,14 @@ function fsBotNotify(text, desp) {
|
|
|
1046
1057
|
}
|
|
1047
1058
|
|
|
1048
1059
|
async function smtpNotify(text, desp) {
|
|
1049
|
-
const {
|
|
1050
|
-
|
|
1060
|
+
const {
|
|
1061
|
+
SMTP_EMAIL,
|
|
1062
|
+
SMTP_TO,
|
|
1063
|
+
SMTP_EMAIL_TO,
|
|
1064
|
+
SMTP_PASSWORD,
|
|
1065
|
+
SMTP_SERVICE,
|
|
1066
|
+
SMTP_NAME,
|
|
1067
|
+
} = push_config;
|
|
1051
1068
|
if (![SMTP_EMAIL, SMTP_PASSWORD].every(Boolean) || !SMTP_SERVICE) {
|
|
1052
1069
|
return;
|
|
1053
1070
|
}
|
|
@@ -1063,9 +1080,20 @@ async function smtpNotify(text, desp) {
|
|
|
1063
1080
|
});
|
|
1064
1081
|
|
|
1065
1082
|
const addr = SMTP_NAME ? `"${SMTP_NAME}" <${SMTP_EMAIL}>` : SMTP_EMAIL;
|
|
1083
|
+
const recipients = [SMTP_EMAIL_TO, SMTP_TO].reduce((list, value) => {
|
|
1084
|
+
if (!value) {
|
|
1085
|
+
return list;
|
|
1086
|
+
}
|
|
1087
|
+
return list.concat(
|
|
1088
|
+
value
|
|
1089
|
+
.split(/[;;]/)
|
|
1090
|
+
.map((item) => item.trim())
|
|
1091
|
+
.filter(Boolean),
|
|
1092
|
+
);
|
|
1093
|
+
}, []);
|
|
1066
1094
|
const info = await transporter.sendMail({
|
|
1067
1095
|
from: addr,
|
|
1068
|
-
to:
|
|
1096
|
+
to: recipients.length ? recipients : SMTP_EMAIL,
|
|
1069
1097
|
subject: text,
|
|
1070
1098
|
html: `${desp.replace(/\n/g, '<br/>')}`,
|
|
1071
1099
|
});
|
|
@@ -1408,6 +1436,112 @@ function wxPusherNotify(text, desp) {
|
|
|
1408
1436
|
});
|
|
1409
1437
|
}
|
|
1410
1438
|
|
|
1439
|
+
function wxPusherSptNotify(text, desp) {
|
|
1440
|
+
return new Promise((resolve) => {
|
|
1441
|
+
const { WXPUSHER_SPT_LIST } = push_config;
|
|
1442
|
+
if (WXPUSHER_SPT_LIST) {
|
|
1443
|
+
// 处理 SPT,将逗号分隔的字符串转为数组
|
|
1444
|
+
const spts = WXPUSHER_SPT_LIST.split(',')
|
|
1445
|
+
.map((spt) => spt.trim())
|
|
1446
|
+
.filter((spt) => spt);
|
|
1447
|
+
|
|
1448
|
+
if (!spts.length) {
|
|
1449
|
+
console.log('wxpusher SPT 不能为空!!');
|
|
1450
|
+
return resolve();
|
|
1451
|
+
}
|
|
1452
|
+
if (spts.length > 10) {
|
|
1453
|
+
console.log('wxpusher SPT 最多支持 10 个!!');
|
|
1454
|
+
return resolve();
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
const body = {
|
|
1458
|
+
content: `<h1>${text}</h1><br/><div style='white-space: pre-wrap;'>${desp}</div>`,
|
|
1459
|
+
summary: text,
|
|
1460
|
+
contentType: 2,
|
|
1461
|
+
// 单个 SPT 用 spt,多个用 sptList
|
|
1462
|
+
...(spts.length === 1 ? { spt: spts[0] } : { sptList: spts }),
|
|
1463
|
+
};
|
|
1464
|
+
|
|
1465
|
+
const options = {
|
|
1466
|
+
url: 'https://wxpusher.zjiecode.com/api/send/message/simple-push',
|
|
1467
|
+
body: JSON.stringify(body),
|
|
1468
|
+
headers: {
|
|
1469
|
+
'Content-Type': 'application/json',
|
|
1470
|
+
},
|
|
1471
|
+
timeout,
|
|
1472
|
+
};
|
|
1473
|
+
|
|
1474
|
+
$.post(options, (err, resp, data) => {
|
|
1475
|
+
try {
|
|
1476
|
+
if (err) {
|
|
1477
|
+
console.log('wxpusher SPT 发送通知消息失败!\n', err);
|
|
1478
|
+
} else {
|
|
1479
|
+
if (data.code === 1000) {
|
|
1480
|
+
console.log('wxpusher SPT 发送通知消息完成!');
|
|
1481
|
+
} else {
|
|
1482
|
+
console.log(`wxpusher SPT 发送通知消息异常:${data.msg}`);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
} catch (e) {
|
|
1486
|
+
$.logErr(e, resp);
|
|
1487
|
+
} finally {
|
|
1488
|
+
resolve(data);
|
|
1489
|
+
}
|
|
1490
|
+
});
|
|
1491
|
+
} else {
|
|
1492
|
+
resolve();
|
|
1493
|
+
}
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
function openiLinkNotify(text, desp) {
|
|
1498
|
+
return new Promise((resolve) => {
|
|
1499
|
+
const { OPENILINK_APP_TOKEN, OPENILINK_HUB_URL, OPENILINK_CONTEXT_TOKEN } =
|
|
1500
|
+
push_config;
|
|
1501
|
+
if (OPENILINK_APP_TOKEN) {
|
|
1502
|
+
const baseUrl = OPENILINK_HUB_URL
|
|
1503
|
+
? OPENILINK_HUB_URL.replace(/\/$/, '')
|
|
1504
|
+
: 'https://hub.openilink.com';
|
|
1505
|
+
const body = {
|
|
1506
|
+
type: 'text',
|
|
1507
|
+
content: `${text}\n\n${desp}`,
|
|
1508
|
+
};
|
|
1509
|
+
if (OPENILINK_CONTEXT_TOKEN) {
|
|
1510
|
+
body.context_token = OPENILINK_CONTEXT_TOKEN;
|
|
1511
|
+
}
|
|
1512
|
+
const options = {
|
|
1513
|
+
url: `${baseUrl}/bot/v1/message/send`,
|
|
1514
|
+
body: JSON.stringify(body),
|
|
1515
|
+
headers: {
|
|
1516
|
+
'Content-Type': 'application/json',
|
|
1517
|
+
Authorization: `Bearer ${OPENILINK_APP_TOKEN}`,
|
|
1518
|
+
},
|
|
1519
|
+
timeout,
|
|
1520
|
+
};
|
|
1521
|
+
|
|
1522
|
+
$.post(options, (err, resp, data) => {
|
|
1523
|
+
try {
|
|
1524
|
+
if (err) {
|
|
1525
|
+
console.log('OpeniLink 发送通知消息失败!\n', err);
|
|
1526
|
+
} else {
|
|
1527
|
+
if (data.ok) {
|
|
1528
|
+
console.log('OpeniLink 发送通知消息成功!');
|
|
1529
|
+
} else {
|
|
1530
|
+
console.log(`OpeniLink 发送通知消息异常:${data.error}`);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
} catch (e) {
|
|
1534
|
+
$.logErr(e, resp);
|
|
1535
|
+
} finally {
|
|
1536
|
+
resolve(data);
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
} else {
|
|
1540
|
+
resolve();
|
|
1541
|
+
}
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1411
1545
|
function parseString(input, valueFormatFn) {
|
|
1412
1546
|
const regex = /(\w+):\s*((?:(?!\n\w+:).)*)/g;
|
|
1413
1547
|
const matches = {};
|
|
@@ -1511,7 +1645,7 @@ async function sendNotify(text, desp, params = {}) {
|
|
|
1511
1645
|
}
|
|
1512
1646
|
}
|
|
1513
1647
|
|
|
1514
|
-
if (
|
|
1648
|
+
if (![false, 'false'].includes(push_config.HITOKOTO)) {
|
|
1515
1649
|
desp += '\n\n' + (await one());
|
|
1516
1650
|
}
|
|
1517
1651
|
|
|
@@ -1527,7 +1661,7 @@ async function sendNotify(text, desp, params = {}) {
|
|
|
1527
1661
|
iGotNotify(text, desp, params), // iGot
|
|
1528
1662
|
gobotNotify(text, desp), // go-cqhttp
|
|
1529
1663
|
gotifyNotify(text, desp), // gotify
|
|
1530
|
-
chatNotify(text, desp), //
|
|
1664
|
+
chatNotify(text, desp), // synology chat
|
|
1531
1665
|
pushDeerNotify(text, desp), // PushDeer
|
|
1532
1666
|
aibotkNotify(text, desp), // 智能微秘书
|
|
1533
1667
|
fsBotNotify(text, desp), // 飞书机器人
|
|
@@ -1538,6 +1672,8 @@ async function sendNotify(text, desp, params = {}) {
|
|
|
1538
1672
|
qmsgNotify(text, desp), // 自定义通知
|
|
1539
1673
|
ntfyNotify(text, desp), // Ntfy
|
|
1540
1674
|
wxPusherNotify(text, desp), // wxpusher
|
|
1675
|
+
wxPusherSptNotify(text, desp), // wxpusher SPT
|
|
1676
|
+
openiLinkNotify(text, desp), // OpeniLink
|
|
1541
1677
|
]);
|
|
1542
1678
|
}
|
|
1543
1679
|
|
package/sample/notify.py
CHANGED
|
@@ -94,8 +94,8 @@ push_config = {
|
|
|
94
94
|
|
|
95
95
|
'QYWX_KEY': '', # 企业微信机器人
|
|
96
96
|
|
|
97
|
-
'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN,例:
|
|
98
|
-
'TG_USER_ID': '', # tg 机器人的 TG_USER_ID,例:
|
|
97
|
+
'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN,例:1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
|
|
98
|
+
'TG_USER_ID': '', # tg 机器人的 TG_USER_ID,例:1234567890
|
|
99
99
|
'TG_API_HOST': '', # tg 代理 api
|
|
100
100
|
'TG_PROXY_AUTH': '', # tg 代理认证参数
|
|
101
101
|
'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST
|
|
@@ -107,7 +107,8 @@ push_config = {
|
|
|
107
107
|
|
|
108
108
|
'SMTP_SERVER': '', # SMTP 发送邮件服务器,形如 smtp.exmail.qq.com:465
|
|
109
109
|
'SMTP_SSL': 'false', # SMTP 发送邮件服务器是否使用 SSL,填写 true 或 false
|
|
110
|
-
'SMTP_EMAIL': '', # SMTP
|
|
110
|
+
'SMTP_EMAIL': '', # SMTP 发件邮箱
|
|
111
|
+
'SMTP_EMAIL_TO': '', # SMTP 收件邮箱,多个分号分隔,默认发给发件邮箱
|
|
111
112
|
'SMTP_PASSWORD': '', # SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定
|
|
112
113
|
'SMTP_NAME': '', # SMTP 收发件人姓名,可随意填写
|
|
113
114
|
|
|
@@ -132,9 +133,20 @@ push_config = {
|
|
|
132
133
|
'NTFY_PASSWORD': '', # 推送用户密码,可选
|
|
133
134
|
'NTFY_ACTIONS': '', # 推送用户动作,可选
|
|
134
135
|
|
|
136
|
+
### 方式一:标准发送(更强大)
|
|
137
|
+
#### 官方文档: https://wxpusher.zjiecode.com/docs/
|
|
138
|
+
#### 管理后台: https://wxpusher.zjiecode.com/admin/
|
|
135
139
|
'WXPUSHER_APP_TOKEN': '', # wxpusher 的 appToken 官方文档: https://wxpusher.zjiecode.com/docs/ 管理后台: https://wxpusher.zjiecode.com/admin/
|
|
136
140
|
'WXPUSHER_TOPIC_IDS': '', # wxpusher 的 主题ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
|
|
137
141
|
'WXPUSHER_UIDS': '', # wxpusher 的 用户ID,多个用英文分号;分隔 topic_ids 与 uids 至少配置一个才行
|
|
142
|
+
### 方式二:极简发送(最简单,简单好用,一键配置,更推荐)
|
|
143
|
+
#### wxPusher 的 SPT(极简推送),扫码获取 https://wxpusher.zjiecode.com/docs/#/?id=spt
|
|
144
|
+
#### 多个用英文逗号,分隔,最多10个;与上面的 appToken 方式二选一即可
|
|
145
|
+
'WXPUSHER_SPT_LIST': '', # wxpusher 的 SPT(极简推送),多个用英文逗号,分隔,最多10个 官方文档: https://wxpusher.zjiecode.com/docs/#/?id=spt
|
|
146
|
+
|
|
147
|
+
'OPENILINK_APP_TOKEN': '', # OpeniLink 的 app_token,在 OpeniLink Hub 后台安装 App 后获取 官方文档: https://openilink.com/docs/hub/apps
|
|
148
|
+
'OPENILINK_HUB_URL': '', # OpeniLink Hub 地址,默认为 https://hub.openilink.com,自建 Hub 时填写自己的地址
|
|
149
|
+
'OPENILINK_CONTEXT_TOKEN': '', # OpeniLink 的 context_token,用于标识消息会话上下文,可从消息事件中获取
|
|
138
150
|
}
|
|
139
151
|
# fmt: on
|
|
140
152
|
|
|
@@ -690,6 +702,10 @@ def smtp(title: str, content: str) -> None:
|
|
|
690
702
|
return
|
|
691
703
|
print("SMTP 邮件 服务启动")
|
|
692
704
|
|
|
705
|
+
email_to = push_config.get("SMTP_EMAIL_TO") or push_config.get("SMTP_EMAIL")
|
|
706
|
+
email_to_list = [
|
|
707
|
+
item.strip() for item in re.split(r"[;;]", email_to) if item.strip()
|
|
708
|
+
]
|
|
693
709
|
message = MIMEText(content, "plain", "utf-8")
|
|
694
710
|
message["From"] = formataddr(
|
|
695
711
|
(
|
|
@@ -697,12 +713,7 @@ def smtp(title: str, content: str) -> None:
|
|
|
697
713
|
push_config.get("SMTP_EMAIL"),
|
|
698
714
|
)
|
|
699
715
|
)
|
|
700
|
-
message["To"] =
|
|
701
|
-
(
|
|
702
|
-
Header(push_config.get("SMTP_NAME"), "utf-8").encode(),
|
|
703
|
-
push_config.get("SMTP_EMAIL"),
|
|
704
|
-
)
|
|
705
|
-
)
|
|
716
|
+
message["To"] = ",".join(email_to_list)
|
|
706
717
|
message["Subject"] = Header(title, "utf-8")
|
|
707
718
|
|
|
708
719
|
try:
|
|
@@ -716,7 +727,7 @@ def smtp(title: str, content: str) -> None:
|
|
|
716
727
|
)
|
|
717
728
|
smtp_server.sendmail(
|
|
718
729
|
push_config.get("SMTP_EMAIL"),
|
|
719
|
-
|
|
730
|
+
email_to_list,
|
|
720
731
|
message.as_bytes(),
|
|
721
732
|
)
|
|
722
733
|
smtp_server.close()
|
|
@@ -898,6 +909,90 @@ def wxpusher_bot(title: str, content: str) -> None:
|
|
|
898
909
|
print(f"wxpusher 推送失败!错误信息:{response.get('msg')}")
|
|
899
910
|
|
|
900
911
|
|
|
912
|
+
def wxpusher_spt(title: str, content: str) -> None:
|
|
913
|
+
"""
|
|
914
|
+
通过 wxpusher 极简推送(SPT)推送消息。
|
|
915
|
+
支持的环境变量:
|
|
916
|
+
- WXPUSHER_SPT_LIST: SPT, 多个用英文逗号,分隔, 最多10个
|
|
917
|
+
"""
|
|
918
|
+
if not push_config.get("WXPUSHER_SPT_LIST"):
|
|
919
|
+
return
|
|
920
|
+
|
|
921
|
+
# 处理 SPT,将逗号分隔的字符串转为数组
|
|
922
|
+
spts = [
|
|
923
|
+
spt.strip()
|
|
924
|
+
for spt in push_config.get("WXPUSHER_SPT_LIST").split(",")
|
|
925
|
+
if spt.strip()
|
|
926
|
+
]
|
|
927
|
+
|
|
928
|
+
if not spts:
|
|
929
|
+
print("wxpusher 服务的 WXPUSHER_SPT_LIST 不能为空!!")
|
|
930
|
+
return
|
|
931
|
+
if len(spts) > 10:
|
|
932
|
+
print("wxpusher 服务的 WXPUSHER_SPT_LIST 最多支持 10 个!!")
|
|
933
|
+
return
|
|
934
|
+
|
|
935
|
+
print("wxpusher SPT 服务启动")
|
|
936
|
+
|
|
937
|
+
url = "https://wxpusher.zjiecode.com/api/send/message/simple-push"
|
|
938
|
+
|
|
939
|
+
data = {
|
|
940
|
+
"content": f"<h1>{title}</h1><br/><div style='white-space: pre-wrap;'>{content}</div>",
|
|
941
|
+
"summary": title,
|
|
942
|
+
"contentType": 2,
|
|
943
|
+
}
|
|
944
|
+
# 单个 SPT 用 spt,多个用 sptList
|
|
945
|
+
if len(spts) == 1:
|
|
946
|
+
data["spt"] = spts[0]
|
|
947
|
+
else:
|
|
948
|
+
data["sptList"] = spts
|
|
949
|
+
|
|
950
|
+
headers = {"Content-Type": "application/json"}
|
|
951
|
+
response = requests.post(url=url, json=data, headers=headers).json()
|
|
952
|
+
|
|
953
|
+
if response.get("code") == 1000:
|
|
954
|
+
print("wxpusher SPT 推送成功!")
|
|
955
|
+
else:
|
|
956
|
+
print(f"wxpusher SPT 推送失败!错误信息:{response.get('msg')}")
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
def openilink(title: str, content: str) -> None:
|
|
960
|
+
"""
|
|
961
|
+
通过 OpeniLink 推送消息。
|
|
962
|
+
支持的环境变量:
|
|
963
|
+
- OPENILINK_APP_TOKEN: 在 OpeniLink Hub 后台安装 App 后获取的 app_token
|
|
964
|
+
- OPENILINK_HUB_URL: OpeniLink Hub 地址,默认为 https://hub.openilink.com
|
|
965
|
+
- OPENILINK_CONTEXT_TOKEN: 消息会话上下文 token,可从消息事件中获取
|
|
966
|
+
"""
|
|
967
|
+
if not push_config.get("OPENILINK_APP_TOKEN"):
|
|
968
|
+
return
|
|
969
|
+
|
|
970
|
+
print("OpeniLink 服务启动")
|
|
971
|
+
|
|
972
|
+
base_url = (
|
|
973
|
+
push_config.get("OPENILINK_HUB_URL", "").rstrip("/")
|
|
974
|
+
or "https://hub.openilink.com"
|
|
975
|
+
)
|
|
976
|
+
url = f"{base_url}/bot/v1/message/send"
|
|
977
|
+
headers = {
|
|
978
|
+
"Content-Type": "application/json",
|
|
979
|
+
"Authorization": f'Bearer {push_config.get("OPENILINK_APP_TOKEN")}',
|
|
980
|
+
}
|
|
981
|
+
data = {
|
|
982
|
+
"type": "text",
|
|
983
|
+
"content": f"{title}\n\n{content}",
|
|
984
|
+
}
|
|
985
|
+
if push_config.get("OPENILINK_CONTEXT_TOKEN"):
|
|
986
|
+
data["context_token"] = push_config.get("OPENILINK_CONTEXT_TOKEN")
|
|
987
|
+
|
|
988
|
+
response = requests.post(url=url, json=data, headers=headers).json()
|
|
989
|
+
|
|
990
|
+
if response.get("ok"):
|
|
991
|
+
print("OpeniLink 推送成功!")
|
|
992
|
+
else:
|
|
993
|
+
print(f'OpeniLink 推送失败!错误信息:{response.get("error")}')
|
|
994
|
+
|
|
995
|
+
|
|
901
996
|
def parse_headers(headers):
|
|
902
997
|
if not headers:
|
|
903
998
|
return {}
|
|
@@ -1063,6 +1158,10 @@ def add_notify_function():
|
|
|
1063
1158
|
push_config.get("WXPUSHER_TOPIC_IDS") or push_config.get("WXPUSHER_UIDS")
|
|
1064
1159
|
):
|
|
1065
1160
|
notify_function.append(wxpusher_bot)
|
|
1161
|
+
if push_config.get("WXPUSHER_SPT_LIST"):
|
|
1162
|
+
notify_function.append(wxpusher_spt)
|
|
1163
|
+
if push_config.get("OPENILINK_APP_TOKEN"):
|
|
1164
|
+
notify_function.append(openilink)
|
|
1066
1165
|
if not notify_function:
|
|
1067
1166
|
print(f"无推送渠道,请检查通知变量是否正确")
|
|
1068
1167
|
return notify_function
|
|
@@ -1088,7 +1187,7 @@ def send(title: str, content: str, ignore_default_config: bool = False, **kwargs
|
|
|
1088
1187
|
return
|
|
1089
1188
|
|
|
1090
1189
|
hitokoto = push_config.get("HITOKOTO")
|
|
1091
|
-
content += "\n\n" + one() if hitokoto
|
|
1190
|
+
content += "\n\n" + one() if hitokoto not in [False, "false"] else ""
|
|
1092
1191
|
|
|
1093
1192
|
notify_function = add_notify_function()
|
|
1094
1193
|
ts = [
|