Compare commits

..

5 Commits

Author SHA1 Message Date
whyour 09a5652556 测试 2024-03-10 21:00:44 +08:00
whyour 9c47a3c5d2 测试 2024-03-10 20:13:03 +08:00
whyour 7b8ad601f8 测试 2024-03-10 19:50:07 +08:00
whyour ac90b24607 增加 update 服务 2024-03-10 19:16:51 +08:00
秋澪Akimio cdeca4b808 notify.py 支持自定义参数 (#2285)
* Bark自定义参数

* 钉钉机器人自定义参数

* 飞书机器人自定义参数

* go_cqhttp自定义参数

* gotify自定义参数

* iGot自定义参数

* serverJ自定义参数

* PushDeer自定义参数

* Chat自定义参数

* push+自定义参数

* qmsg自定义参数

* 企业微信自定义参数

* 企业微信机器人自定义参数

* telegram自定义参数

* 智能微秘书自定义参数

* SMTP 邮件自定义设置

* PUSHME自定义参数

* CHRONOCAT自定义参数

* 智能微秘书条件判断错误修正
2024-03-05 22:13:38 +08:00
13 changed files with 390 additions and 195 deletions
+1
View File
@@ -1,3 +1,4 @@
UPDATE_PORT=5300
PUBLIC_PORT=5400
CRON_PORT=5500
BACK_PORT=5600
+2 -74
View File
@@ -2,15 +2,8 @@ name: Build And Push Docker Image
on:
push:
paths-ignore:
- "*.md"
branches:
- "master"
- "develop"
tags:
- "v*"
schedule:
- cron: "00 20 * * *"
- "npm-debug"
workflow_dispatch:
jobs:
@@ -163,73 +156,8 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=whyour/qinglong:cache
cache-to: type=registry,ref=whyour/qinglong:cache,mode=max
- name: Image digest
run: |
echo ${{ steps.docker_build.outputs.digest }}
build310:
if: ${{ github.ref_name == 'master' }}
needs: build-static
runs-on: ubuntu-20.04
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: "8.3.1"
- uses: actions/setup-node@v4
with:
cache: "pnpm"
- name: Setup timezone
uses: szenius/set-timezone@v1.2
with:
timezoneLinux: Asia/Shanghai
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push python3.10
id: docker_build_310
uses: docker/build-push-action@v5
with:
build-args: |
MAINTAINER=${{ github.repository_owner }}
QL_BRANCH=${{ github.ref_name }}
SOURCE_COMMIT=${{ github.sha }}
network: host
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,linux/386
context: .
file: ./docker/310.Dockerfile
push: true
tags: whyour/qinglong:python3.10
cache-from: type=registry,ref=whyour/qinglong:cache-python3.10
cache-to: type=registry,ref=whyour/qinglong:cache-python3.10,mode=max
- name: Image digest
run: |
echo ${{ steps.docker_build_310.outputs.digest }}
+5
View File
@@ -16,6 +16,11 @@ export default defineConfig({
favicons: [`https://qn.whyour.cn/favicon.svg`],
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
proxy: {
[`${baseUrl}api/update`]: {
target: 'http://127.0.0.1:5300/',
changeOrigin: true,
pathRewrite: { [`^${baseUrl}api/update`]: '/api' },
},
[`${baseUrl}api/public`]: {
target: 'http://127.0.0.1:5400/',
changeOrigin: true,
+1
View File
@@ -57,6 +57,7 @@ export default {
port: parseInt(process.env.BACK_PORT as string, 10),
cronPort: parseInt(process.env.CRON_PORT as string, 10),
publicPort: parseInt(process.env.PUBLIC_PORT as string, 10),
updatePort: parseInt(process.env.UPDATE_PORT as string, 10),
secret: process.env.SECRET || createRandomString(16, 32),
logs: {
level: process.env.LOG_LEVEL || 'silly',
+93
View File
@@ -0,0 +1,93 @@
import bodyParser from 'body-parser';
import { errors } from 'celebrate';
import cors from 'cors';
import { Application, NextFunction, Request, Response } from 'express';
import jwt from 'express-jwt';
import Container from 'typedi';
import { Logger } from 'winston';
import config from '../config';
import SystemService from '../services/system';
export default ({ app }: { app: Application }) => {
app.set('trust proxy', 'loopback');
app.use(cors());
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
app.use(
jwt({
secret: config.secret,
algorithms: ['HS384'],
}),
);
app.put(
'/api/system',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const systemService = Container.get(SystemService);
const result = await systemService.reloadSystem('system');
res.send(result);
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
app.put(
'/api/data',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const systemService = Container.get(SystemService);
const result = await systemService.reloadSystem('data');
res.send(result);
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
app.use((req, res, next) => {
const err: any = new Error('Not Found');
err['status'] = 404;
next(err);
});
app.use(errors());
app.use(
(
err: Error & { status: number },
req: Request,
res: Response,
next: NextFunction,
) => {
if (err.name === 'UnauthorizedError') {
return res
.status(err.status)
.send({ code: 401, message: err.message })
.end();
}
return next(err);
},
);
app.use(
(
err: Error & { status: number },
req: Request,
res: Response,
next: NextFunction,
) => {
res.status(err.status || 500);
res.json({
code: err.status || 500,
message: err.message,
});
},
);
};
+24
View File
@@ -0,0 +1,24 @@
import 'reflect-metadata'; // We need this in order to use @Decorators
import config from './config';
import express from 'express';
import Logger from './loaders/logger';
async function startServer() {
const app = express();
await require('./loaders/update').default({ app });
app
.listen(config.updatePort, () => {
Logger.debug(`✌️ 更新服务启动成功!`);
console.debug(`✌️ 更新服务启动成功!`);
process.send?.('ready');
})
.on('error', (err) => {
Logger.error(err);
console.error(err);
process.exit(1);
});
}
startServer();
+5 -4
View File
@@ -3,11 +3,11 @@ COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
RUN set -x \
&& apk update \
&& apk add nodejs npm git \
&& npm i -g pnpm@8.3.1 \
&& npm i -g pnpm@8.3.1 pm2 tsx \
&& cd /tmp/build \
&& pnpm install --prod
FROM python:3.11-alpine3.18
FROM python:3.11-alpine
ARG QL_MAINTAINER="whyour"
LABEL maintainer="${QL_MAINTAINER}"
@@ -27,6 +27,9 @@ VOLUME /ql/data
EXPOSE 5700
COPY --from=builder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
COPY --from=builder /usr/local/bin/. /usr/local/bin/
RUN set -x \
&& apk update -f \
&& apk upgrade \
@@ -53,11 +56,9 @@ RUN set -x \
&& git config --global user.email "qinglong@@users.noreply.github.com" \
&& git config --global user.name "qinglong" \
&& git config --global http.postBuffer 524288000 \
&& npm install -g pnpm@8.3.1 pm2 tsx \
&& rm -rf /root/.pnpm-store \
&& rm -rf /root/.local/share/pnpm/store \
&& rm -rf /root/.cache \
&& rm -rf /root/.npm \
&& ulimit -c 0
ARG SOURCE_COMMIT
+16
View File
@@ -6,6 +6,10 @@ upstream publicApi {
server 0.0.0.0:5400;
}
upstream updateApi {
server 0.0.0.0:5300;
}
map $http_upgrade $connection_upgrade {
default keep-alive;
'websocket' upgrade;
@@ -16,6 +20,18 @@ server {
IPV6_CONFIG
ssl_session_timeout 5m;
location QL_BASE_URLapi/update/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://updateApi/api/;
proxy_buffering off;
proxy_redirect default;
proxy_connect_timeout 1800;
proxy_send_timeout 1800;
proxy_read_timeout 1800;
}
location QL_BASE_URLapi/public/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
+9
View File
@@ -1,5 +1,14 @@
module.exports = {
apps: [
{
name: 'update',
max_restarts: 10,
kill_timeout: 15000,
wait_ready: true,
listen_timeout: 10000,
time: true,
script: 'static/build/update.js',
},
{
name: 'schedule',
max_restarts: 10,
+2
View File
@@ -4,6 +4,7 @@
"start": "concurrently -n w: npm:start:*",
"start:front": "max dev",
"start:back": "nodemon",
"start:update": "ts-node -P tsconfig.back.json ./back/update.ts",
"start:public": "ts-node -P tsconfig.back.json ./back/public.ts",
"start:rpc": "ts-node -P tsconfig.back.json ./back/schedule/index.ts",
"build:front": "max build",
@@ -11,6 +12,7 @@
"panel": "npm run build:back && node static/build/app.js",
"schedule": "npm run build:back && node static/build/schedule/index.js",
"public": "npm run build:back && node static/build/public.js",
"update": "npm run build:back && node static/build/update.js",
"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",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"postinstall": "max setup 2>/dev/null || true",
+229 -114
View File
@@ -123,19 +123,19 @@ for k in push_config:
push_config[k] = v
def bark(title: str, content: str) -> None:
def bark(title: str, content: str, **kwargs) -> None:
"""
使用 bark 推送消息。
"""
if not push_config.get("BARK_PUSH"):
if not (push_config.get("BARK_PUSH") or kwargs.get("BARK_PUSH")):
print("bark 服务的 BARK_PUSH 未设置!!\n取消推送")
return
print("bark 服务启动")
if push_config.get("BARK_PUSH").startswith("http"):
url = f'{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}'
BARK_PUSH = kwargs.get("BARK_PUSH", push_config.get("BARK_PUSH"))
if BARK_PUSH.startswith("http"):
url = f'{BARK_PUSH}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}'
else:
url = f'https://api.day.app/{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}'
url = f'https://api.day.app/{BARK_PUSH}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}'
bark_params = {
"BARK_ARCHIVE": "isArchive",
@@ -149,11 +149,12 @@ def bark(title: str, content: str) -> None:
for pair in filter(
lambda pairs: pairs[0].startswith("BARK_")
and pairs[0] != "BARK_PUSH"
and pairs[1]
and (pairs[1] or kwargs.get(pairs[0]))
and bark_params.get(pairs[0]),
push_config.items(),
):
params += f"{bark_params.get(pair[0])}={pair[1]}&"
value = kwargs.get(pair[0], pair[1])
params += f"{bark_params.get(pair[0])}={value}&"
if params:
url = url + "?" + params.rstrip("&")
response = requests.get(url).json()
@@ -164,31 +165,37 @@ def bark(title: str, content: str) -> None:
print("bark 推送失败!")
def console(title: str, content: str) -> None:
def console(title: str, content: str, **kwargs) -> None:
"""
使用 控制台 推送消息。
"""
print(f"{title}\n\n{content}")
def dingding_bot(title: str, content: str) -> None:
def dingding_bot(title: str, content: str, **kwargs) -> None:
"""
使用 钉钉机器人 推送消息。
"""
if not push_config.get("DD_BOT_SECRET") or not push_config.get("DD_BOT_TOKEN"):
if not ((kwargs.get("DD_BOT_SECRET") and kwargs.get("DD_BOT_TOKEN")) or (push_config.get("DD_BOT_SECRET") and push_config.get("DD_BOT_TOKEN"))):
print("钉钉机器人 服务的 DD_BOT_SECRET 或者 DD_BOT_TOKEN 未设置!!\n取消推送")
return
print("钉钉机器人 服务启动")
if kwargs.get("DD_BOT_SECRET") and kwargs.get("DD_BOT_TOKEN"):
DD_BOT_SECRET = kwargs.get("DD_BOT_SECRET")
DD_BOT_TOKEN = kwargs.get("DD_BOT_TOKEN")
else:
DD_BOT_SECRET = push_config.get("DD_BOT_SECRET")
DD_BOT_TOKEN = push_config.get("DD_BOT_TOKEN")
timestamp = str(round(time.time() * 1000))
secret_enc = push_config.get("DD_BOT_SECRET").encode("utf-8")
string_to_sign = "{}\n{}".format(timestamp, push_config.get("DD_BOT_SECRET"))
secret_enc = DD_BOT_SECRET.encode("utf-8")
string_to_sign = "{}\n{}".format(timestamp, DD_BOT_SECRET)
string_to_sign_enc = string_to_sign.encode("utf-8")
hmac_code = hmac.new(
secret_enc, string_to_sign_enc, digestmod=hashlib.sha256
).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
url = f'https://oapi.dingtalk.com/robot/send?access_token={push_config.get("DD_BOT_TOKEN")}&timestamp={timestamp}&sign={sign}'
url = f'https://oapi.dingtalk.com/robot/send?access_token={DD_BOT_TOKEN}&timestamp={timestamp}&sign={sign}'
headers = {"Content-Type": "application/json;charset=utf-8"}
data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}}
response = requests.post(
@@ -201,16 +208,16 @@ def dingding_bot(title: str, content: str) -> None:
print("钉钉机器人 推送失败!")
def feishu_bot(title: str, content: str) -> None:
def feishu_bot(title: str, content: str, **kwargs) -> None:
"""
使用 飞书机器人 推送消息。
"""
if not push_config.get("FSKEY"):
if not (kwargs.get("DD_BOT_SECRET") or push_config.get("FSKEY")):
print("飞书 服务的 FSKEY 未设置!!\n取消推送")
return
print("飞书 服务启动")
url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{push_config.get("FSKEY")}'
FSKEY = kwargs.get("DD_BOT_SECRET", push_config.get("FSKEY"))
url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{FSKEY}'
data = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}}
response = requests.post(url, data=json.dumps(data)).json()
@@ -220,16 +227,24 @@ def feishu_bot(title: str, content: str) -> None:
print("飞书 推送失败!错误信息如下:\n", response)
def go_cqhttp(title: str, content: str) -> None:
def go_cqhttp(title: str, content: str, **kwargs) -> None:
"""
使用 go_cqhttp 推送消息。
"""
if not push_config.get("GOBOT_URL") or not push_config.get("GOBOT_QQ"):
if not ((kwargs.get("GOBOT_URL") and kwargs.get("GOBOT_QQ")) or (push_config.get("GOBOT_URL") and push_config.get("GOBOT_QQ"))):
print("go-cqhttp 服务的 GOBOT_URL 或 GOBOT_QQ 未设置!!\n取消推送")
return
print("go-cqhttp 服务启动")
if kwargs.get("GOBOT_URL") and kwargs.get("GOBOT_QQ"):
GOBOT_URL = kwargs.get("GOBOT_URL")
GOBOT_QQ = kwargs.get("GOBOT_QQ")
GOBOT_TOKEN = kwargs.get("GOBOT_TOKEN")
else:
GOBOT_URL = push_config.get("GOBOT_URL")
GOBOT_QQ = push_config.get("GOBOT_QQ")
GOBOT_TOKEN = push_config.get("GOBOT_TOKEN")
url = f'{push_config.get("GOBOT_URL")}?access_token={push_config.get("GOBOT_TOKEN")}&{push_config.get("GOBOT_QQ")}&message=标题:{title}\n内容:{content}'
url = f'{GOBOT_URL}?access_token={GOBOT_TOKEN}&{GOBOT_QQ}&message=标题:{title}\n内容:{content}'
response = requests.get(url).json()
if response["status"] == "ok":
@@ -238,20 +253,28 @@ def go_cqhttp(title: str, content: str) -> None:
print("go-cqhttp 推送失败!")
def gotify(title: str, content: str) -> None:
def gotify(title: str, content: str, **kwargs) -> None:
"""
使用 gotify 推送消息。
"""
if not push_config.get("GOTIFY_URL") or not push_config.get("GOTIFY_TOKEN"):
if not ((kwargs.get("GOTIFY_URL") and kwargs.get("GOTIFY_TOKEN")) or (push_config.get("GOTIFY_URL") and push_config.get("GOTIFY_TOKEN"))):
print("gotify 服务的 GOTIFY_URL 或 GOTIFY_TOKEN 未设置!!\n取消推送")
return
print("gotify 服务启动")
if kwargs.get("GOTIFY_URL") and kwargs.get("GOTIFY_TOKEN"):
GOTIFY_URL = kwargs.get("GOTIFY_URL")
GOTIFY_TOKEN = kwargs.get("GOBOTGOTIFY_TOKEN_QQ")
GOTIFY_PRIORITY = kwargs.get("GOTIFY_PRIORITY")
else:
GOTIFY_URL = push_config.get("GOTIFY_URL")
GOTIFY_TOKEN = push_config.get("GOTIFY_TOKEN")
GOTIFY_PRIORITY = kwargs.get("GOTIFY_PRIORITY")
url = f'{push_config.get("GOTIFY_URL")}/message?token={push_config.get("GOTIFY_TOKEN")}'
url = f'{GOTIFY_URL}/message?token={GOTIFY_TOKEN}'
data = {
"title": title,
"message": content,
"priority": push_config.get("GOTIFY_PRIORITY"),
"priority": GOTIFY_PRIORITY,
}
response = requests.post(url, data=data).json()
@@ -261,16 +284,16 @@ def gotify(title: str, content: str) -> None:
print("gotify 推送失败!")
def iGot(title: str, content: str) -> None:
def iGot(title: str, content: str, **kwargs) -> None:
"""
使用 iGot 推送消息。
"""
if not push_config.get("IGOT_PUSH_KEY"):
if not (kwargs.get("IGOT_PUSH_KEY") or push_config.get("IGOT_PUSH_KEY")):
print("iGot 服务的 IGOT_PUSH_KEY 未设置!!\n取消推送")
return
print("iGot 服务启动")
url = f'https://push.hellyw.com/{push_config.get("IGOT_PUSH_KEY")}'
IGOT_PUSH_KEY = kwargs.get("IGOT_PUSH_KEY", push_config.get("IGOT_PUSH_KEY"))
url = f'https://push.hellyw.com/{IGOT_PUSH_KEY}'
data = {"title": title, "content": content}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
response = requests.post(url, data=data, headers=headers).json()
@@ -281,20 +304,21 @@ def iGot(title: str, content: str) -> None:
print(f'iGot 推送失败!{response["errMsg"]}')
def serverJ(title: str, content: str) -> None:
def serverJ(title: str, content: str, **kwargs) -> None:
"""
通过 serverJ 推送消息。
"""
if not push_config.get("PUSH_KEY"):
if not (kwargs.get("PUSH_KEY") or push_config.get("PUSH_KEY")):
print("serverJ 服务的 PUSH_KEY 未设置!!\n取消推送")
return
print("serverJ 服务启动")
PUSH_KEY = kwargs.get("PUSH_KEY", push_config.get("PUSH_KEY"))
data = {"text": title, "desp": content.replace("\n", "\n\n")}
if push_config.get("PUSH_KEY").find("SCT") != -1:
url = f'https://sctapi.ftqq.com/{push_config.get("PUSH_KEY")}.send'
if PUSH_KEY.find("SCT") != -1:
url = f'https://sctapi.ftqq.com/{PUSH_KEY}.send'
else:
url = f'https://sc.ftqq.com/{push_config.get("PUSH_KEY")}.send'
url = f'https://sc.ftqq.com/{PUSH_KEY}.send'
response = requests.post(url, data=data).json()
if response.get("errno") == 0 or response.get("code") == 0:
@@ -303,23 +327,27 @@ def serverJ(title: str, content: str) -> None:
print(f'serverJ 推送失败!错误码:{response["message"]}')
def pushdeer(title: str, content: str) -> None:
def pushdeer(title: str, content: str, **kwargs) -> None:
"""
通过PushDeer 推送消息
"""
if not push_config.get("DEER_KEY"):
if not (kwargs.get("DEER_KEY") or push_config.get("DEER_KEY")):
print("PushDeer 服务的 DEER_KEY 未设置!!\n取消推送")
return
print("PushDeer 服务启动")
DEER_KEY = kwargs.get("DEER_KEY", push_config.get("DEER_KEY"))
data = {
"text": title,
"desp": content,
"type": "markdown",
"pushkey": push_config.get("DEER_KEY"),
"pushkey": DEER_KEY,
}
url = "https://api2.pushdeer.com/message/push"
if push_config.get("DEER_URL"):
url = push_config.get("DEER_URL")
if kwargs.get("DEER_URL"):
url = kwargs.get("DEER_URL")
response = requests.post(url, data=data).json()
@@ -329,16 +357,23 @@ def pushdeer(title: str, content: str) -> None:
print("PushDeer 推送失败!错误信息:", response)
def chat(title: str, content: str) -> None:
def chat(title: str, content: str, **kwargs) -> None:
"""
通过Chat 推送消息
"""
if not push_config.get("CHAT_URL") or not push_config.get("CHAT_TOKEN"):
if not ((kwargs.get("CHAT_URL") and kwargs.get("CHAT_TOKEN")) or (push_config.get("CHAT_URL") and push_config.get("CHAT_TOKEN"))):
print("chat 服务的 CHAT_URL或CHAT_TOKEN 未设置!!\n取消推送")
return
print("chat 服务启动")
if kwargs.get("CHAT_URL") and kwargs.get("CHAT_TOKEN"):
CHAT_URL = kwargs.get("CHAT_URL")
CHAT_TOKEN = kwargs.get("CHAT_TOKEN")
else:
CHAT_URL = push_config.get("CHAT_URL")
CHAT_TOKEN = push_config.get("CHAT_TOKEN")
data = "payload=" + json.dumps({"text": title + "\n" + content})
url = push_config.get("CHAT_URL") + push_config.get("CHAT_TOKEN")
url = CHAT_URL + CHAT_TOKEN
response = requests.post(url, data=data)
if response.status_code == 200:
@@ -347,21 +382,23 @@ def chat(title: str, content: str) -> None:
print("Chat 推送失败!错误信息:", response)
def pushplus_bot(title: str, content: str) -> None:
def pushplus_bot(title: str, content: str, **kwargs) -> None:
"""
通过 push+ 推送消息。
"""
if not push_config.get("PUSH_PLUS_TOKEN"):
if not (kwargs.get("PUSH_PLUS_TOKEN") or push_config.get("PUSH_PLUS_TOKEN")):
print("PUSHPLUS 服务的 PUSH_PLUS_TOKEN 未设置!!\n取消推送")
return
print("PUSHPLUS 服务启动")
PUSH_PLUS_TOKEN = kwargs.get("PUSH_PLUS_TOKEN", push_config.get("PUSH_PLUS_TOKEN"))
PUSH_PLUS_USER = kwargs.get("PUSH_PLUS_USER", push_config.get("PUSH_PLUS_USER"))
url = "http://www.pushplus.plus/send"
data = {
"token": push_config.get("PUSH_PLUS_TOKEN"),
"token": PUSH_PLUS_TOKEN,
"title": title,
"content": content,
"topic": push_config.get("PUSH_PLUS_USER"),
"topic": PUSH_PLUS_USER,
}
body = json.dumps(data).encode(encoding="utf-8")
headers = {"Content-Type": "application/json"}
@@ -382,16 +419,22 @@ def pushplus_bot(title: str, content: str) -> None:
print("PUSHPLUS 推送失败!")
def qmsg_bot(title: str, content: str) -> None:
def qmsg_bot(title: str, content: str, **kwargs) -> None:
"""
使用 qmsg 推送消息。
"""
if not push_config.get("QMSG_KEY") or not push_config.get("QMSG_TYPE"):
if not ((kwargs.get("QMSG_KEY") and kwargs.get("QMSG_TYPE")) or (push_config.get("QMSG_KEY") and push_config.get("QMSG_TYPE"))):
print("qmsg 的 QMSG_KEY 或者 QMSG_TYPE 未设置!!\n取消推送")
return
print("qmsg 服务启动")
if kwargs.get("QMSG_KEY") and kwargs.get("QMSG_TYPE"):
QMSG_KEY = kwargs.get("QMSG_KEY")
QMSG_TYPE = kwargs.get("QMSG_TYPE")
else:
QMSG_KEY = push_config.get("QMSG_KEY")
QMSG_TYPE = push_config.get("QMSG_TYPE")
url = f'https://qmsg.zendee.cn/{push_config.get("QMSG_TYPE")}/{push_config.get("QMSG_KEY")}'
url = f'https://qmsg.zendee.cn/{QMSG_TYPE}/{QMSG_KEY}'
payload = {"msg": f'{title}\n\n{content.replace("----", "-")}'.encode("utf-8")}
response = requests.post(url=url, params=payload).json()
@@ -401,14 +444,15 @@ def qmsg_bot(title: str, content: str) -> None:
print(f'qmsg 推送失败!{response["reason"]}')
def wecom_app(title: str, content: str) -> None:
def wecom_app(title: str, content: str, **kwargs) -> None:
"""
通过 企业微信 APP 推送消息。
"""
if not push_config.get("QYWX_AM"):
if not (kwargs.get("QYWX_AM") or push_config.get("QYWX_AM")):
print("QYWX_AM 未设置!!\n取消推送")
return
QYWX_AM_AY = re.split(",", push_config.get("QYWX_AM"))
QYWX_AM = kwargs.get("QYWX_AM", push_config.get("QYWX_AM"))
QYWX_AM_AY = re.split(",", QYWX_AM)
if 4 < len(QYWX_AM_AY) > 5:
print("QYWX_AM 设置错误!!\n取消推送")
return
@@ -498,20 +542,23 @@ class WeCom:
return respone["errmsg"]
def wecom_bot(title: str, content: str) -> None:
def wecom_bot(title: str, content: str, **kwargs) -> None:
"""
通过 企业微信机器人 推送消息。
"""
if not push_config.get("QYWX_KEY"):
if not (kwargs.get("QYWX_KEY") or push_config.get("QYWX_KEY")):
print("企业微信机器人 服务的 QYWX_KEY 未设置!!\n取消推送")
return
print("企业微信机器人服务启动")
QYWX_KEY = kwargs.get("QYWX_KEY", push_config.get("QYWX_KEY"))
origin = "https://qyapi.weixin.qq.com"
if push_config.get("QYWX_ORIGIN"):
origin = push_config.get("QYWX_ORIGIN")
if kwargs.get("QYWX_ORIGIN"):
origin = kwargs.get("QYWX_ORIGIN")
url = f"{origin}/cgi-bin/webhook/send?key={push_config.get('QYWX_KEY')}"
url = f"{origin}/cgi-bin/webhook/send?key={QYWX_KEY}"
headers = {"Content-Type": "application/json;charset=utf-8"}
data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}}
response = requests.post(
@@ -524,39 +571,52 @@ def wecom_bot(title: str, content: str) -> None:
print("企业微信机器人推送失败!")
def telegram_bot(title: str, content: str) -> None:
def telegram_bot(title: str, content: str, **kwargs) -> None:
"""
使用 telegram 机器人 推送消息。
"""
if not push_config.get("TG_BOT_TOKEN") or not push_config.get("TG_USER_ID"):
print("tg 服务的 bot_token 或者 user_id 未设置!!\n取消推送")
if not ((kwargs.get("TG_BOT_TOKEN") and kwargs.get("TG_USER_ID")) or (push_config.get("TG_BOT_TOKEN") and push_config.get("TG_USER_ID"))):
print("tg 服务的 TG_BOT_TOKEN 或者 TG_USER_ID 未设置!!\n取消推送")
return
print("tg 服务启动")
if kwargs.get("TG_BOT_TOKEN") and kwargs.get("TG_USER_ID"):
TG_BOT_TOKEN = kwargs.get("TG_BOT_TOKEN")
TG_USER_ID = kwargs.get("TG_USER_ID")
else:
TG_BOT_TOKEN = push_config.get("TG_BOT_TOKEN")
TG_USER_ID = push_config.get("TG_USER_ID")
if push_config.get("TG_API_HOST"):
url = f"{push_config.get('TG_API_HOST')}/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage"
if kwargs.get("TG_API_HOST") or push_config.get("TG_API_HOST"):
TG_API_HOST = kwargs.get("TG_API_HOST", push_config.get("TG_API_HOST"))
url = f"{TG_API_HOST}/bot{TG_BOT_TOKEN}/sendMessage"
else:
url = (
f"https://api.telegram.org/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage"
f"https://api.telegram.org/bot{TG_BOT_TOKEN}/sendMessage"
)
headers = {"Content-Type": "application/x-www-form-urlencoded"}
payload = {
"chat_id": str(push_config.get("TG_USER_ID")),
"chat_id": str(TG_USER_ID),
"text": f"{title}\n\n{content}",
"disable_web_page_preview": "true",
}
proxies = None
if push_config.get("TG_PROXY_HOST") and push_config.get("TG_PROXY_PORT"):
if push_config.get("TG_PROXY_AUTH") is not None and "@" not in push_config.get(
"TG_PROXY_HOST"
):
push_config["TG_PROXY_HOST"] = (
push_config.get("TG_PROXY_AUTH")
if not ((kwargs.get("TG_PROXY_HOST") and kwargs.get("TG_PROXY_PORT")) or (push_config.get("TG_PROXY_HOST") and push_config.get("TG_PROXY_PORT"))):
if kwargs.get("TG_PROXY_HOST") and kwargs.get("TG_PROXY_PORT"):
TG_PROXY_HOST = kwargs.get("TG_PROXY_HOST")
TG_PROXY_PORT = kwargs.get("TG_PROXY_PORT")
else:
TG_PROXY_HOST = kwargs.get("TG_PROXY_HOST")
TG_PROXY_PORT = kwargs.get("TG_PROXY_PORT")
if kwargs.get("TG_PROXY_AUTH") or push_config.get("TG_PROXY_AUTH"):
TG_PROXY_AUTH = kwargs.get("TG_PROXY_AUTH", push_config.get("TG_PROXY_AUTH"))
if TG_PROXY_AUTH is not None and "@" not in TG_PROXY_HOST:
TG_PROXY_HOST = (
TG_PROXY_AUTH
+ "@"
+ push_config.get("TG_PROXY_HOST")
+ TG_PROXY_HOST
)
proxyStr = "http://{}:{}".format(
push_config.get("TG_PROXY_HOST"), push_config.get("TG_PROXY_PORT")
TG_PROXY_HOST, TG_PROXY_PORT
)
proxies = {"http": proxyStr, "https": proxyStr}
response = requests.post(
@@ -569,33 +629,48 @@ def telegram_bot(title: str, content: str) -> None:
print("tg 推送失败!")
def aibotk(title: str, content: str) -> None:
def aibotk(title: str, content: str, **kwargs) -> None:
"""
使用 智能微秘书 推送消息。
"""
if (
not push_config.get("AIBOTK_KEY")
or not push_config.get("AIBOTK_TYPE")
or not push_config.get("AIBOTK_NAME")
):
if not (
(
kwargs.get("AIBOTK_KEY")
and kwargs.get("AIBOTK_TYPE")
and kwargs.get("AIBOTK_NAME")
)
or
(
push_config.get("AIBOTK_KEY")
and push_config.get("AIBOTK_TYPE")
and push_config.get("AIBOTK_NAME")
)
):
print(
"智能微秘书 的 AIBOTK_KEY 或者 AIBOTK_TYPE 或者 AIBOTK_NAME 未设置!!\n取消推送"
)
return
print("智能微秘书 服务启动")
if push_config.get("AIBOTK_TYPE") == "room":
if kwargs.get("AIBOTK_KEY") and kwargs.get("AIBOTK_TYPE") and kwargs.get("AIBOTK_NAME"):
AIBOTK_KEY = kwargs.get("AIBOTK_KEY")
AIBOTK_TYPE = kwargs.get("AIBOTK_TYPE")
AIBOTK_NAME = kwargs.get("AIBOTK_NAME")
else:
AIBOTK_KEY = push_config.get("AIBOTK_KEY")
AIBOTK_TYPE = push_config.get("AIBOTK_TYPE")
AIBOTK_NAME = push_config.get("AIBOTK_NAME")
if AIBOTK_TYPE == "room":
url = "https://api-bot.aibotk.com/openapi/v1/chat/room"
data = {
"apiKey": push_config.get("AIBOTK_KEY"),
"roomName": push_config.get("AIBOTK_NAME"),
"apiKey": AIBOTK_KEY,
"roomName": AIBOTK_NAME,
"message": {"type": 1, "content": f"【青龙快讯】\n\n{title}\n{content}"},
}
else:
url = "https://api-bot.aibotk.com/openapi/v1/chat/contact"
data = {
"apiKey": push_config.get("AIBOTK_KEY"),
"name": push_config.get("AIBOTK_NAME"),
"apiKey": AIBOTK_KEY,
"name": AIBOTK_NAME,
"message": {"type": 1, "content": f"【青龙快讯】\n\n{title}\n{content}"},
}
body = json.dumps(data).encode(encoding="utf-8")
@@ -608,50 +683,74 @@ def aibotk(title: str, content: str) -> None:
print(f'智能微秘书 推送失败!{response["error"]}')
def smtp(title: str, content: str) -> None:
def smtp(title: str, content: str, **kwargs) -> None:
"""
使用 SMTP 邮件 推送消息。
"""
if (
not push_config.get("SMTP_SERVER")
or not push_config.get("SMTP_SSL")
or not push_config.get("SMTP_EMAIL")
or not push_config.get("SMTP_PASSWORD")
or not push_config.get("SMTP_NAME")
):
if not ((
kwargs.get("SMTP_SERVER")
and kwargs.get("SMTP_SSL")
and kwargs.get("SMTP_EMAIL")
and kwargs.get("SMTP_PASSWORD")
and kwargs.get("SMTP_NAME")
) or (
push_config.get("SMTP_SERVER")
and push_config.get("SMTP_SSL")
and push_config.get("SMTP_EMAIL")
and push_config.get("SMTP_PASSWORD")
and push_config.get("SMTP_NAME")
)):
print(
"SMTP 邮件 的 SMTP_SERVER 或者 SMTP_SSL 或者 SMTP_EMAIL 或者 SMTP_PASSWORD 或者 SMTP_NAME 未设置!!\n取消推送"
)
return
print("SMTP 邮件 服务启动")
if (
kwargs.get("SMTP_SERVER")
and kwargs.get("SMTP_SSL")
and kwargs.get("SMTP_EMAIL")
and kwargs.get("SMTP_PASSWORD")
and kwargs.get("SMTP_NAME")
):
SMTP_SERVER = kwargs.get("SMTP_SERVER")
SMTP_SSL = kwargs.get("SMTP_SSL")
SMTP_EMAIL = kwargs.get("SMTP_EMAIL")
SMTP_PASSWORD = kwargs.get("SMTP_PASSWORD")
SMTP_NAME = kwargs.get("SMTP_NAME")
else:
SMTP_SERVER = push_config.get("SMTP_SERVER")
SMTP_SSL = push_config.get("SMTP_SSL")
SMTP_EMAIL = push_config.get("SMTP_EMAIL")
SMTP_PASSWORD = push_config.get("SMTP_PASSWORD")
SMTP_NAME = push_config.get("SMTP_NAME")
message = MIMEText(content, "plain", "utf-8")
message["From"] = formataddr(
(
Header(push_config.get("SMTP_NAME"), "utf-8").encode(),
push_config.get("SMTP_EMAIL"),
Header(SMTP_NAME, "utf-8").encode(),
SMTP_EMAIL,
)
)
message["To"] = formataddr(
(
Header(push_config.get("SMTP_NAME"), "utf-8").encode(),
push_config.get("SMTP_EMAIL"),
Header(SMTP_NAME, "utf-8").encode(),
SMTP_EMAIL,
)
)
message["Subject"] = Header(title, "utf-8")
try:
smtp_server = (
smtplib.SMTP_SSL(push_config.get("SMTP_SERVER"))
if push_config.get("SMTP_SSL") == "true"
else smtplib.SMTP(push_config.get("SMTP_SERVER"))
smtplib.SMTP_SSL(SMTP_SERVER)
if SMTP_SSL == "true"
else smtplib.SMTP(SMTP_SERVER)
)
smtp_server.login(
push_config.get("SMTP_EMAIL"), push_config.get("SMTP_PASSWORD")
SMTP_EMAIL, SMTP_PASSWORD
)
smtp_server.sendmail(
push_config.get("SMTP_EMAIL"),
push_config.get("SMTP_EMAIL"),
SMTP_EMAIL,
SMTP_EMAIL,
message.as_bytes(),
)
smtp_server.close()
@@ -660,16 +759,17 @@ def smtp(title: str, content: str) -> None:
print(f"SMTP 邮件 推送失败!{e}")
def pushme(title: str, content: str) -> None:
def pushme(title: str, content: str, **kwargs) -> None:
"""
使用 PushMe 推送消息。
"""
if not push_config.get("PUSHME_KEY"):
if not (kwargs.get("PUSHME_KEY") or push_config.get("PUSHME_KEY")):
print("PushMe 服务的 PUSHME_KEY 未设置!!\n取消推送")
return
print("PushMe 服务启动")
PUSHME_KEY = kwargs.get("PUSHME_KEY", push_config.get("PUSHME_KEY"))
url = f'https://push.i-i.me/?push_key={push_config.get("PUSHME_KEY")}'
url = f'https://push.i-i.me/?push_key={PUSHME_KEY}'
data = {
"title": title,
"content": content,
@@ -682,27 +782,42 @@ def pushme(title: str, content: str) -> None:
print(f"PushMe 推送失败!{response.status_code} {response.text}")
def chronocat(title: str, content: str) -> None:
def chronocat(title: str, content: str, **kwargs) -> None:
"""
使用 CHRONOCAT 推送消息。
"""
if (
not push_config.get("CHRONOCAT_URL")
or not push_config.get("CHRONOCAT_QQ")
or not push_config.get("CHRONOCAT_TOKEN")
):
if not ((
push_config.get("CHRONOCAT_URL")
and push_config.get("CHRONOCAT_QQ")
and push_config.get("CHRONOCAT_TOKEN")
) or (
push_config.get("CHRONOCAT_URL")
and push_config.get("CHRONOCAT_QQ")
and push_config.get("CHRONOCAT_TOKEN")
)):
print("CHRONOCAT 服务的 CHRONOCAT_URL 或 CHRONOCAT_QQ 未设置!!\n取消推送")
return
print("CHRONOCAT 服务启动")
if (
kwargs.get("CHRONOCAT_URL")
and kwargs.get("CHRONOCAT_QQ")
and kwargs.get("CHRONOCAT_TOKEN")
):
CHRONOCAT_URL = kwargs.get("CHRONOCAT_URL")
CHRONOCAT_QQ = kwargs.get("CHRONOCAT_QQ")
CHRONOCAT_TOKEN = kwargs.get("CHRONOCAT_TOKEN")
else:
CHRONOCAT_URL = push_config.get("CHRONOCAT_URL")
CHRONOCAT_QQ = push_config.get("CHRONOCAT_QQ")
CHRONOCAT_TOKEN = push_config.get("CHRONOCAT_TOKEN")
user_ids = re.findall(r"user_id=(\d+)", push_config.get("CHRONOCAT_QQ"))
group_ids = re.findall(r"group_id=(\d+)", push_config.get("CHRONOCAT_QQ"))
user_ids = re.findall(r"user_id=(\d+)", CHRONOCAT_QQ)
group_ids = re.findall(r"group_id=(\d+)", CHRONOCAT_QQ)
url = f'{push_config.get("CHRONOCAT_URL")}/api/message/send'
url = f'{CHRONOCAT_URL}/api/message/send'
headers = {
"Content-Type": "application/json",
"Authorization": f'Bearer {push_config.get("CHRONOCAT_TOKEN")}',
"Authorization": f'Bearer {CHRONOCAT_TOKEN}',
}
for chat_type, ids in [(1, user_ids), (2, group_ids)]:
@@ -896,7 +1011,7 @@ def add_notify_function():
notify_function.append(custom_notify)
def send(title: str, content: str) -> None:
def send(title: str, content: str, **kwargs) -> None:
if not content:
print(f"{title} 推送内容为空!")
return
@@ -913,7 +1028,7 @@ def send(title: str, content: str) -> None:
add_notify_function()
ts = [
threading.Thread(target=mode, args=(title, content), name=mode.__name__)
threading.Thread(target=mode, args=(title, content),kwargs=kwargs, name=mode.__name__)
for mode in notify_function
]
[t.start() for t in ts]
+2 -2
View File
@@ -116,7 +116,7 @@ const CheckUpdate = ({ systemInfo }: any) => {
const reloadSystem = (type?: string) => {
request
.put(`${config.apiPrefix}system/reload`, { type })
.put(`${config.apiPrefix}update/${type}`)
.then((_data: any) => {
message.success({
content: (
@@ -220,7 +220,7 @@ const CheckUpdate = ({ systemInfo }: any) => {
</Button>
<Button
type="primary"
onClick={() => reloadSystem()}
onClick={() => reloadSystem('system')}
style={{ marginLeft: 8 }}
>
{intl.get('重新启动')}
+1 -1
View File
@@ -141,7 +141,7 @@ const Other = ({
okText: intl.get('重启'),
onOk() {
request
.put(`${config.apiPrefix}system/reload`, { type: 'data' })
.put(`${config.apiPrefix}update/data`)
.then(() => {
message.success({
content: (