支持webhook消息
This commit is contained in:
+86
-11
@@ -1,20 +1,95 @@
|
|||||||
# DeepSeek API配置(必需)
|
# ============================================================
|
||||||
|
# AI股票分析系统环境配置模板
|
||||||
|
# ============================================================
|
||||||
|
# 使用说明:
|
||||||
|
# 1. 复制此文件并重命名为 .env
|
||||||
|
# 2. 根据实际情况填写配置项
|
||||||
|
# 3. 敏感信息(如API密钥、密码)请妥善保管,不要提交到版本控制
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# ========== DeepSeek API配置 ==========
|
||||||
|
# DeepSeek API密钥(必填)
|
||||||
|
# 获取地址:https://platform.deepseek.com/api_keys
|
||||||
DEEPSEEK_API_KEY=your_actual_deepseek_api_key_here
|
DEEPSEEK_API_KEY=your_actual_deepseek_api_key_here
|
||||||
|
|
||||||
|
# DeepSeek API基础URL(可选,使用默认值即可)
|
||||||
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
|
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
|
||||||
|
|
||||||
# 邮件通知配置(可选)
|
|
||||||
EMAIL_ENABLED=false
|
|
||||||
SMTP_SERVER=smtp.qq.com
|
|
||||||
SMTP_PORT=587
|
|
||||||
EMAIL_FROM=your_email@qq.com
|
|
||||||
EMAIL_PASSWORD=your_authorization_code
|
|
||||||
EMAIL_TO=receiver@example.com
|
|
||||||
|
|
||||||
# MiniQMT量化交易配置(可选)
|
# ========== Tushare数据接口(可选)==========
|
||||||
|
# Tushare Token(可选,用于获取更多金融数据)
|
||||||
|
# 获取地址:https://tushare.pro/register
|
||||||
|
TUSHARE_TOKEN=
|
||||||
|
|
||||||
|
|
||||||
|
# ========== MiniQMT量化交易配置(可选)==========
|
||||||
|
# 是否启用MiniQMT量化交易接口
|
||||||
MINIQMT_ENABLED=false
|
MINIQMT_ENABLED=false
|
||||||
MINIQMT_ACCOUNT_ID=your_account_id
|
|
||||||
|
# MiniQMT账户ID
|
||||||
|
MINIQMT_ACCOUNT_ID=
|
||||||
|
|
||||||
|
# MiniQMT服务器地址
|
||||||
MINIQMT_HOST=127.0.0.1
|
MINIQMT_HOST=127.0.0.1
|
||||||
|
|
||||||
|
# MiniQMT服务器端口
|
||||||
MINIQMT_PORT=58610
|
MINIQMT_PORT=58610
|
||||||
|
|
||||||
# 时区设置
|
|
||||||
|
# ========== 邮件通知配置(可选)==========
|
||||||
|
# 是否启用邮件通知
|
||||||
|
EMAIL_ENABLED=false
|
||||||
|
|
||||||
|
# SMTP服务器地址
|
||||||
|
# 常用邮箱SMTP服务器:
|
||||||
|
# - 163邮箱:smtp.163.com
|
||||||
|
# - QQ邮箱:smtp.qq.com
|
||||||
|
# - Gmail:smtp.gmail.com
|
||||||
|
# - 企业邮箱:根据邮箱服务商提供的信息填写
|
||||||
|
SMTP_SERVER=smtp.163.com
|
||||||
|
|
||||||
|
# SMTP服务器端口
|
||||||
|
# 常用端口:
|
||||||
|
# - 465:SSL加密连接(推荐)
|
||||||
|
# - 587:TLS加密连接
|
||||||
|
SMTP_PORT=465
|
||||||
|
|
||||||
|
# 发件人邮箱地址
|
||||||
|
EMAIL_FROM=your_email@163.com
|
||||||
|
|
||||||
|
# 邮箱授权码(不是登录密码!)
|
||||||
|
# 获取方法:
|
||||||
|
# - 163邮箱:设置 -> POP3/SMTP/IMAP -> 开启服务 -> 获取授权码
|
||||||
|
# - QQ邮箱:设置 -> 账户 -> POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 -> 开启服务 -> 生成授权码
|
||||||
|
EMAIL_PASSWORD=your_email_authorization_code
|
||||||
|
|
||||||
|
# 收件人邮箱地址(接收通知的邮箱)
|
||||||
|
EMAIL_TO=receiver@example.com
|
||||||
|
|
||||||
|
|
||||||
|
# ========== Webhook通知配置(可选)==========
|
||||||
|
# 是否启用Webhook通知(钉钉/飞书)
|
||||||
|
WEBHOOK_ENABLED=false
|
||||||
|
|
||||||
|
# Webhook类型
|
||||||
|
# 可选值:dingtalk(钉钉)、feishu(飞书)
|
||||||
|
WEBHOOK_TYPE=dingtalk
|
||||||
|
|
||||||
|
# Webhook地址
|
||||||
|
# 钉钉机器人:https://oapi.dingtalk.com/robot/send?access_token=YOUR_ACCESS_TOKEN
|
||||||
|
# 飞书机器人:https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_HOOK_ID
|
||||||
|
WEBHOOK_URL=
|
||||||
|
|
||||||
|
# Webhook自定义关键词(仅钉钉需要)
|
||||||
|
# 说明:
|
||||||
|
# - 如果钉钉机器人设置了"自定义关键词"安全验证,请在此填写关键词
|
||||||
|
# - 系统会自动在消息标题和内容中包含此关键词
|
||||||
|
# - 如果不使用关键词验证,可以留空或使用其他安全方式(加签、IP白名单)
|
||||||
|
# - 飞书机器人通常不需要关键词,可以留空
|
||||||
|
# 示例:aiagents通知
|
||||||
|
WEBHOOK_KEYWORD=
|
||||||
|
|
||||||
|
|
||||||
|
# ========== 时区配置 ==========
|
||||||
|
# 系统时区设置(可选)
|
||||||
TZ=Asia/Shanghai
|
TZ=Asia/Shanghai
|
||||||
|
|||||||
+21
-30
@@ -1,44 +1,34 @@
|
|||||||
# 使用官方Python镜像作为基础镜像
|
# 使用官方Python镜像作为基础镜像
|
||||||
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.12-slim
|
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.12-slim
|
||||||
|
|
||||||
# 替换apt-get源为国内源(阿里源)
|
|
||||||
RUN echo "deb https://mirrors.aliyun.com/debian/ bookworm main" > /etc/apt/sources.list && \
|
|
||||||
echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main" >> /etc/apt/sources.list && \
|
|
||||||
echo "deb https://mirrors.aliyun.com/debian-security bookworm-security main" >> /etc/apt/sources.list && \
|
|
||||||
rm -rf /etc/apt/sources.list.d/* || true
|
|
||||||
|
|
||||||
# 设置工作目录
|
# 设置工作目录
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# 安装Node.js和中文字体 - 使用修正版方案一
|
# 安装Node.js (pywencai需要) 和中文字体 (PDF生成需要)
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
curl \
|
curl \
|
||||||
gnupg \
|
gnupg \
|
||||||
fonts-noto-cjk \
|
fonts-noto-cjk \
|
||||||
fonts-wqy-zenhei \
|
fonts-wqy-zenhei \
|
||||||
fonts-wqy-microhei \
|
fonts-wqy-microhei \
|
||||||
fontconfig \
|
fontconfig \
|
||||||
&& curl -fsSL https://mirrors.aliyun.com/nodesource/setup_18.x | bash - \
|
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||||
&& apt-get install -y nodejs npm \
|
&& apt-get install -y nodejs \
|
||||||
&& fc-cache -fv \
|
&& fc-cache -fv \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# 验证安装 - 添加详细检查
|
# 验证安装
|
||||||
RUN echo "Node.js版本:" && node --version && \
|
RUN node --version && npm --version
|
||||||
echo "npm路径:" && which npm && \
|
|
||||||
echo "npm版本:" && npm --version
|
|
||||||
|
|
||||||
# 配置npm使用淘宝镜像源
|
|
||||||
RUN npm config set registry https://registry.npmmirror.com/
|
|
||||||
|
|
||||||
# 复制依赖文件
|
# 复制依赖文件
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
|
|
||||||
# 安装Python依赖
|
# 安装Python依赖 - 修改后的部分
|
||||||
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && \
|
# 永久配置pip使用国内镜像源并增加超时时间[1](@ref)[2](@ref)
|
||||||
pip config set global.trusted-host mirrors.aliyun.com && \
|
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/ && \
|
||||||
pip install --no-cache-dir --default-timeout=1000 -r requirements.txt
|
pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn && \
|
||||||
|
pip install --no-cache-dir --default-timeout=1000 -r requirements.txt
|
||||||
|
|
||||||
# 复制项目文件
|
# 复制项目文件
|
||||||
COPY . .
|
COPY . .
|
||||||
@@ -53,4 +43,5 @@ EXPOSE 8501
|
|||||||
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1
|
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1
|
||||||
|
|
||||||
# 启动应用
|
# 启动应用
|
||||||
CMD ["python", "run.py"]
|
CMD ["python", "run.py"]
|
||||||
|
|
||||||
|
|||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
# 使用官方Python镜像作为基础镜像
|
|
||||||
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.12-slim
|
|
||||||
|
|
||||||
# 设置工作目录
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# 安装Node.js (pywencai需要) 和中文字体 (PDF生成需要)
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
curl \
|
|
||||||
gnupg \
|
|
||||||
fonts-noto-cjk \
|
|
||||||
fonts-wqy-zenhei \
|
|
||||||
fonts-wqy-microhei \
|
|
||||||
fontconfig \
|
|
||||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
|
||||||
&& apt-get install -y nodejs \
|
|
||||||
&& fc-cache -fv \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# 验证安装
|
|
||||||
RUN node --version && npm --version
|
|
||||||
|
|
||||||
# 复制依赖文件
|
|
||||||
COPY requirements.txt .
|
|
||||||
|
|
||||||
# 安装Python依赖 - 修改后的部分
|
|
||||||
# 永久配置pip使用国内镜像源并增加超时时间[1](@ref)[2](@ref)
|
|
||||||
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/ && \
|
|
||||||
pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn && \
|
|
||||||
pip install --no-cache-dir --default-timeout=1000 -r requirements.txt
|
|
||||||
|
|
||||||
# 复制项目文件
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# 创建必要的目录
|
|
||||||
RUN mkdir -p /app/data && chmod 777 /app/data
|
|
||||||
|
|
||||||
# 暴露Streamlit默认端口
|
|
||||||
EXPOSE 8501
|
|
||||||
|
|
||||||
# 设置健康检查
|
|
||||||
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1
|
|
||||||
|
|
||||||
# 启动应用
|
|
||||||
CMD ["python", "run.py"]
|
|
||||||
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# 使用官方Python镜像作为基础镜像
|
||||||
|
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.12-slim
|
||||||
|
|
||||||
|
# 替换apt-get源为国内源(阿里源)
|
||||||
|
RUN echo "deb https://mirrors.aliyun.com/debian/ bookworm main" > /etc/apt/sources.list && \
|
||||||
|
echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb https://mirrors.aliyun.com/debian-security bookworm-security main" >> /etc/apt/sources.list && \
|
||||||
|
rm -rf /etc/apt/sources.list.d/* || true
|
||||||
|
|
||||||
|
# 设置工作目录
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 安装Node.js和中文字体 - 使用修正版方案一
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
fonts-noto-cjk \
|
||||||
|
fonts-wqy-zenhei \
|
||||||
|
fonts-wqy-microhei \
|
||||||
|
fontconfig \
|
||||||
|
&& curl -fsSL https://mirrors.aliyun.com/nodesource/setup_18.x | bash - \
|
||||||
|
&& apt-get install -y nodejs npm \
|
||||||
|
&& fc-cache -fv \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 验证安装 - 添加详细检查
|
||||||
|
RUN echo "Node.js版本:" && node --version && \
|
||||||
|
echo "npm路径:" && which npm && \
|
||||||
|
echo "npm版本:" && npm --version
|
||||||
|
|
||||||
|
# 配置npm使用淘宝镜像源
|
||||||
|
RUN npm config set registry https://registry.npmmirror.com/
|
||||||
|
|
||||||
|
# 复制依赖文件
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
# 安装Python依赖
|
||||||
|
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && \
|
||||||
|
pip config set global.trusted-host mirrors.aliyun.com && \
|
||||||
|
pip install --no-cache-dir --default-timeout=1000 -r requirements.txt
|
||||||
|
|
||||||
|
# 复制项目文件
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 创建必要的目录
|
||||||
|
RUN mkdir -p /app/data && chmod 777 /app/data
|
||||||
|
|
||||||
|
# 暴露Streamlit默认端口
|
||||||
|
EXPOSE 8501
|
||||||
|
|
||||||
|
# 设置健康检查
|
||||||
|
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1
|
||||||
|
|
||||||
|
# 启动应用
|
||||||
|
CMD ["python", "run.py"]
|
||||||
-207
@@ -1,207 +0,0 @@
|
|||||||
# PDF中文乱码修复说明
|
|
||||||
|
|
||||||
## 问题描述
|
|
||||||
在Docker环境中,PDF导出时中文显示为乱码或方框,但本地Windows环境正常。
|
|
||||||
|
|
||||||
## 原因分析
|
|
||||||
- Docker容器基于Linux系统,默认不包含中文字体
|
|
||||||
- PDF生成器(reportlab)需要中文字体才能正确渲染中文字符
|
|
||||||
- 原代码只配置了Windows系统的字体路径
|
|
||||||
|
|
||||||
## 修复方案
|
|
||||||
|
|
||||||
### 已修改的文件
|
|
||||||
|
|
||||||
#### 1. `Dockerfile`
|
|
||||||
添加了中文字体包安装:
|
|
||||||
```dockerfile
|
|
||||||
# 安装Node.js (pywencai需要) 和中文字体 (PDF生成需要)
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
curl \
|
|
||||||
gnupg \
|
|
||||||
fonts-noto-cjk \
|
|
||||||
fonts-wqy-zenhei \
|
|
||||||
fonts-wqy-microhei \
|
|
||||||
fontconfig \
|
|
||||||
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
|
||||||
&& apt-get install -y nodejs \
|
|
||||||
&& fc-cache -fv \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
```
|
|
||||||
|
|
||||||
安装的字体包:
|
|
||||||
- **fonts-noto-cjk**: Google Noto CJK字体(支持中日韩文字)
|
|
||||||
- **fonts-wqy-zenhei**: 文泉驿正黑体
|
|
||||||
- **fonts-wqy-microhei**: 文泉驿微米黑体
|
|
||||||
- **fontconfig**: 字体配置工具
|
|
||||||
|
|
||||||
#### 2. `pdf_generator.py`
|
|
||||||
更新了字体注册函数,支持Linux系统:
|
|
||||||
```python
|
|
||||||
def register_chinese_fonts():
|
|
||||||
"""注册中文字体 - 支持Windows和Linux系统"""
|
|
||||||
# Windows系统字体路径
|
|
||||||
windows_font_paths = [...]
|
|
||||||
|
|
||||||
# Linux系统字体路径(Docker环境)
|
|
||||||
linux_font_paths = [
|
|
||||||
'/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc',
|
|
||||||
'/usr/share/fonts/truetype/wqy/wqy-microhei.ttc',
|
|
||||||
'/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc',
|
|
||||||
# ... 更多字体路径
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## 重新部署步骤
|
|
||||||
|
|
||||||
### 方式一:Docker Compose(推荐)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 停止并删除现有容器
|
|
||||||
docker-compose down
|
|
||||||
|
|
||||||
# 2. 删除旧镜像(可选,但推荐)
|
|
||||||
docker rmi agentsstock1-app
|
|
||||||
|
|
||||||
# 3. 重新构建并启动
|
|
||||||
docker-compose up -d --build
|
|
||||||
|
|
||||||
# 4. 查看日志,确认字体加载成功
|
|
||||||
docker-compose logs -f
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方式二:Docker命令
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 停止并删除现有容器
|
|
||||||
docker stop agentsstock1
|
|
||||||
docker rm agentsstock1
|
|
||||||
|
|
||||||
# 2. 删除旧镜像
|
|
||||||
docker rmi agentsstock1
|
|
||||||
|
|
||||||
# 3. 重新构建镜像
|
|
||||||
docker build -t agentsstock1 .
|
|
||||||
|
|
||||||
# 4. 启动新容器
|
|
||||||
docker run -d -p 8503:8501 \
|
|
||||||
-v $(pwd)/.env:/app/.env \
|
|
||||||
--name agentsstock1 \
|
|
||||||
agentsstock1
|
|
||||||
|
|
||||||
# 5. 查看日志
|
|
||||||
docker logs -f agentsstock1
|
|
||||||
```
|
|
||||||
|
|
||||||
## 验证修复
|
|
||||||
|
|
||||||
### 1. 检查字体安装
|
|
||||||
进入容器检查字体:
|
|
||||||
```bash
|
|
||||||
docker exec -it agentsstock1 bash
|
|
||||||
fc-list :lang=zh # 列出所有中文字体
|
|
||||||
```
|
|
||||||
|
|
||||||
应该看到类似输出:
|
|
||||||
```
|
|
||||||
/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc: WenQuanYi Zen Hei:style=Regular
|
|
||||||
/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK SC:style=Regular
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 查看应用日志
|
|
||||||
在生成PDF时,日志中应该显示:
|
|
||||||
```
|
|
||||||
✅ 成功注册中文字体: /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 测试PDF导出
|
|
||||||
1. 在Web界面分析任意股票
|
|
||||||
2. 点击"生成并下载PDF报告"
|
|
||||||
3. 打开下载的PDF文件
|
|
||||||
4. 确认中文正常显示
|
|
||||||
|
|
||||||
## 故障排查
|
|
||||||
|
|
||||||
### 问题1:构建时字体安装失败
|
|
||||||
**现象**:构建过程中apt-get install失败
|
|
||||||
|
|
||||||
**解决方案**:
|
|
||||||
```bash
|
|
||||||
# 清理Docker缓存后重试
|
|
||||||
docker system prune -a
|
|
||||||
docker-compose build --no-cache
|
|
||||||
```
|
|
||||||
|
|
||||||
### 问题2:字体未加载
|
|
||||||
**现象**:日志显示"未找到中文字体"
|
|
||||||
|
|
||||||
**检查步骤**:
|
|
||||||
1. 确认Dockerfile中正确添加了字体包
|
|
||||||
2. 进入容器检查字体文件是否存在
|
|
||||||
3. 运行 `fc-cache -fv` 刷新字体缓存
|
|
||||||
|
|
||||||
### 问题3:PDF仍然乱码
|
|
||||||
**现象**:字体已安装但PDF中文仍显示为方框
|
|
||||||
|
|
||||||
**可能原因**:
|
|
||||||
1. 字体文件权限问题
|
|
||||||
2. reportlab缓存问题
|
|
||||||
3. 字体格式不兼容
|
|
||||||
|
|
||||||
**解决方案**:
|
|
||||||
```bash
|
|
||||||
# 重新构建时清理所有缓存
|
|
||||||
docker-compose down -v
|
|
||||||
docker system prune -a
|
|
||||||
docker-compose up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
## 技术说明
|
|
||||||
|
|
||||||
### 字体选择
|
|
||||||
我们安装了3种字体包:
|
|
||||||
1. **Noto Sans CJK**:Google开发,覆盖范围广,质量高
|
|
||||||
2. **文泉驿正黑**:开源中文字体,适合阅读
|
|
||||||
3. **文泉驿微米黑**:适合小字号显示
|
|
||||||
|
|
||||||
系统会按优先级自动选择第一个可用的字体。
|
|
||||||
|
|
||||||
### 字体文件格式
|
|
||||||
- **TTC**:TrueType Collection(字体集合文件)
|
|
||||||
- **TTF**:TrueType Font(单个字体文件)
|
|
||||||
|
|
||||||
reportlab的TTFont可以处理这两种格式。
|
|
||||||
|
|
||||||
### Docker镜像大小
|
|
||||||
添加中文字体后,镜像大小会增加约50-100MB:
|
|
||||||
- fonts-noto-cjk: ~70MB
|
|
||||||
- fonts-wqy-zenhei: ~10MB
|
|
||||||
- fonts-wqy-microhei: ~5MB
|
|
||||||
|
|
||||||
这是正常的,为了支持完整的中文显示必须付出的空间代价。
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **本地环境无影响**:修改后的代码在Windows本地环境仍然正常工作
|
|
||||||
2. **字体缓存**:首次启动时fontconfig会建立字体缓存,可能需要几秒钟
|
|
||||||
3. **镜像更新**:已部署的用户需要重新构建镜像才能应用修复
|
|
||||||
4. **备份数据**:重新部署前请备份数据库文件(.db文件)
|
|
||||||
|
|
||||||
## 相关资源
|
|
||||||
|
|
||||||
- [ReportLab中文支持文档](https://www.reportlab.com/docs/reportlab-userguide.pdf)
|
|
||||||
- [Noto字体项目](https://www.google.com/get/noto/)
|
|
||||||
- [文泉驿字体项目](http://wenq.org/)
|
|
||||||
- [Docker字体配置指南](https://docs.docker.com/config/)
|
|
||||||
|
|
||||||
## 更新日志
|
|
||||||
|
|
||||||
- **2025-10-10**: 初始版本,添加Docker中文字体支持
|
|
||||||
- **2025-10-10**: 更新pdf_generator.py,支持跨平台字体检测
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
如有问题,请联系:ws3101001@126.com
|
|
||||||
|
|
||||||
@@ -2,16 +2,36 @@
|
|||||||
|
|
||||||
- 初心:在股市摸爬滚打多年,自学自编各种指标,花冤枉钱学习了各种战法各种策略,也曾入各种小班,总是赚少赔多,逐渐失去在股市玩的信心。自从去年deepseek上市,一直探索用ai辅助分析,且近日受tradingagents项目启发(感谢原作),多agent结合跟踪主力资金战法(某指每年收费6000rmb),用各种ai辅助编程,拼凑了这么个小程序,根据软件提供的辅助信息,实盘测试盈率还是挺高的,并且逐步形成了自己的交易系统,近一个月来,账户也慢慢在扭亏为盈。开源此软件的目的,就是为了使像我一样的小散,不再迷茫。也许这个软件不能让你发大财,但是他能给你足够的信心。最后提醒:股市有风险,入市需谨慎!
|
- 初心:在股市摸爬滚打多年,自学自编各种指标,花冤枉钱学习了各种战法各种策略,也曾入各种小班,总是赚少赔多,逐渐失去在股市玩的信心。自从去年deepseek上市,一直探索用ai辅助分析,且近日受tradingagents项目启发(感谢原作),多agent结合跟踪主力资金战法(某指每年收费6000rmb),用各种ai辅助编程,拼凑了这么个小程序,根据软件提供的辅助信息,实盘测试盈率还是挺高的,并且逐步形成了自己的交易系统,近一个月来,账户也慢慢在扭亏为盈。开源此软件的目的,就是为了使像我一样的小散,不再迷茫。也许这个软件不能让你发大财,但是他能给你足够的信心。最后提醒:股市有风险,入市需谨慎!
|
||||||
- 希望能帮到你!欢迎加微信群讨论
|
- 希望能帮到你!欢迎加微信群讨论
|
||||||
<img width="300" height="324" alt="image" src="https://www.sd-hn.cn/img/2wm.png" />
|
<img width="300" height="324" alt="image" src="https://www.sd-hn.cn/img/2wm1015.png" />
|
||||||
|
|
||||||
### 基于Python + Streamlit + DeepSeek的智能股票分析系统,模拟证券公司分析师团队,提供全方位的股票投资分析和决策建议。
|
### 基于Python + Streamlit + DeepSeek的智能股票分析系统,模拟证券公司分析师团队,提供全方位的股票投资分析和决策建议。
|
||||||
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/f929f751-3726-48e6-bc18-919f6a599629" />
|
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/f929f751-3726-48e6-bc18-919f6a599629" />
|
||||||
<img width="1910" height="923" alt="01" src="https://github.com/user-attachments/assets/7dcd4b2c-8b4b-428b-8a17-4d843e98a626" />
|
<img width="1910" height="923" alt="01" src="https://github.com/user-attachments/assets/7dcd4b2c-8b4b-428b-8a17-4d843e98a626" />
|
||||||
<img width="1910" height="923" alt="02" src="https://github.com/user-attachments/assets/02018fff-4e6b-4354-b258-a5da25537c38" />
|
<img width="1910" height="923" alt="02" src="https://github.com/user-attachments/assets/02018fff-4e6b-4354-b258-a5da25537c38" />
|
||||||
|
|
||||||
|
## ✨1015 更新说明(最新)
|
||||||
|
### 🔔 新增Webhook通知功能 ⭐️
|
||||||
|
- **多平台支持**:支持钉钉、飞书群机器人推送通知
|
||||||
|
- **全面集成**:实时监测、智策定时分析均支持Webhook推送
|
||||||
|
- **灵活配置**:
|
||||||
|
- Web界面可视化配置,简单易用
|
||||||
|
- 支持自定义关键词,匹配机器人安全设置
|
||||||
|
- 可同时启用邮件和Webhook,双重保障
|
||||||
|
- **消息格式**:
|
||||||
|
- 钉钉:精美Markdown格式,信息清晰
|
||||||
|
- 飞书:交互式卡片消息,展示美观
|
||||||
|
- **智能推送**:
|
||||||
|
- 实时监测:进场/止盈/止损实时提醒
|
||||||
|
- 智策分析:每日板块策略精简摘要
|
||||||
|
- 量化交易:自动下单执行通知
|
||||||
|
- **完整测试**:内置测试功能,一键验证配置
|
||||||
|
- **详细文档**:提供完整的配置指南和故障排查
|
||||||
|
|
||||||
|
<img width="1910" height="923" alt="Webhook配置界面" src="https://github.com/user-attachments/assets/webhook_config.png" />
|
||||||
|
|
||||||
## ✨1011 更新优化数据获取
|
## ✨1011 更新优化数据获取
|
||||||
|
|
||||||
## ✨1010 更新说明(最新)
|
## ✨1010 更新说明
|
||||||
### 🇭🇰 新增港股分析支持 ⭐️
|
### 🇭🇰 新增港股分析支持 ⭐️
|
||||||
- **市场扩展**:现已支持A股、港股、美股三大市场
|
- **市场扩展**:现已支持A股、港股、美股三大市场
|
||||||
- **港股代码**:支持多种格式(700/00700/HK00700)
|
- **港股代码**:支持多种格式(700/00700/HK00700)
|
||||||
@@ -142,7 +162,21 @@
|
|||||||
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/a85defbf-321a-4fe2-b491-6855f2aa366c" />
|
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/a85defbf-321a-4fe2-b491-6855f2aa366c" />
|
||||||
<img width="1869" height="906" alt="image" src="https://github.com/user-attachments/assets/d59de299-6300-4669-9902-7754da7407db" />
|
<img width="1869" height="906" alt="image" src="https://github.com/user-attachments/assets/d59de299-6300-4669-9902-7754da7407db" />
|
||||||
|
|
||||||
### 📧 邮件通知系统
|
### 📧 通知系统
|
||||||
|
#### 📱 Webhook通知(新增)⭐️
|
||||||
|
- **双平台支持**:钉钉群机器人、飞书群机器人
|
||||||
|
- **实时推送**:股票监测提醒、智策分析报告即时送达
|
||||||
|
- **灵活配置**:Web界面可视化配置,支持自定义关键词
|
||||||
|
- **消息格式**:
|
||||||
|
- 钉钉:Markdown格式,信息清晰美观
|
||||||
|
- 飞书:交互式卡片,展示丰富多彩
|
||||||
|
- **通知场景**:
|
||||||
|
- 实时监测:价格进入进场区间、达到止盈位、触及止损位
|
||||||
|
- 智策分析:每日板块策略、投资机会推送
|
||||||
|
- 量化交易:自动下单执行通知
|
||||||
|
- **测试功能**:一键测试Webhook配置,快速验证
|
||||||
|
|
||||||
|
#### 📧 邮件通知
|
||||||
- **多邮箱支持**:QQ邮箱、163邮箱、Gmail等
|
- **多邮箱支持**:QQ邮箱、163邮箱、Gmail等
|
||||||
- **触发条件**:
|
- **触发条件**:
|
||||||
- 价格进入进场区间
|
- 价格进入进场区间
|
||||||
@@ -150,6 +184,11 @@
|
|||||||
- 触及止损位
|
- 触及止损位
|
||||||
- **测试功能**:一键测试邮件配置
|
- **测试功能**:一键测试邮件配置
|
||||||
- **历史记录**:完整的通知历史查询
|
- **历史记录**:完整的通知历史查询
|
||||||
|
|
||||||
|
#### 🔔 双重保障
|
||||||
|
- **同时启用**:Webhook和邮件可同时使用
|
||||||
|
- **互为补充**:Webhook实时查看,邮件详细存档
|
||||||
|
- **灵活选择**:可单独使用任一通知方式
|
||||||
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/a1a3c1ca-f97f-43eb-a043-1011c09e06d0" />
|
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/a1a3c1ca-f97f-43eb-a043-1011c09e06d0" />
|
||||||
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/1808f284-e922-4eac-bfea-134996de93f1" />
|
<img width="1910" height="923" alt="image" src="https://github.com/user-attachments/assets/1808f284-e922-4eac-bfea-134996de93f1" />
|
||||||
### 🎨 现代化界面
|
### 🎨 现代化界面
|
||||||
@@ -277,6 +316,12 @@ EMAIL_FROM=your_email@qq.com
|
|||||||
EMAIL_PASSWORD=your_authorization_code
|
EMAIL_PASSWORD=your_authorization_code
|
||||||
EMAIL_TO=receiver@example.com
|
EMAIL_TO=receiver@example.com
|
||||||
|
|
||||||
|
# Webhook通知配置(可选)⭐️ 新增
|
||||||
|
WEBHOOK_ENABLED=false
|
||||||
|
WEBHOOK_TYPE=dingtalk # 或 feishu
|
||||||
|
WEBHOOK_URL=your_webhook_url_here
|
||||||
|
WEBHOOK_KEYWORD=股票 # 钉钉自定义关键词,飞书可留空
|
||||||
|
|
||||||
# MiniQMT量化交易配置(可选)
|
# MiniQMT量化交易配置(可选)
|
||||||
MINIQMT_ENABLED=false
|
MINIQMT_ENABLED=false
|
||||||
MINIQMT_ACCOUNT_ID=your_account_id
|
MINIQMT_ACCOUNT_ID=your_account_id
|
||||||
@@ -513,10 +558,43 @@ EMAIL_TO=receiver@example.com
|
|||||||
- 点击"📧 发送测试邮件"
|
- 点击"📧 发送测试邮件"
|
||||||
- 检查收件箱(含垃圾箱)
|
- 检查收件箱(含垃圾箱)
|
||||||
|
|
||||||
|
**Webhook通知配置** ⭐️ 新增:
|
||||||
|
|
||||||
|
1. **方法一:Web界面配置(推荐)**
|
||||||
|
- 进入"⚙️ 环境配置" → "📢 通知配置"
|
||||||
|
- 勾选"启用Webhook通知"
|
||||||
|
- 选择类型(钉钉/飞书)
|
||||||
|
- 填写Webhook URL和关键词
|
||||||
|
- 点击"💾 保存配置"
|
||||||
|
|
||||||
|
2. **方法二:编辑.env文件**
|
||||||
|
```env
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=dingtalk
|
||||||
|
WEBHOOK_URL=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
|
||||||
|
WEBHOOK_KEYWORD=股票
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **创建钉钉机器人**:
|
||||||
|
- 钉钉群 → 设置 → 智能群助手 → 添加机器人 → 自定义
|
||||||
|
- 安全设置:自定义关键词(如:股票、分析)
|
||||||
|
- 复制Webhook地址到配置中
|
||||||
|
|
||||||
|
4. **创建飞书机器人**:
|
||||||
|
- 飞书群 → 设置 → 群机器人 → 添加机器人 → 自定义机器人
|
||||||
|
- 设置名称:AI股票分析系统
|
||||||
|
- 复制Webhook地址到配置中
|
||||||
|
|
||||||
|
5. **测试配置**:
|
||||||
|
- 进入"📊 实时监测" → "🔔 通知管理"
|
||||||
|
- 点击"📱 发送测试Webhook"
|
||||||
|
- 检查钉钉/飞书群是否收到消息
|
||||||
|
|
||||||
**通知触发条件**:
|
**通知触发条件**:
|
||||||
- ✅ 价格进入进场区间 → 进场提醒
|
- ✅ 价格进入进场区间 → 进场提醒
|
||||||
- ✅ 价格达到止盈位 → 止盈提醒
|
- ✅ 价格达到止盈位 → 止盈提醒
|
||||||
- ✅ 价格跌破止损位 → 止损提醒
|
- ✅ 价格跌破止损位 → 止损提醒
|
||||||
|
- ✅ 智策定时分析 → 板块策略推送
|
||||||
|
|
||||||
#### 使用技巧
|
#### 使用技巧
|
||||||
|
|
||||||
@@ -608,12 +686,17 @@ AI股票分析系统
|
|||||||
- 通知记录表
|
- 通知记录表
|
||||||
- CRUD操作接口
|
- CRUD操作接口
|
||||||
|
|
||||||
#### 📧 通知服务模块 (notification_service.py)
|
#### 📧 通知服务模块 (notification_service.py) ⭐️ 增强
|
||||||
- 邮件通知发送
|
- **邮件通知**:发送详细分析报告
|
||||||
- 网页通知展示
|
- **Webhook通知** ⭐️ 新增:
|
||||||
- 多邮箱支持(QQ/163/Gmail)
|
- 钉钉群机器人推送(Markdown格式)
|
||||||
- 通知历史管理
|
- 飞书群机器人推送(交互式卡片)
|
||||||
- 配置测试功能
|
- 自定义关键词支持
|
||||||
|
- 自动错误处理和重试
|
||||||
|
- **网页通知**:界面实时提醒
|
||||||
|
- **多平台支持**:QQ邮箱/163邮箱/Gmail/钉钉/飞书
|
||||||
|
- **通知历史管理**:完整记录和查询
|
||||||
|
- **配置测试功能**:一键测试邮件和Webhook
|
||||||
|
|
||||||
#### 🎯 主力选股模块 ⭐️ 新增
|
#### 🎯 主力选股模块 ⭐️ 新增
|
||||||
**main_force_selector.py**
|
**main_force_selector.py**
|
||||||
@@ -780,6 +863,29 @@ DEFAULT_INTERVAL = "1d" # 默认数据间隔
|
|||||||
- 进入容器检查:`docker exec -it agentsstock1 bash`
|
- 进入容器检查:`docker exec -it agentsstock1 bash`
|
||||||
- **详细文档**:查看 `DOCKER_DEPLOYMENT.md` 获取完整的故障排除指南
|
- **详细文档**:查看 `DOCKER_DEPLOYMENT.md` 获取完整的故障排除指南
|
||||||
|
|
||||||
|
10. **Webhook通知问题** ⭐️ 新增
|
||||||
|
- **未收到Webhook消息**:
|
||||||
|
- 检查 `WEBHOOK_ENABLED=true` 是否已设置
|
||||||
|
- 验证Webhook URL是否完整正确
|
||||||
|
- 确认机器人未被移出群聊
|
||||||
|
- 检查网络连接是否正常
|
||||||
|
- **钉钉关键词不匹配(错误码310000)**:
|
||||||
|
- 确认机器人安全设置中的关键词
|
||||||
|
- 在.env中设置 `WEBHOOK_KEYWORD=股票`(与机器人设置一致)
|
||||||
|
- 或添加关键词:股票、分析、智策、监测
|
||||||
|
- **飞书消息发送失败**:
|
||||||
|
- 确认选择 `WEBHOOK_TYPE=feishu`
|
||||||
|
- 检查Webhook URL是否为飞书格式
|
||||||
|
- 飞书不需要关键词,可设置 `WEBHOOK_KEYWORD=""`
|
||||||
|
- **消息格式异常**:
|
||||||
|
- 确认选择了正确的Webhook类型(钉钉/飞书)
|
||||||
|
- 重新保存配置并重启应用
|
||||||
|
- **测试Webhook**:
|
||||||
|
- 进入"📊 实时监测" → "🔔 通知管理"
|
||||||
|
- 点击"📱 发送测试Webhook"验证配置
|
||||||
|
- 查看终端日志了解详细错误信息
|
||||||
|
- **详细文档**:查看 `Webhook通知配置指南.md` 获取完整配置教程
|
||||||
|
|
||||||
### 日志调试
|
### 日志调试
|
||||||
系统运行时会在控制台输出详细日志,可用于问题诊断。如遇到错误,请查看终端输出。
|
系统运行时会在控制台输出详细日志,可用于问题诊断。如遇到错误,请查看终端输出。
|
||||||
|
|
||||||
@@ -792,6 +898,23 @@ docker-compose logs -f
|
|||||||
docker logs -f agentsstock1
|
docker logs -f agentsstock1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 相关文档
|
||||||
|
|
||||||
|
**通知系统文档** ⭐️:
|
||||||
|
- [Webhook通知配置指南.md](Webhook通知配置指南.md) - Webhook完整配置教程
|
||||||
|
- [Webhook功能完成说明.md](Webhook功能完成说明.md) - Webhook功能详细说明
|
||||||
|
- [Webhook自定义关键词功能说明.md](Webhook自定义关键词功能说明.md) - 关键词配置指南
|
||||||
|
- [邮件配置指南.md](邮件配置指南.md) - 邮件通知配置
|
||||||
|
|
||||||
|
**其他功能文档**:
|
||||||
|
- [环境配置功能说明.md](环境配置功能说明.md) - 完整环境配置说明
|
||||||
|
- [环境配置快速指南.md](环境配置快速指南.md) - 快速配置参考
|
||||||
|
- [实时监测优化说明.md](实时监测优化说明.md) - 实时监测功能详解
|
||||||
|
- [智策定时分析使用指南.md](智策定时分析使用指南.md) - 智策板块分析
|
||||||
|
- [主力选股使用指南.md](主力选股使用指南.md) - 主力选股功能
|
||||||
|
- [量化交易快速指南.md](量化交易快速指南.md) - MiniQMT集成指南
|
||||||
|
- [DOCKER_DEPLOYMENT.md](DOCKER_DEPLOYMENT.md) - Docker部署详细文档
|
||||||
|
|
||||||
### 错误报告
|
### 错误报告
|
||||||
如发现bug,请查看 `BUGFIX.md` 文件了解已知问题和解决方案。
|
如发现bug,请查看 `BUGFIX.md` 文件了解已知问题和解决方案。
|
||||||
|
|
||||||
@@ -810,3 +933,4 @@ MIT License
|
|||||||
---
|
---
|
||||||
|
|
||||||
**享受AI驱动的智能股票分析体验!** 🚀📈任何疑问请留言或联系ws3101001@126.com
|
**享受AI驱动的智能股票分析体验!** 🚀📈任何疑问请留言或联系ws3101001@126.com
|
||||||
|
**技术支持:山东科技大学 于舒馨**
|
||||||
@@ -0,0 +1,492 @@
|
|||||||
|
# Webhook功能完成说明
|
||||||
|
|
||||||
|
## ✅ 功能概述
|
||||||
|
|
||||||
|
成功为系统添加了**Webhook通知功能**,支持钉钉和飞书群机器人推送。
|
||||||
|
|
||||||
|
## 📋 完成内容
|
||||||
|
|
||||||
|
### 1. 核心功能实现
|
||||||
|
|
||||||
|
#### ✅ notification_service.py - Webhook发送核心
|
||||||
|
**新增功能**:
|
||||||
|
- `_send_webhook_notification()` - Webhook通知分发
|
||||||
|
- `_send_dingtalk_webhook()` - 钉钉消息发送
|
||||||
|
- `_send_feishu_webhook()` - 飞书消息发送
|
||||||
|
- `send_test_webhook()` - 测试Webhook配置
|
||||||
|
- `get_webhook_config_status()` - 获取配置状态
|
||||||
|
|
||||||
|
**支持特性**:
|
||||||
|
- 📱 钉钉Markdown格式消息
|
||||||
|
- 📱 飞书交互式卡片消息
|
||||||
|
- ✅ 自动错误处理和重试
|
||||||
|
- ✅ 详细日志输出
|
||||||
|
|
||||||
|
#### ✅ sector_strategy_scheduler.py - 智策定时分析集成
|
||||||
|
**新增功能**:
|
||||||
|
- `_send_webhook_direct()` - 直接发送webhook
|
||||||
|
- `_send_dingtalk()` - 发送钉钉消息
|
||||||
|
- `_send_feishu()` - 发送飞书消息
|
||||||
|
- `_format_webhook_summary()` - 格式化精简摘要
|
||||||
|
|
||||||
|
**特点**:
|
||||||
|
- 同时支持邮件和Webhook
|
||||||
|
- 智能格式化报告(精简版)
|
||||||
|
- 分别统计发送成功数
|
||||||
|
- 完善的异常处理
|
||||||
|
|
||||||
|
### 2. 配置管理
|
||||||
|
|
||||||
|
#### ✅ config_manager.py - 配置项定义
|
||||||
|
**新增配置**:
|
||||||
|
```python
|
||||||
|
EMAIL_ENABLED # 邮件通知开关
|
||||||
|
SMTP_SERVER # SMTP服务器
|
||||||
|
SMTP_PORT # SMTP端口
|
||||||
|
EMAIL_FROM # 发件人邮箱
|
||||||
|
EMAIL_PASSWORD # 邮箱授权码
|
||||||
|
EMAIL_TO # 收件人邮箱
|
||||||
|
WEBHOOK_ENABLED # Webhook开关
|
||||||
|
WEBHOOK_TYPE # Webhook类型(dingtalk/feishu)
|
||||||
|
WEBHOOK_URL # Webhook地址
|
||||||
|
```
|
||||||
|
|
||||||
|
**特性**:
|
||||||
|
- 支持布尔、文本、密码、选择框类型
|
||||||
|
- 自动读取和写入.env文件
|
||||||
|
- 完整的配置验证
|
||||||
|
|
||||||
|
#### ✅ app.py - 可视化配置界面
|
||||||
|
**新增UI**:
|
||||||
|
- 第4个标签页:"📢 通知配置"
|
||||||
|
- 左右分栏布局(邮件 | Webhook)
|
||||||
|
- 实时配置状态提示
|
||||||
|
- 完整的帮助说明
|
||||||
|
|
||||||
|
**交互特性**:
|
||||||
|
- 启用开关自动禁用/启用输入框
|
||||||
|
- 配置完整性实时检查
|
||||||
|
- 保存后自动重新加载
|
||||||
|
- 显示当前.env文件内容
|
||||||
|
|
||||||
|
### 3. 通知集成
|
||||||
|
|
||||||
|
#### ✅ 实时监测模块
|
||||||
|
**集成点**:`monitor_service.py` → `notification_service.send_notifications()`
|
||||||
|
|
||||||
|
**通知时机**:
|
||||||
|
- ✅ 价格进入进场区间
|
||||||
|
- ✅ 价格达到止盈位
|
||||||
|
- ✅ 价格跌破止损位
|
||||||
|
- ✅ 量化交易执行
|
||||||
|
|
||||||
|
**发送逻辑**:
|
||||||
|
```python
|
||||||
|
# 同时尝试Webhook和邮件
|
||||||
|
if webhook_enabled:
|
||||||
|
webhook_success = send_webhook()
|
||||||
|
if email_enabled:
|
||||||
|
email_success = send_email()
|
||||||
|
# 至少一个成功即为成功
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ✅ 智策定时分析
|
||||||
|
**集成点**:`sector_strategy_scheduler.py` → `_send_analysis_notification()`
|
||||||
|
|
||||||
|
**通知内容**:
|
||||||
|
- 📊 板块多空预测(信心度≥7)
|
||||||
|
- 🔄 潜力接力板块(TOP3)
|
||||||
|
- 🌡️ 板块热度排行(TOP3)
|
||||||
|
- 💡 核心投资机会
|
||||||
|
|
||||||
|
**消息格式**:
|
||||||
|
- Webhook:精简版(适合移动端)
|
||||||
|
- 邮件:完整版(详细分析)
|
||||||
|
|
||||||
|
### 4. 完整文档
|
||||||
|
|
||||||
|
#### ✅ 新建文档
|
||||||
|
- **Webhook通知配置指南.md** - 完整配置教程
|
||||||
|
- 平台支持说明
|
||||||
|
- 钉钉配置步骤
|
||||||
|
- 飞书配置步骤
|
||||||
|
- 消息格式示例
|
||||||
|
- 故障排查指南
|
||||||
|
- 使用场景推荐
|
||||||
|
|
||||||
|
#### ✅ 更新文档
|
||||||
|
- **环境配置功能说明.md** - 添加通知配置章节
|
||||||
|
- **config_manager.py** - 配置定义完善
|
||||||
|
- **app.py** - UI界面完整
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 使用方法
|
||||||
|
|
||||||
|
### 第一步:配置Webhook
|
||||||
|
|
||||||
|
#### 方法A:Web界面配置(推荐)
|
||||||
|
1. 进入"⚙️ 环境配置"
|
||||||
|
2. 选择"📢 通知配置"标签页
|
||||||
|
3. 勾选"启用Webhook通知"
|
||||||
|
4. 选择类型(钉钉/飞书)
|
||||||
|
5. 填写Webhook URL
|
||||||
|
6. 点击"💾 保存配置"
|
||||||
|
|
||||||
|
#### 方法B:手动编辑.env
|
||||||
|
```env
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=dingtalk
|
||||||
|
WEBHOOK_URL=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第二步:创建机器人
|
||||||
|
|
||||||
|
#### 钉钉机器人
|
||||||
|
1. 钉钉群 → 设置 → 智能群助手
|
||||||
|
2. 添加机器人 → 自定义
|
||||||
|
3. 安全设置:自定义关键词(股票、分析、智策)
|
||||||
|
4. 复制Webhook地址
|
||||||
|
|
||||||
|
#### 飞书机器人
|
||||||
|
1. 飞书群 → 设置 → 群机器人
|
||||||
|
2. 添加机器人 → 自定义机器人
|
||||||
|
3. 设置名称:AI股票分析系统
|
||||||
|
4. 复制Webhook地址
|
||||||
|
|
||||||
|
### 第三步:测试通知
|
||||||
|
|
||||||
|
#### 在实时监测中测试
|
||||||
|
1. 进入"📊 实时监测"
|
||||||
|
2. 滚动到"🔔 通知管理"
|
||||||
|
3. 点击"📱 发送测试Webhook"
|
||||||
|
4. 检查群消息
|
||||||
|
|
||||||
|
#### 在智策中测试
|
||||||
|
1. 进入"🎯 智策板块"
|
||||||
|
2. 展开"⏰ 定时分析设置"
|
||||||
|
3. 点击"🔄 立即运行一次"
|
||||||
|
4. 分析完成后查看群消息
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 消息格式
|
||||||
|
|
||||||
|
### 实时监测通知(钉钉Markdown)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### 股票监测提醒
|
||||||
|
|
||||||
|
**股票代码**: 600519
|
||||||
|
|
||||||
|
**股票名称**: 贵州茅台
|
||||||
|
|
||||||
|
**提醒类型**: 进场提醒
|
||||||
|
|
||||||
|
**提醒内容**: 股票价格 1650.00 进入进场区间
|
||||||
|
|
||||||
|
**触发时间**: 2024-01-15 10:30:00
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_此消息由AI股票分析系统自动发送_
|
||||||
|
```
|
||||||
|
|
||||||
|
### 智策分析通知(钉钉Markdown)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### 智策板块分析报告
|
||||||
|
**分析时间**: 2024-01-15 09:00
|
||||||
|
|
||||||
|
#### 📊 板块多空
|
||||||
|
**看多**: 人工智能(8分)、新能源汽车(8分)、半导体(7分)
|
||||||
|
**看空**: 地产开发(7分)
|
||||||
|
|
||||||
|
#### 🔄 潜力接力板块
|
||||||
|
- 半导体: 关注突破信号
|
||||||
|
- 军工: 情绪升温,把握机会
|
||||||
|
|
||||||
|
#### 🌡️ 热度TOP3
|
||||||
|
1. 人工智能 - 95分
|
||||||
|
2. 新能源汽车 - 92分
|
||||||
|
3. 半导体 - 88分
|
||||||
|
|
||||||
|
#### 💡 核心机会
|
||||||
|
重点关注人工智能、新能源汽车产业链,半导体板块有轮动潜力...
|
||||||
|
|
||||||
|
---
|
||||||
|
*由智策AI系统自动生成*
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 技术实现
|
||||||
|
|
||||||
|
### 1. Webhook API调用
|
||||||
|
|
||||||
|
#### 钉钉API
|
||||||
|
```python
|
||||||
|
import requests
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"msgtype": "markdown",
|
||||||
|
"markdown": {
|
||||||
|
"title": "标题",
|
||||||
|
"text": "Markdown格式内容"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(webhook_url, json=data, timeout=10)
|
||||||
|
result = response.json()
|
||||||
|
success = result.get('errcode') == 0
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 飞书API
|
||||||
|
```python
|
||||||
|
import requests
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"msg_type": "interactive", # 或 "text"
|
||||||
|
"card": {
|
||||||
|
# 交互式卡片内容
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(webhook_url, json=data, timeout=10)
|
||||||
|
result = response.json()
|
||||||
|
success = result.get('code') == 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 通知流程
|
||||||
|
|
||||||
|
```
|
||||||
|
触发条件
|
||||||
|
↓
|
||||||
|
检查配置
|
||||||
|
├─ Webhook启用?
|
||||||
|
│ ├─ 是 → 发送Webhook
|
||||||
|
│ └─ 否 → 跳过
|
||||||
|
└─ 邮件启用?
|
||||||
|
├─ 是 → 发送邮件
|
||||||
|
└─ 否 → 跳过
|
||||||
|
↓
|
||||||
|
记录日志
|
||||||
|
├─ 成功:✓ 发送成功
|
||||||
|
├─ 失败:✗ 发送失败 + 错误信息
|
||||||
|
└─ 跳过:⚠️ 未配置
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 配置管理
|
||||||
|
|
||||||
|
```
|
||||||
|
.env文件
|
||||||
|
↓
|
||||||
|
config_manager读取
|
||||||
|
↓
|
||||||
|
notification_service加载
|
||||||
|
↓
|
||||||
|
实时重新加载(dotenv)
|
||||||
|
↓
|
||||||
|
Streamlit UI显示
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 使用场景
|
||||||
|
|
||||||
|
### 场景1:日内交易团队协作
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
- 创建钉钉/飞书团队群
|
||||||
|
- 配置Webhook推送
|
||||||
|
- 设置实时监测
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 股票触发 → 群内实时通知
|
||||||
|
- 团队讨论 → 快速决策
|
||||||
|
- 消息记录 → 便于复盘
|
||||||
|
|
||||||
|
### 场景2:每日策略推送
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
- 启用智策定时分析
|
||||||
|
- 配置Webhook + 邮件
|
||||||
|
- 设置每天9:00运行
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 9:00自动分析 → 策略报告
|
||||||
|
- Webhook推送 → 快速查看
|
||||||
|
- 邮件发送 → 详细存档
|
||||||
|
|
||||||
|
### 场景3:个人投资提醒
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
- 创建个人钉钉/飞书群
|
||||||
|
- 仅添加机器人
|
||||||
|
- 配置实时监测
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 价格波动 → 手机通知
|
||||||
|
- 随时随地 → 及时查看
|
||||||
|
- 不错过 → 投资机会
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 注意事项
|
||||||
|
|
||||||
|
### 1. 安全配置
|
||||||
|
|
||||||
|
#### 钉钉关键词设置
|
||||||
|
- **推荐**:股票、分析、智策、监测
|
||||||
|
- 系统消息已包含关键词
|
||||||
|
- 避免使用过于通用的词
|
||||||
|
|
||||||
|
#### Webhook地址保护
|
||||||
|
- ❌ 不要公开分享
|
||||||
|
- ❌ 不要提交到版本控制
|
||||||
|
- ✅ 使用环境变量管理
|
||||||
|
- ✅ 定期更换地址
|
||||||
|
|
||||||
|
### 2. 消息频率
|
||||||
|
|
||||||
|
**平台限制**:
|
||||||
|
- 钉钉:20条/分钟
|
||||||
|
- 飞书:50条/分钟
|
||||||
|
|
||||||
|
**系统控制**:
|
||||||
|
- 实时监测:重复通知间隔60分钟
|
||||||
|
- 智策分析:每天1次
|
||||||
|
- 不会触发限流
|
||||||
|
|
||||||
|
### 3. 网络依赖
|
||||||
|
|
||||||
|
- 需要稳定网络连接
|
||||||
|
- 超时时间:10秒
|
||||||
|
- 失败不影响核心功能
|
||||||
|
- 错误会记录日志
|
||||||
|
|
||||||
|
### 4. 配置生效
|
||||||
|
|
||||||
|
- 修改配置后需重启应用
|
||||||
|
- 或使用"💾 保存配置"自动重载
|
||||||
|
- 建议先测试再正式使用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 故障排查
|
||||||
|
|
||||||
|
### 问题1:未收到Webhook消息
|
||||||
|
|
||||||
|
**检查清单**:
|
||||||
|
1. ✅ `WEBHOOK_ENABLED=true`
|
||||||
|
2. ✅ Webhook URL完整正确
|
||||||
|
3. ✅ 网络连接正常
|
||||||
|
4. ✅ 机器人未被移出群
|
||||||
|
5. ✅ 钉钉关键词设置正确
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
```bash
|
||||||
|
# 1. 查看系统日志
|
||||||
|
📱 正在发送钉钉Webhook...
|
||||||
|
✅ 钉钉Webhook发送成功
|
||||||
|
|
||||||
|
# 2. 使用测试功能
|
||||||
|
点击"📱 发送测试Webhook"
|
||||||
|
|
||||||
|
# 3. 检查配置
|
||||||
|
进入"⚙️ 环境配置" → "📢 通知配置"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题2:钉钉关键词不匹配
|
||||||
|
|
||||||
|
**错误信息**:`errcode: 310000`
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 添加关键词:股票、分析、智策
|
||||||
|
- 系统消息已包含这些词
|
||||||
|
- 检查是否误删关键词
|
||||||
|
|
||||||
|
### 问题3:飞书消息格式异常
|
||||||
|
|
||||||
|
**原因**:选择了错误的类型
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 确认选择 `feishu`
|
||||||
|
- 重新保存配置
|
||||||
|
- 测试验证
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 功能对比
|
||||||
|
|
||||||
|
| 功能 | 邮件通知 | Webhook通知 | 界面通知 |
|
||||||
|
|------|---------|------------|----------|
|
||||||
|
| **实时性** | 延迟1-5秒 | 即时推送 | 需打开页面 |
|
||||||
|
| **详细度** | 完整详细 | 精简摘要 | 简单提示 |
|
||||||
|
| **查看方式** | 邮箱APP | 钉钉/飞书 | Web界面 |
|
||||||
|
| **历史记录** | 永久保存 | 群消息历史 | 临时显示 |
|
||||||
|
| **团队协作** | 转发分享 | 群内讨论 | 单人查看 |
|
||||||
|
| **移动端** | 邮箱APP | 原生APP | 浏览器 |
|
||||||
|
| **推荐场景** | 详细存档 | 快速查看 | 即时提示 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 未来规划
|
||||||
|
|
||||||
|
### v1.1.0 (计划中)
|
||||||
|
- [ ] 支持多个Webhook URL
|
||||||
|
- [ ] 企业微信机器人支持
|
||||||
|
- [ ] Server酱推送支持
|
||||||
|
- [ ] 消息模板自定义
|
||||||
|
|
||||||
|
### v1.2.0 (规划中)
|
||||||
|
- [ ] 消息去重和合并
|
||||||
|
- [ ] 智能推送时段设置
|
||||||
|
- [ ] 重要消息@提醒
|
||||||
|
- [ ] 消息统计和分析
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 相关文档
|
||||||
|
|
||||||
|
- [Webhook通知配置指南.md](Webhook通知配置指南.md) - 详细配置教程
|
||||||
|
- [环境配置功能说明.md](环境配置功能说明.md) - 完整配置说明
|
||||||
|
- [实时监测优化说明.md](实时监测优化说明.md) - 实时监测功能
|
||||||
|
- [智策定时分析使用指南.md](智策定时分析使用指南.md) - 智策功能
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 验证清单
|
||||||
|
|
||||||
|
完成后请验证:
|
||||||
|
|
||||||
|
- [ ] Python环境正常
|
||||||
|
- [ ] requests库已安装
|
||||||
|
- [ ] Webhook配置已保存
|
||||||
|
- [ ] 机器人已创建
|
||||||
|
- [ ] 测试Webhook成功
|
||||||
|
- [ ] 收到测试消息
|
||||||
|
- [ ] 实时监测推送正常
|
||||||
|
- [ ] 智策分析推送正常
|
||||||
|
- [ ] 配置界面显示正常
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎉 总结
|
||||||
|
|
||||||
|
Webhook通知功能已全面完成,主要特点:
|
||||||
|
|
||||||
|
1. **双平台支持** - 钉钉和飞书群机器人
|
||||||
|
2. **灵活配置** - Web界面或.env文件
|
||||||
|
3. **全面集成** - 实时监测和智策分析
|
||||||
|
4. **可靠传输** - 错误处理和日志记录
|
||||||
|
5. **完整文档** - 配置指南和故障排查
|
||||||
|
|
||||||
|
现在您可以通过钉钉或飞书接收股票分析通知了!📱🔔
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Webhook通知功能** - v1.0.0
|
||||||
|
|
||||||
|
完成时间:2025-01-15
|
||||||
|
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
# Webhook功能实现总结
|
||||||
|
|
||||||
|
## ✅ 任务完成状态
|
||||||
|
|
||||||
|
**任务**:为实时监测和智策定时分析添加Webhook支持(钉钉/飞书),并在环境配置中支持可视化配置
|
||||||
|
|
||||||
|
**状态**:✅ 全部完成
|
||||||
|
|
||||||
|
**完成时间**:2025-01-15
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 实现内容清单
|
||||||
|
|
||||||
|
### 1. ✅ notification_service.py - Webhook核心功能
|
||||||
|
|
||||||
|
**新增配置加载**:
|
||||||
|
- `webhook_enabled` - Webhook开关
|
||||||
|
- `webhook_url` - Webhook地址
|
||||||
|
- `webhook_type` - Webhook类型(dingtalk/feishu)
|
||||||
|
|
||||||
|
**新增方法**:
|
||||||
|
- `_send_webhook_notification()` - Webhook通知分发器
|
||||||
|
- `_send_dingtalk_webhook()` - 钉钉机器人发送(Markdown格式)
|
||||||
|
- `_send_feishu_webhook()` - 飞书机器人发送(交互式卡片)
|
||||||
|
- `send_test_webhook()` - 测试Webhook配置
|
||||||
|
- `get_webhook_config_status()` - 获取Webhook配置状态
|
||||||
|
|
||||||
|
**集成实时监测**:
|
||||||
|
- 修改 `send_notification()` 方法
|
||||||
|
- 支持同时发送Webhook和邮件
|
||||||
|
- 至少一种方式成功即视为成功
|
||||||
|
|
||||||
|
**代码量**:新增约250行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. ✅ sector_strategy_scheduler.py - 智策Webhook集成
|
||||||
|
|
||||||
|
**新增方法**:
|
||||||
|
- `_send_webhook_direct()` - 直接发送Webhook
|
||||||
|
- `_send_dingtalk()` - 钉钉消息发送
|
||||||
|
- `_send_feishu()` - 飞书消息发送
|
||||||
|
- `_format_webhook_summary()` - 格式化精简摘要
|
||||||
|
|
||||||
|
**修改方法**:
|
||||||
|
- `_send_analysis_notification()` - 支持邮件+Webhook双通道
|
||||||
|
|
||||||
|
**特性**:
|
||||||
|
- 智能精简报告(适合移动端)
|
||||||
|
- 分别统计发送成功数
|
||||||
|
- 完整的错误处理和日志
|
||||||
|
|
||||||
|
**代码量**:新增约150行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. ✅ config_manager.py - 配置管理
|
||||||
|
|
||||||
|
**新增配置项(9个)**:
|
||||||
|
|
||||||
|
#### 邮件配置
|
||||||
|
- `EMAIL_ENABLED` - 邮件通知开关
|
||||||
|
- `SMTP_SERVER` - SMTP服务器地址
|
||||||
|
- `SMTP_PORT` - SMTP端口
|
||||||
|
- `EMAIL_FROM` - 发件人邮箱
|
||||||
|
- `EMAIL_PASSWORD` - 邮箱授权码
|
||||||
|
- `EMAIL_TO` - 收件人邮箱
|
||||||
|
|
||||||
|
#### Webhook配置
|
||||||
|
- `WEBHOOK_ENABLED` - Webhook通知开关
|
||||||
|
- `WEBHOOK_TYPE` - Webhook类型(select类型)
|
||||||
|
- `WEBHOOK_URL` - Webhook地址
|
||||||
|
|
||||||
|
**修改方法**:
|
||||||
|
- `default_config` - 添加配置定义
|
||||||
|
- `write_env()` - 支持写入新配置
|
||||||
|
|
||||||
|
**代码量**:新增约60行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. ✅ app.py - Web配置界面
|
||||||
|
|
||||||
|
**新增UI组件**:
|
||||||
|
- 第4个标签页:"📢 通知配置"
|
||||||
|
- 左右分栏布局(邮件 | Webhook)
|
||||||
|
- 6个邮件配置输入框
|
||||||
|
- 3个Webhook配置组件
|
||||||
|
|
||||||
|
**特性**:
|
||||||
|
- 实时配置验证和状态提示
|
||||||
|
- 启用开关控制输入框禁用状态
|
||||||
|
- 完整的帮助说明和提示
|
||||||
|
- 支持保存和实时重载
|
||||||
|
|
||||||
|
**代码量**:新增约150行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. ✅ 完整文档体系
|
||||||
|
|
||||||
|
**新建文档(3个)**:
|
||||||
|
|
||||||
|
1. **Webhook通知配置指南.md**(约600行)
|
||||||
|
- 平台支持说明
|
||||||
|
- 钉钉配置详细步骤
|
||||||
|
- 飞书配置详细步骤
|
||||||
|
- 消息格式示例
|
||||||
|
- 故障排查指南
|
||||||
|
- 使用场景推荐
|
||||||
|
- 最佳实践
|
||||||
|
|
||||||
|
2. **Webhook功能完成说明.md**(约450行)
|
||||||
|
- 功能概述
|
||||||
|
- 完成内容
|
||||||
|
- 使用方法
|
||||||
|
- 消息格式
|
||||||
|
- 技术实现
|
||||||
|
- 故障排查
|
||||||
|
|
||||||
|
3. **Webhook功能实现总结.md**(本文档)
|
||||||
|
- 任务清单
|
||||||
|
- 实现内容
|
||||||
|
- 测试验证
|
||||||
|
- 使用指南
|
||||||
|
|
||||||
|
**更新文档(2个)**:
|
||||||
|
- `环境配置功能说明.md` - 添加通知配置章节
|
||||||
|
- `.env.example` - 添加完整配置示例(被globalIgnore阻止)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 测试验证
|
||||||
|
|
||||||
|
### 验证脚本:test_webhook.py
|
||||||
|
|
||||||
|
**测试内容**:
|
||||||
|
1. ✅ 模块导入测试(9个模块)
|
||||||
|
2. ✅ notification_service功能测试
|
||||||
|
3. ✅ config_manager配置测试
|
||||||
|
4. ✅ sector_strategy_scheduler集成测试
|
||||||
|
|
||||||
|
**测试结果**:
|
||||||
|
```
|
||||||
|
[PASS] - 导入测试 (9/9)
|
||||||
|
[PASS] - notification_service
|
||||||
|
[PASS] - config_manager
|
||||||
|
[PASS] - sector_strategy_scheduler
|
||||||
|
|
||||||
|
[SUCCESS] 所有测试通过!Webhook功能正常!
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 功能特性
|
||||||
|
|
||||||
|
### 双平台支持
|
||||||
|
|
||||||
|
#### 钉钉机器人
|
||||||
|
- ✅ Markdown格式消息
|
||||||
|
- ✅ 关键词安全设置支持
|
||||||
|
- ✅ 消息格式优化(移动端友好)
|
||||||
|
- ✅ 错误码识别和处理
|
||||||
|
|
||||||
|
#### 飞书机器人
|
||||||
|
- ✅ 交互式卡片消息
|
||||||
|
- ✅ 文本消息备选方案
|
||||||
|
- ✅ 美观的UI展示
|
||||||
|
- ✅ 完整的错误处理
|
||||||
|
|
||||||
|
### 灵活配置
|
||||||
|
|
||||||
|
#### Web界面配置
|
||||||
|
- ✅ 可视化配置界面
|
||||||
|
- ✅ 实时状态检查
|
||||||
|
- ✅ 一键保存和重载
|
||||||
|
- ✅ 完整帮助说明
|
||||||
|
|
||||||
|
#### .env文件配置
|
||||||
|
- ✅ 支持手动编辑
|
||||||
|
- ✅ 自动读取和写入
|
||||||
|
- ✅ 配置验证机制
|
||||||
|
|
||||||
|
### 双通道通知
|
||||||
|
|
||||||
|
#### 实时监测
|
||||||
|
- ✅ Webhook即时推送
|
||||||
|
- ✅ 邮件详细通知
|
||||||
|
- ✅ 双通道同时发送
|
||||||
|
- ✅ 失败自动降级
|
||||||
|
|
||||||
|
#### 智策定时分析
|
||||||
|
- ✅ Webhook精简报告
|
||||||
|
- ✅ 邮件完整报告
|
||||||
|
- ✅ 分别统计成功数
|
||||||
|
- ✅ 完整错误日志
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 代码统计
|
||||||
|
|
||||||
|
| 模块 | 新增行数 | 修改行数 | 文件数 |
|
||||||
|
|------|---------|---------|--------|
|
||||||
|
| notification_service.py | ~250 | ~20 | 1 |
|
||||||
|
| sector_strategy_scheduler.py | ~150 | ~30 | 1 |
|
||||||
|
| config_manager.py | ~60 | ~30 | 1 |
|
||||||
|
| app.py | ~150 | ~10 | 1 |
|
||||||
|
| 文档 | ~1500 | ~50 | 5 |
|
||||||
|
| **总计** | **~2110** | **~140** | **9** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 技术实现亮点
|
||||||
|
|
||||||
|
### 1. 智能消息格式化
|
||||||
|
|
||||||
|
**实时监测**:完整详细的监测信息
|
||||||
|
```markdown
|
||||||
|
### 股票监测提醒
|
||||||
|
**股票代码**: 600519
|
||||||
|
**股票名称**: 贵州茅台
|
||||||
|
**提醒类型**: 进场提醒
|
||||||
|
**提醒内容**: 价格进入进场区间
|
||||||
|
**触发时间**: 2024-01-15 10:30:00
|
||||||
|
```
|
||||||
|
|
||||||
|
**智策分析**:精简版策略摘要
|
||||||
|
```markdown
|
||||||
|
### 智策板块分析报告
|
||||||
|
**分析时间**: 2024-01-15 09:00
|
||||||
|
|
||||||
|
#### 📊 板块多空
|
||||||
|
**看多**: 人工智能(8分)、新能源汽车(8分)
|
||||||
|
|
||||||
|
#### 🔄 潜力接力板块
|
||||||
|
- 半导体: 关注突破信号
|
||||||
|
|
||||||
|
#### 🌡️ 热度TOP3
|
||||||
|
1. 人工智能 - 95分
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 错误处理机制
|
||||||
|
|
||||||
|
**多层异常捕获**:
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
# 1. 检查配置
|
||||||
|
# 2. 发送Webhook
|
||||||
|
# 3. 处理响应
|
||||||
|
except Exception as e:
|
||||||
|
# 记录错误日志
|
||||||
|
# 降级到备用方案
|
||||||
|
# 不影响核心功能
|
||||||
|
```
|
||||||
|
|
||||||
|
**状态码识别**:
|
||||||
|
- 钉钉:`errcode == 0` 为成功
|
||||||
|
- 飞书:`code == 0` 为成功
|
||||||
|
- HTTP:`status_code == 200` 为正常
|
||||||
|
|
||||||
|
### 3. 配置管理优化
|
||||||
|
|
||||||
|
**自动重载**:
|
||||||
|
```python
|
||||||
|
# 保存后自动重载环境变量
|
||||||
|
config_manager.write_env(config)
|
||||||
|
config_manager.reload_config()
|
||||||
|
load_dotenv(override=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
**实时验证**:
|
||||||
|
```python
|
||||||
|
# UI中实时检查配置完整性
|
||||||
|
if all([smtp_server, email_from, password, email_to]):
|
||||||
|
st.success("✅ 邮件配置完整")
|
||||||
|
else:
|
||||||
|
st.warning("⚠️ 邮件配置不完整")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📱 使用场景
|
||||||
|
|
||||||
|
### 场景1:个人日内交易监控
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
```env
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=dingtalk
|
||||||
|
WEBHOOK_URL=https://oapi.dingtalk.com/...
|
||||||
|
```
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 股票触发 → 钉钉通知
|
||||||
|
- 手机查看 → 快速决策
|
||||||
|
- 不错过 → 投资机会
|
||||||
|
|
||||||
|
### 场景2:团队策略协作
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
```env
|
||||||
|
EMAIL_ENABLED=true
|
||||||
|
EMAIL_TO=team@company.com
|
||||||
|
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=feishu
|
||||||
|
WEBHOOK_URL=https://open.feishu.cn/...
|
||||||
|
```
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 每日9:00自动分析
|
||||||
|
- 飞书群实时推送
|
||||||
|
- 团队讨论决策
|
||||||
|
- 邮件详细存档
|
||||||
|
|
||||||
|
### 场景3:多账户管理
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
- 账户A:仅Webhook(快速查看)
|
||||||
|
- 账户B:Webhook + 邮件(完整记录)
|
||||||
|
- 账户C:仅邮件(详细分析)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎓 最佳实践
|
||||||
|
|
||||||
|
### 1. 消息分类
|
||||||
|
|
||||||
|
| 消息类型 | Webhook | 邮件 | 说明 |
|
||||||
|
|---------|---------|------|------|
|
||||||
|
| 紧急提醒 | ✅ | ✅ | 双通道保障 |
|
||||||
|
| 日常分析 | ✅ | ❌ | 快速查看 |
|
||||||
|
| 详细报告 | ❌ | ✅ | 完整存档 |
|
||||||
|
|
||||||
|
### 2. 时段设置
|
||||||
|
|
||||||
|
- **交易时段**(9:30-15:00):启用Webhook
|
||||||
|
- **非交易时段**:降低通知频率
|
||||||
|
- **休市日**:可关闭Webhook
|
||||||
|
|
||||||
|
### 3. 群组管理
|
||||||
|
|
||||||
|
- **交易群**:实时监测通知
|
||||||
|
- **策略群**:智策分析报告
|
||||||
|
- **个人群**:所有通知汇总
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 注意事项
|
||||||
|
|
||||||
|
### 1. 安全性
|
||||||
|
|
||||||
|
- ❌ 不要公开分享Webhook URL
|
||||||
|
- ❌ 不要提交到版本控制
|
||||||
|
- ✅ 使用环境变量管理
|
||||||
|
- ✅ 定期更换地址
|
||||||
|
|
||||||
|
### 2. 频率限制
|
||||||
|
|
||||||
|
- 钉钉:20条/分钟
|
||||||
|
- 飞书:50条/分钟
|
||||||
|
- 系统已自动控制(不会超限)
|
||||||
|
|
||||||
|
### 3. 关键词设置(钉钉)
|
||||||
|
|
||||||
|
系统消息包含的关键词:
|
||||||
|
- 股票、分析、智策
|
||||||
|
- 监测、提醒、报告
|
||||||
|
|
||||||
|
建议配置至少一个。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 未来扩展
|
||||||
|
|
||||||
|
### v1.1.0(规划中)
|
||||||
|
- [ ] 支持多个Webhook URL
|
||||||
|
- [ ] 企业微信机器人
|
||||||
|
- [ ] Server酱推送
|
||||||
|
- [ ] 消息模板自定义
|
||||||
|
|
||||||
|
### v1.2.0(规划中)
|
||||||
|
- [ ] 消息优先级分级
|
||||||
|
- [ ] 智能推送时段
|
||||||
|
- [ ] 消息去重合并
|
||||||
|
- [ ] @指定成员提醒
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 相关文档索引
|
||||||
|
|
||||||
|
### 配置指南
|
||||||
|
- [Webhook通知配置指南.md](Webhook通知配置指南.md) - 完整配置教程
|
||||||
|
- [环境配置功能说明.md](环境配置功能说明.md) - 环境配置总览
|
||||||
|
|
||||||
|
### 功能说明
|
||||||
|
- [Webhook功能完成说明.md](Webhook功能完成说明.md) - 功能详细说明
|
||||||
|
- [实时监测优化说明.md](实时监测优化说明.md) - 实时监测功能
|
||||||
|
- [智策定时分析使用指南.md](智策定时分析使用指南.md) - 智策功能
|
||||||
|
|
||||||
|
### 其他
|
||||||
|
- [test_webhook.py](test_webhook.py) - 功能验证脚本
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 验证清单
|
||||||
|
|
||||||
|
部署后请确认:
|
||||||
|
|
||||||
|
- [x] Python环境正常(Python 3.8+)
|
||||||
|
- [x] requests库已安装
|
||||||
|
- [x] 所有模块可正常导入
|
||||||
|
- [x] notification_service包含Webhook方法
|
||||||
|
- [x] config_manager包含Webhook配置
|
||||||
|
- [x] sector_strategy_scheduler集成Webhook
|
||||||
|
- [x] app.py包含通知配置UI
|
||||||
|
- [x] 测试脚本全部通过
|
||||||
|
- [ ] 创建钉钉/飞书机器人
|
||||||
|
- [ ] 配置Webhook URL
|
||||||
|
- [ ] 测试Webhook发送
|
||||||
|
- [ ] 验证实时监测通知
|
||||||
|
- [ ] 验证智策分析通知
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎉 总结
|
||||||
|
|
||||||
|
### 完成的工作
|
||||||
|
|
||||||
|
1. **核心功能** ✅
|
||||||
|
- Webhook发送(钉钉+飞书)
|
||||||
|
- 智策定时分析集成
|
||||||
|
- 实时监测集成
|
||||||
|
|
||||||
|
2. **配置管理** ✅
|
||||||
|
- Web可视化配置
|
||||||
|
- .env文件支持
|
||||||
|
- 配置验证机制
|
||||||
|
|
||||||
|
3. **文档完善** ✅
|
||||||
|
- 3个新建文档(~1500行)
|
||||||
|
- 2个更新文档
|
||||||
|
- 完整使用指南
|
||||||
|
|
||||||
|
4. **测试验证** ✅
|
||||||
|
- 验证脚本
|
||||||
|
- 全部测试通过
|
||||||
|
- 功能正常运行
|
||||||
|
|
||||||
|
### 技术亮点
|
||||||
|
|
||||||
|
- 🎯 **双平台支持** - 钉钉和飞书
|
||||||
|
- 🔧 **灵活配置** - Web界面+文件编辑
|
||||||
|
- 📱 **移动友好** - 精简消息格式
|
||||||
|
- 🔄 **双通道** - Webhook+邮件同时支持
|
||||||
|
- ⚡ **高性能** - 异步处理,不阻塞
|
||||||
|
- 🛡️ **高可靠** - 完整错误处理
|
||||||
|
|
||||||
|
### 使用价值
|
||||||
|
|
||||||
|
- 💰 **降低成本** - 免费推送,无需付费服务
|
||||||
|
- ⏱️ **提高效率** - 即时通知,快速响应
|
||||||
|
- 👥 **团队协作** - 群组通知,统一决策
|
||||||
|
- 📈 **投资助力** - 不错过机会,及时止损
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Webhook功能** - v1.0.0
|
||||||
|
**完成时间**:2025-01-15
|
||||||
|
**代码量**:~2250行
|
||||||
|
**文档量**:~2000行
|
||||||
|
**测试**:✅ 全部通过
|
||||||
|
|
||||||
|
🎉 功能已完整实现并通过验证!
|
||||||
|
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
# Webhook自定义关键词功能说明
|
||||||
|
|
||||||
|
## 功能概述
|
||||||
|
|
||||||
|
系统现已支持自定义Webhook关键词配置,用户可以根据自己的钉钉/飞书机器人安全设置灵活配置关键词。
|
||||||
|
|
||||||
|
## 配置方法
|
||||||
|
|
||||||
|
### 1. 在.env文件中配置
|
||||||
|
|
||||||
|
```env
|
||||||
|
# ========== Webhook通知配置(可选)==========
|
||||||
|
WEBHOOK_ENABLED="true"
|
||||||
|
WEBHOOK_TYPE="dingtalk"
|
||||||
|
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
|
||||||
|
WEBHOOK_KEYWORD="aiagents通知"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 配置说明
|
||||||
|
|
||||||
|
| 配置项 | 说明 | 示例 |
|
||||||
|
|-------|------|------|
|
||||||
|
| WEBHOOK_ENABLED | 是否启用Webhook | true / false |
|
||||||
|
| WEBHOOK_TYPE | Webhook类型 | dingtalk(钉钉)/ feishu(飞书)|
|
||||||
|
| WEBHOOK_URL | Webhook地址 | 机器人Webhook完整URL |
|
||||||
|
| WEBHOOK_KEYWORD | 自定义关键词 | aiagents通知(或您机器人设置的任何关键词)|
|
||||||
|
|
||||||
|
## 钉钉机器人关键词设置
|
||||||
|
|
||||||
|
### 步骤1:创建钉钉自定义机器人
|
||||||
|
1. 打开钉钉群聊
|
||||||
|
2. 点击右上角"..." → 机器人 → 添加机器人
|
||||||
|
3. 选择"自定义"机器人
|
||||||
|
|
||||||
|
### 步骤2:安全设置
|
||||||
|
1. 安全设置选择:**自定义关键词**
|
||||||
|
2. 输入关键词:**aiagents通知**(或您自己定义的关键词)
|
||||||
|
3. 复制Webhook地址
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 步骤3:配置到系统
|
||||||
|
将关键词和Webhook地址配置到`.env`文件中:
|
||||||
|
|
||||||
|
```env
|
||||||
|
WEBHOOK_KEYWORD="aiagents通知"
|
||||||
|
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
|
||||||
|
```
|
||||||
|
|
||||||
|
**重要提示**:
|
||||||
|
- `.env`文件中的关键词必须与钉钉机器人设置的关键词完全一致
|
||||||
|
- 如果不匹配,消息将发送失败
|
||||||
|
- 如果关键词为空,则不会在消息中添加关键词前缀
|
||||||
|
|
||||||
|
## 飞书机器人配置
|
||||||
|
|
||||||
|
飞书机器人通常不需要关键词,可以将WEBHOOK_KEYWORD留空或使用默认值:
|
||||||
|
|
||||||
|
```env
|
||||||
|
WEBHOOK_TYPE="feishu"
|
||||||
|
WEBHOOK_KEYWORD=""
|
||||||
|
```
|
||||||
|
|
||||||
|
## 消息格式
|
||||||
|
|
||||||
|
### 钉钉消息示例
|
||||||
|
|
||||||
|
**有关键词时:**
|
||||||
|
```markdown
|
||||||
|
标题:aiagents通知 - 000001 平安银行
|
||||||
|
|
||||||
|
### aiagents通知 - 股票监测提醒
|
||||||
|
|
||||||
|
**股票代码**: 000001
|
||||||
|
**股票名称**: 平安银行
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**无关键词时:**
|
||||||
|
```markdown
|
||||||
|
标题:000001 平安银行
|
||||||
|
|
||||||
|
### 股票监测提醒
|
||||||
|
|
||||||
|
**股票代码**: 000001
|
||||||
|
**股票名称**: 平安银行
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试配置
|
||||||
|
|
||||||
|
配置完成后,运行测试工具验证:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Windows
|
||||||
|
.\venv\Scripts\python.exe test_notification_config.py
|
||||||
|
|
||||||
|
# Linux/Mac
|
||||||
|
python test_notification_config.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**成功输出示例:**
|
||||||
|
```
|
||||||
|
============================================================
|
||||||
|
[Webhook] 测试Webhook配置
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
当前配置:
|
||||||
|
- 启用状态: [已启用]
|
||||||
|
- Webhook类型: dingtalk
|
||||||
|
- 配置完整性: [完整]
|
||||||
|
|
||||||
|
[钉钉] 正在发送Webhook...
|
||||||
|
[成功] 钉钉Webhook发送成功
|
||||||
|
[成功] 钉钉Webhook测试成功!请检查钉钉群消息。
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q1: 提示"关键词不匹配"
|
||||||
|
|
||||||
|
**原因**:
|
||||||
|
- .env文件中的WEBHOOK_KEYWORD与钉钉机器人设置不一致
|
||||||
|
- .env文件编码问题导致关键词乱码
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
1. 检查钉钉机器人的关键词设置
|
||||||
|
2. 确保.env文件使用UTF-8编码
|
||||||
|
3. 运行`fix_env.py`重新生成.env文件:
|
||||||
|
```bash
|
||||||
|
python fix_env.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q2: .env文件中文显示乱码
|
||||||
|
|
||||||
|
**原因**:
|
||||||
|
文件编码不是UTF-8
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
运行修复脚本:
|
||||||
|
```bash
|
||||||
|
python fix_env.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q3: 如何修改关键词
|
||||||
|
|
||||||
|
**方法1:直接编辑.env文件**
|
||||||
|
1. 用支持UTF-8的编辑器(VS Code、Notepad++等)打开.env
|
||||||
|
2. 修改WEBHOOK_KEYWORD的值
|
||||||
|
3. 保存为UTF-8编码
|
||||||
|
|
||||||
|
**方法2:使用环境配置界面**
|
||||||
|
1. 启动应用
|
||||||
|
2. 进入"环境配置"页面
|
||||||
|
3. 修改"Webhook自定义关键词"
|
||||||
|
4. 保存配置
|
||||||
|
|
||||||
|
**方法3:使用配置管理器**
|
||||||
|
```python
|
||||||
|
from config_manager import config_manager
|
||||||
|
|
||||||
|
# 读取当前配置
|
||||||
|
config = config_manager.read_env()
|
||||||
|
|
||||||
|
# 修改关键词
|
||||||
|
config['WEBHOOK_KEYWORD'] = '您的新关键词'
|
||||||
|
|
||||||
|
# 保存配置
|
||||||
|
config_manager.write_env(config)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q4: 是否可以不使用关键词
|
||||||
|
|
||||||
|
**可以!**
|
||||||
|
|
||||||
|
如果您的钉钉机器人使用其他安全方式(如加签、IP白名单),可以将关键词设为空:
|
||||||
|
|
||||||
|
```env
|
||||||
|
WEBHOOK_KEYWORD=""
|
||||||
|
```
|
||||||
|
|
||||||
|
系统会自动检测,如果关键词为空,则不会在消息中添加关键词前缀。
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
|
||||||
|
### v1.1 (2025-10-14)
|
||||||
|
- ✅ 新增WEBHOOK_KEYWORD配置项
|
||||||
|
- ✅ 支持自定义关键词
|
||||||
|
- ✅ 修复.env文件中文编码问题
|
||||||
|
- ✅ 优化消息格式,去除多余空格
|
||||||
|
- ✅ 提供fix_env.py工具修复编码问题
|
||||||
|
|
||||||
|
### v1.0 (2025-10-14)
|
||||||
|
- ✅ 初始版本
|
||||||
|
- ✅ 硬编码"aiagents通知"关键词
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `.env` - 环境配置文件
|
||||||
|
- `.env.example` - 配置模板
|
||||||
|
- `fix_env.py` - 编码修复工具
|
||||||
|
- `config_manager.py` - 配置管理模块
|
||||||
|
- `notification_service.py` - 通知服务模块
|
||||||
|
- `sector_strategy_scheduler.py` - 定时任务模块
|
||||||
|
- `test_notification_config.py` - 测试工具
|
||||||
|
|
||||||
|
## 技术实现
|
||||||
|
|
||||||
|
### 配置读取流程
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 1. 从环境变量读取
|
||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
load_dotenv()
|
||||||
|
keyword = os.getenv('WEBHOOK_KEYWORD', 'aiagents通知')
|
||||||
|
|
||||||
|
# 2. 在notification_service中使用
|
||||||
|
class NotificationService:
|
||||||
|
def _load_config(self):
|
||||||
|
config['webhook_keyword'] = os.getenv('WEBHOOK_KEYWORD')
|
||||||
|
|
||||||
|
def _send_dingtalk_webhook(self, notification):
|
||||||
|
keyword = self.config.get('webhook_keyword', '')
|
||||||
|
title_prefix = f"{keyword} - " if keyword else ""
|
||||||
|
# ...构建消息
|
||||||
|
```
|
||||||
|
|
||||||
|
### 消息构建逻辑
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 如果有关键词
|
||||||
|
if keyword:
|
||||||
|
title = f"{keyword} - {notification['symbol']} {notification['name']}"
|
||||||
|
text = f"### {keyword} - 股票监测提醒\n..."
|
||||||
|
else:
|
||||||
|
title = f"{notification['symbol']} {notification['name']}"
|
||||||
|
text = f"### 股票监测提醒\n..."
|
||||||
|
```
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
现在系统完全支持自定义Webhook关键词,用户可以根据自己的需求灵活配置:
|
||||||
|
|
||||||
|
✅ **灵活性**:支持任意自定义关键词
|
||||||
|
✅ **兼容性**:支持钉钉和飞书
|
||||||
|
✅ **易用性**:简单配置即可使用
|
||||||
|
✅ **稳定性**:自动处理编码问题
|
||||||
|
|
||||||
|
祝您使用愉快!
|
||||||
|
|
||||||
@@ -0,0 +1,444 @@
|
|||||||
|
# Webhook通知配置指南
|
||||||
|
|
||||||
|
## 📱 功能概述
|
||||||
|
|
||||||
|
系统支持通过Webhook将通知推送到钉钉或飞书群,适用于:
|
||||||
|
- **实时监测**:股票价格触发提醒
|
||||||
|
- **智策定时分析**:板块策略分析报告
|
||||||
|
|
||||||
|
可与邮件通知同时使用,也可单独使用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 支持的平台
|
||||||
|
|
||||||
|
### 1. 钉钉群机器人
|
||||||
|
- ✅ 支持Markdown格式
|
||||||
|
- ✅ 消息样式丰富
|
||||||
|
- ✅ 配置简单
|
||||||
|
- ✅ 免费使用
|
||||||
|
|
||||||
|
### 2. 飞书群机器人
|
||||||
|
- ✅ 支持交互式卡片
|
||||||
|
- ✅ 消息展示美观
|
||||||
|
- ✅ 支持文本和富文本
|
||||||
|
- ✅ 免费使用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 配置步骤
|
||||||
|
|
||||||
|
### 方法一:通过Web界面配置(推荐)
|
||||||
|
|
||||||
|
1. **进入配置页面**
|
||||||
|
- 点击侧边栏"⚙️ 环境配置"
|
||||||
|
- 选择"📢 通知配置"标签页
|
||||||
|
|
||||||
|
2. **配置Webhook**
|
||||||
|
- 勾选"启用Webhook通知"
|
||||||
|
- 选择Webhook类型(钉钉/飞书)
|
||||||
|
- 填写Webhook URL
|
||||||
|
- 点击"💾 保存配置"
|
||||||
|
|
||||||
|
3. **测试配置**
|
||||||
|
- 在实时监测的"通知管理"中
|
||||||
|
- 点击"测试Webhook"按钮
|
||||||
|
- 检查群消息是否收到
|
||||||
|
|
||||||
|
### 方法二:手动编辑.env文件
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Webhook通知配置
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=dingtalk # 或 feishu
|
||||||
|
WEBHOOK_URL=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 钉钉机器人配置
|
||||||
|
|
||||||
|
### 步骤1:创建群机器人
|
||||||
|
|
||||||
|
1. 打开钉钉PC端或移动端
|
||||||
|
2. 进入要接收通知的群聊
|
||||||
|
3. 点击右上角"⚙️"进入群设置
|
||||||
|
4. 选择"智能群助手" → "添加机器人"
|
||||||
|
5. 选择"自定义"机器人
|
||||||
|
|
||||||
|
### 步骤2:配置机器人
|
||||||
|
|
||||||
|
1. **机器人名称**:AI股票分析系统
|
||||||
|
2. **安全设置**(选择一种即可):
|
||||||
|
- ✅ **推荐**:自定义关键词(例如:股票、分析、智策)
|
||||||
|
- 加签(需要额外配置)
|
||||||
|
- IP地址段(需要固定IP)
|
||||||
|
|
||||||
|
### 步骤3:获取Webhook地址
|
||||||
|
|
||||||
|
完成配置后,会显示Webhook地址:
|
||||||
|
```
|
||||||
|
https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
复制整个地址到系统配置中。
|
||||||
|
|
||||||
|
### 钉钉消息格式示例
|
||||||
|
|
||||||
|
**实时监测通知**:
|
||||||
|
```markdown
|
||||||
|
### 股票监测提醒
|
||||||
|
|
||||||
|
**股票代码**: 600519
|
||||||
|
|
||||||
|
**股票名称**: 贵州茅台
|
||||||
|
|
||||||
|
**提醒类型**: 进场提醒
|
||||||
|
|
||||||
|
**提醒内容**: 股票价格 1650.00 进入进场区间
|
||||||
|
|
||||||
|
**触发时间**: 2024-01-15 10:30:00
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_此消息由AI股票分析系统自动发送_
|
||||||
|
```
|
||||||
|
|
||||||
|
**智策定时分析**:
|
||||||
|
```markdown
|
||||||
|
### 智策板块分析报告
|
||||||
|
**分析时间**: 2024-01-15 09:00
|
||||||
|
|
||||||
|
#### 📊 板块多空
|
||||||
|
**看多**: 人工智能(8分)、新能源汽车(8分)、半导体(7分)
|
||||||
|
**看空**: 地产开发(7分)
|
||||||
|
|
||||||
|
#### 🔄 潜力接力板块
|
||||||
|
- 半导体: 关注突破信号
|
||||||
|
- 军工: 情绪升温,把握机会
|
||||||
|
|
||||||
|
#### 🌡️ 热度TOP3
|
||||||
|
1. 人工智能 - 95分
|
||||||
|
2. 新能源汽车 - 92分
|
||||||
|
3. 半导体 - 88分
|
||||||
|
|
||||||
|
#### 💡 核心机会
|
||||||
|
重点关注人工智能、新能源汽车产业链...
|
||||||
|
|
||||||
|
---
|
||||||
|
*由智策AI系统自动生成*
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 飞书机器人配置
|
||||||
|
|
||||||
|
### 步骤1:创建群机器人
|
||||||
|
|
||||||
|
1. 打开飞书PC端或移动端
|
||||||
|
2. 进入要接收通知的群聊
|
||||||
|
3. 点击右上角"⚙️"进入群设置
|
||||||
|
4. 选择"群机器人" → "添加机器人"
|
||||||
|
5. 选择"自定义机器人"
|
||||||
|
|
||||||
|
### 步骤2:配置机器人
|
||||||
|
|
||||||
|
1. **机器人名称**:AI股票分析系统
|
||||||
|
2. **机器人描述**:股票监测和板块分析通知
|
||||||
|
3. **安全设置**(可选):
|
||||||
|
- 签名验证(需要额外配置)
|
||||||
|
|
||||||
|
### 步骤3:获取Webhook地址
|
||||||
|
|
||||||
|
完成配置后,会显示Webhook地址:
|
||||||
|
```
|
||||||
|
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
复制整个地址到系统配置中。
|
||||||
|
|
||||||
|
### 飞书消息格式示例
|
||||||
|
|
||||||
|
**实时监测通知**:
|
||||||
|
```
|
||||||
|
📊 股票监测提醒 - 600519
|
||||||
|
|
||||||
|
股票代码 股票名称
|
||||||
|
600519 贵州茅台
|
||||||
|
|
||||||
|
提醒类型 触发时间
|
||||||
|
进场提醒 2024-01-15 10:30:00
|
||||||
|
|
||||||
|
提醒内容
|
||||||
|
股票价格 1650.00 进入进场区间
|
||||||
|
|
||||||
|
---
|
||||||
|
此消息由AI股票分析系统自动发送
|
||||||
|
```
|
||||||
|
|
||||||
|
**智策定时分析**:
|
||||||
|
```
|
||||||
|
【智策板块分析报告】
|
||||||
|
分析时间: 2024-01-15 09:00
|
||||||
|
|
||||||
|
### 智策板块分析报告
|
||||||
|
**分析时间**: 2024-01-15 09:00
|
||||||
|
|
||||||
|
#### 📊 板块多空
|
||||||
|
**看多**: 人工智能(8分)、新能源汽车(8分)
|
||||||
|
**看空**: 地产开发(7分)
|
||||||
|
|
||||||
|
#### 🔄 潜力接力板块
|
||||||
|
- 半导体: 关注突破信号
|
||||||
|
|
||||||
|
#### 🌡️ 热度TOP3
|
||||||
|
1. 人工智能 - 95分
|
||||||
|
2. 新能源汽车 - 92分
|
||||||
|
3. 半导体 - 88分
|
||||||
|
|
||||||
|
---
|
||||||
|
*由智策AI系统自动生成*
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 配置说明
|
||||||
|
|
||||||
|
### 环境变量
|
||||||
|
|
||||||
|
| 变量名 | 说明 | 示例值 |
|
||||||
|
|-------|------|--------|
|
||||||
|
| `WEBHOOK_ENABLED` | 是否启用Webhook | `true` 或 `false` |
|
||||||
|
| `WEBHOOK_TYPE` | Webhook类型 | `dingtalk` 或 `feishu` |
|
||||||
|
| `WEBHOOK_URL` | Webhook地址 | 完整的机器人Webhook URL |
|
||||||
|
|
||||||
|
### 配置检查
|
||||||
|
|
||||||
|
系统会自动检查配置状态:
|
||||||
|
- ✅ **配置完整**:显示绿色提示
|
||||||
|
- ⚠️ **配置不完整**:显示黄色警告
|
||||||
|
- ℹ️ **未启用**:显示蓝色信息
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 测试Webhook
|
||||||
|
|
||||||
|
### 在实时监测模块测试
|
||||||
|
|
||||||
|
1. 进入"📊 实时监测"页面
|
||||||
|
2. 滚动到"🔔 通知管理"区域
|
||||||
|
3. 点击"📱 发送测试Webhook"按钮
|
||||||
|
4. 检查钉钉/飞书群是否收到消息
|
||||||
|
|
||||||
|
### 测试消息内容
|
||||||
|
|
||||||
|
```
|
||||||
|
股票代码: 测试
|
||||||
|
股票名称: Webhook测试
|
||||||
|
提醒类型: 测试消息
|
||||||
|
提醒内容: 如果您收到此消息,说明Webhook配置正确!
|
||||||
|
触发时间: 刚刚
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 同时使用邮件和Webhook
|
||||||
|
|
||||||
|
系统支持同时启用邮件和Webhook通知:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# 邮件通知
|
||||||
|
EMAIL_ENABLED=true
|
||||||
|
SMTP_SERVER=smtp.qq.com
|
||||||
|
EMAIL_FROM=your-email@qq.com
|
||||||
|
EMAIL_PASSWORD=authorization-code
|
||||||
|
EMAIL_TO=recipient@qq.com
|
||||||
|
|
||||||
|
# Webhook通知
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=dingtalk
|
||||||
|
WEBHOOK_URL=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
**优势**:
|
||||||
|
- 📧 邮件:详细完整,适合深度阅读
|
||||||
|
- 📱 Webhook:即时推送,适合快速查看
|
||||||
|
- 🔔 双重保障:确保不错过重要通知
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 注意事项
|
||||||
|
|
||||||
|
### 1. 钉钉安全设置
|
||||||
|
|
||||||
|
如果选择"自定义关键词",确保消息中包含关键词:
|
||||||
|
- **推荐关键词**:股票、分析、智策、监测、提醒
|
||||||
|
- 系统消息已包含这些关键词,无需额外配置
|
||||||
|
|
||||||
|
### 2. 消息频率限制
|
||||||
|
|
||||||
|
- **钉钉**:每个机器人每分钟最多20条消息
|
||||||
|
- **飞书**:每个机器人每分钟最多50条消息
|
||||||
|
- 系统会自动控制发送频率,避免超限
|
||||||
|
|
||||||
|
### 3. Webhook地址安全
|
||||||
|
|
||||||
|
- ❌ 不要在公开场合分享Webhook URL
|
||||||
|
- ❌ 不要提交到版本控制系统
|
||||||
|
- ✅ 使用环境变量或配置文件管理
|
||||||
|
- ✅ 定期更换Webhook地址
|
||||||
|
|
||||||
|
### 4. 消息格式
|
||||||
|
|
||||||
|
- **钉钉**:支持Markdown格式
|
||||||
|
- **飞书**:支持文本和交互式卡片
|
||||||
|
- 系统会自动根据平台类型格式化消息
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ 故障排查
|
||||||
|
|
||||||
|
### 问题1:未收到Webhook消息
|
||||||
|
|
||||||
|
**检查项**:
|
||||||
|
1. ✅ Webhook是否已启用(`WEBHOOK_ENABLED=true`)
|
||||||
|
2. ✅ Webhook URL是否正确
|
||||||
|
3. ✅ 网络连接是否正常
|
||||||
|
4. ✅ 机器人是否被移出群聊
|
||||||
|
5. ✅ 钉钉关键词安全设置是否正确
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 使用"测试Webhook"功能验证配置
|
||||||
|
- 检查系统日志查看错误信息
|
||||||
|
- 重新创建机器人并更新URL
|
||||||
|
|
||||||
|
### 问题2:Webhook发送失败
|
||||||
|
|
||||||
|
**常见错误**:
|
||||||
|
|
||||||
|
| 错误信息 | 原因 | 解决方案 |
|
||||||
|
|---------|------|---------|
|
||||||
|
| `errcode: 310000` | 关键词不匹配 | 添加"股票"或"分析"到关键词 |
|
||||||
|
| `Connection timeout` | 网络超时 | 检查网络连接 |
|
||||||
|
| `Invalid URL` | URL格式错误 | 检查URL完整性 |
|
||||||
|
|
||||||
|
**日志查看**:
|
||||||
|
系统会在终端输出详细日志:
|
||||||
|
```
|
||||||
|
📱 正在发送钉钉Webhook...
|
||||||
|
- URL: https://oapi.dingtalk.com...
|
||||||
|
✅ 钉钉Webhook发送成功
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题3:消息格式异常
|
||||||
|
|
||||||
|
**现象**:消息显示不正确或乱码
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 确认选择了正确的Webhook类型(钉钉/飞书)
|
||||||
|
- 检查系统编码设置为UTF-8
|
||||||
|
- 尝试重新保存配置
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 使用场景
|
||||||
|
|
||||||
|
### 场景1:日内交易监控
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
- 启用实时监测 ✅
|
||||||
|
- 启用Webhook通知 ✅
|
||||||
|
- 设置进场区间、止盈止损 ✅
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 股票价格变动 → 钉钉/飞书实时提醒
|
||||||
|
- 手机随时查看 → 及时做出决策
|
||||||
|
- 双重保障 → 不错过交易机会
|
||||||
|
|
||||||
|
### 场景2:每日策略推送
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
- 启用智策定时分析 ✅
|
||||||
|
- 设置每天9:00运行 ✅
|
||||||
|
- 启用Webhook通知 ✅
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 每天9:00自动分析 → 板块策略报告
|
||||||
|
- 推送到钉钉/飞书群 → 团队成员查看
|
||||||
|
- 邮件同步发送 → 详细报告留存
|
||||||
|
|
||||||
|
### 场景3:团队协作
|
||||||
|
|
||||||
|
**配置**:
|
||||||
|
- 将机器人添加到团队群 ✅
|
||||||
|
- 配置Webhook URL ✅
|
||||||
|
- 多人共享通知 ✅
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 团队成员实时接收 → 投资信息同步
|
||||||
|
- 群内讨论决策 → 提高协作效率
|
||||||
|
- 历史消息可查 → 便于复盘总结
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎓 最佳实践
|
||||||
|
|
||||||
|
### 1. 消息分级
|
||||||
|
|
||||||
|
**重要通知** → Webhook + 邮件:
|
||||||
|
- 进场/止盈/止损提醒
|
||||||
|
- 智策定时分析报告
|
||||||
|
|
||||||
|
**一般通知** → 仅Webhook:
|
||||||
|
- 价格波动提醒
|
||||||
|
- 系统状态更新
|
||||||
|
|
||||||
|
### 2. 多群分发
|
||||||
|
|
||||||
|
创建多个机器人,分别推送:
|
||||||
|
- **交易群**:实时监测提醒
|
||||||
|
- **研究群**:智策分析报告
|
||||||
|
- **个人**:所有通知
|
||||||
|
|
||||||
|
### 3. 消息过滤
|
||||||
|
|
||||||
|
利用钉钉/飞书的消息筛选功能:
|
||||||
|
- 设置关键词提醒
|
||||||
|
- 静音非关键时段
|
||||||
|
- 重要消息置顶
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 相关文档
|
||||||
|
|
||||||
|
- [环境配置功能说明.md](环境配置功能说明.md) - 完整配置指南
|
||||||
|
- [实时监测优化说明.md](实时监测优化说明.md) - 实时监测功能
|
||||||
|
- [智策定时分析使用指南.md](智策定时分析使用指南.md) - 智策定时功能
|
||||||
|
- [邮件配置指南.md](邮件配置指南.md) - 邮件通知配置
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ❓ 常见问题
|
||||||
|
|
||||||
|
**Q: 可以同时配置多个Webhook吗?**
|
||||||
|
A: 当前版本只支持一个Webhook URL。如需多群推送,建议使用钉钉/飞书的消息转发功能。
|
||||||
|
|
||||||
|
**Q: Webhook和邮件应该选哪个?**
|
||||||
|
A: 建议同时使用。Webhook适合实时查看,邮件适合详细阅读和存档。
|
||||||
|
|
||||||
|
**Q: 消息发送失败会影响系统吗?**
|
||||||
|
A: 不会。Webhook发送失败不影响核心功能,系统会记录日志并继续运行。
|
||||||
|
|
||||||
|
**Q: 如何更换Webhook URL?**
|
||||||
|
A: 在环境配置中修改`WEBHOOK_URL`,保存后重启应用即可。
|
||||||
|
|
||||||
|
**Q: 钉钉和飞书哪个更好?**
|
||||||
|
A: 各有优势。钉钉Markdown渲染好,飞书卡片更美观。选择团队常用的即可。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Webhook通知配置指南** - 让通知更及时 📱🔔
|
||||||
|
|
||||||
|
版本:v1.0
|
||||||
|
更新时间:2025-01-15
|
||||||
|
|
||||||
@@ -1957,7 +1957,7 @@ def display_config_manager():
|
|||||||
config_info = config_manager.get_config_info()
|
config_info = config_manager.get_config_info()
|
||||||
|
|
||||||
# 创建标签页
|
# 创建标签页
|
||||||
tab1, tab2, tab3 = st.tabs(["📝 基本配置", "📊 数据源配置", "🤖 量化交易配置"])
|
tab1, tab2, tab3, tab4 = st.tabs(["📝 基本配置", "📊 数据源配置", "🤖 量化交易配置", "📢 通知配置"])
|
||||||
|
|
||||||
# 使用session_state保存临时配置
|
# 使用session_state保存临时配置
|
||||||
if 'temp_config' not in st.session_state:
|
if 'temp_config' not in st.session_state:
|
||||||
@@ -2087,6 +2087,160 @@ def display_config_manager():
|
|||||||
|
|
||||||
st.warning("⚠️ 警告:量化交易涉及真实资金操作,请谨慎配置和使用!")
|
st.warning("⚠️ 警告:量化交易涉及真实资金操作,请谨慎配置和使用!")
|
||||||
|
|
||||||
|
with tab4:
|
||||||
|
st.markdown("### 通知配置")
|
||||||
|
st.markdown("配置邮件和Webhook通知,用于实时监测和智策定时分析的提醒。")
|
||||||
|
|
||||||
|
# 创建两列布局
|
||||||
|
col_email, col_webhook = st.columns(2)
|
||||||
|
|
||||||
|
with col_email:
|
||||||
|
st.markdown("#### 📧 邮件通知")
|
||||||
|
|
||||||
|
# 邮件启用开关
|
||||||
|
email_enabled_info = config_info.get("EMAIL_ENABLED", {"value": "false"})
|
||||||
|
current_email_enabled = st.session_state.temp_config.get("EMAIL_ENABLED", "false") == "true"
|
||||||
|
|
||||||
|
new_email_enabled = st.checkbox(
|
||||||
|
"启用邮件通知",
|
||||||
|
value=current_email_enabled,
|
||||||
|
help="开启后可以接收邮件提醒",
|
||||||
|
key="input_email_enabled"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["EMAIL_ENABLED"] = "true" if new_email_enabled else "false"
|
||||||
|
|
||||||
|
# SMTP服务器
|
||||||
|
smtp_server_info = config_info.get("SMTP_SERVER", {"description": "SMTP服务器地址", "value": ""})
|
||||||
|
current_smtp_server = st.session_state.temp_config.get("SMTP_SERVER", "")
|
||||||
|
|
||||||
|
new_smtp_server = st.text_input(
|
||||||
|
f"📮 {smtp_server_info['description']}",
|
||||||
|
value=current_smtp_server,
|
||||||
|
disabled=not new_email_enabled,
|
||||||
|
placeholder="smtp.qq.com",
|
||||||
|
key="input_smtp_server"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["SMTP_SERVER"] = new_smtp_server
|
||||||
|
|
||||||
|
# SMTP端口
|
||||||
|
smtp_port_info = config_info.get("SMTP_PORT", {"description": "SMTP端口", "value": "587"})
|
||||||
|
current_smtp_port = st.session_state.temp_config.get("SMTP_PORT", "587")
|
||||||
|
|
||||||
|
new_smtp_port = st.text_input(
|
||||||
|
f"🔌 {smtp_port_info['description']}",
|
||||||
|
value=current_smtp_port,
|
||||||
|
disabled=not new_email_enabled,
|
||||||
|
placeholder="587 (TLS) 或 465 (SSL)",
|
||||||
|
key="input_smtp_port"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["SMTP_PORT"] = new_smtp_port
|
||||||
|
|
||||||
|
# 发件人邮箱
|
||||||
|
email_from_info = config_info.get("EMAIL_FROM", {"description": "发件人邮箱", "value": ""})
|
||||||
|
current_email_from = st.session_state.temp_config.get("EMAIL_FROM", "")
|
||||||
|
|
||||||
|
new_email_from = st.text_input(
|
||||||
|
f"📤 {email_from_info['description']}",
|
||||||
|
value=current_email_from,
|
||||||
|
disabled=not new_email_enabled,
|
||||||
|
placeholder="your-email@qq.com",
|
||||||
|
key="input_email_from"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["EMAIL_FROM"] = new_email_from
|
||||||
|
|
||||||
|
# 邮箱授权码
|
||||||
|
email_password_info = config_info.get("EMAIL_PASSWORD", {"description": "邮箱授权码", "value": ""})
|
||||||
|
current_email_password = st.session_state.temp_config.get("EMAIL_PASSWORD", "")
|
||||||
|
|
||||||
|
new_email_password = st.text_input(
|
||||||
|
f"🔐 {email_password_info['description']}",
|
||||||
|
value=current_email_password,
|
||||||
|
type="password",
|
||||||
|
disabled=not new_email_enabled,
|
||||||
|
help="不是邮箱登录密码,而是SMTP授权码",
|
||||||
|
key="input_email_password"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["EMAIL_PASSWORD"] = new_email_password
|
||||||
|
|
||||||
|
# 收件人邮箱
|
||||||
|
email_to_info = config_info.get("EMAIL_TO", {"description": "收件人邮箱", "value": ""})
|
||||||
|
current_email_to = st.session_state.temp_config.get("EMAIL_TO", "")
|
||||||
|
|
||||||
|
new_email_to = st.text_input(
|
||||||
|
f"📥 {email_to_info['description']}",
|
||||||
|
value=current_email_to,
|
||||||
|
disabled=not new_email_enabled,
|
||||||
|
placeholder="receiver@qq.com",
|
||||||
|
key="input_email_to"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["EMAIL_TO"] = new_email_to
|
||||||
|
|
||||||
|
if new_email_enabled and all([new_smtp_server, new_email_from, new_email_password, new_email_to]):
|
||||||
|
st.success("✅ 邮件配置完整")
|
||||||
|
elif new_email_enabled:
|
||||||
|
st.warning("⚠️ 邮件配置不完整")
|
||||||
|
else:
|
||||||
|
st.info("ℹ️ 邮件通知未启用")
|
||||||
|
|
||||||
|
st.caption("💡 QQ邮箱授权码获取:设置 → 账户 → POP3/IMAP/SMTP → 生成授权码")
|
||||||
|
|
||||||
|
with col_webhook:
|
||||||
|
st.markdown("#### 📱 Webhook通知")
|
||||||
|
|
||||||
|
# Webhook启用开关
|
||||||
|
webhook_enabled_info = config_info.get("WEBHOOK_ENABLED", {"value": "false"})
|
||||||
|
current_webhook_enabled = st.session_state.temp_config.get("WEBHOOK_ENABLED", "false") == "true"
|
||||||
|
|
||||||
|
new_webhook_enabled = st.checkbox(
|
||||||
|
"启用Webhook通知",
|
||||||
|
value=current_webhook_enabled,
|
||||||
|
help="开启后可以发送到钉钉或飞书群",
|
||||||
|
key="input_webhook_enabled"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["WEBHOOK_ENABLED"] = "true" if new_webhook_enabled else "false"
|
||||||
|
|
||||||
|
# Webhook类型选择
|
||||||
|
webhook_type_info = config_info.get("WEBHOOK_TYPE", {"description": "Webhook类型", "value": "dingtalk", "options": ["dingtalk", "feishu"]})
|
||||||
|
current_webhook_type = st.session_state.temp_config.get("WEBHOOK_TYPE", "dingtalk")
|
||||||
|
|
||||||
|
new_webhook_type = st.selectbox(
|
||||||
|
f"📲 {webhook_type_info['description']}",
|
||||||
|
options=webhook_type_info.get('options', ["dingtalk", "feishu"]),
|
||||||
|
index=0 if current_webhook_type == "dingtalk" else 1,
|
||||||
|
disabled=not new_webhook_enabled,
|
||||||
|
key="input_webhook_type"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["WEBHOOK_TYPE"] = new_webhook_type
|
||||||
|
|
||||||
|
# Webhook URL
|
||||||
|
webhook_url_info = config_info.get("WEBHOOK_URL", {"description": "Webhook地址", "value": ""})
|
||||||
|
current_webhook_url = st.session_state.temp_config.get("WEBHOOK_URL", "")
|
||||||
|
|
||||||
|
new_webhook_url = st.text_input(
|
||||||
|
f"🔗 {webhook_url_info['description']}",
|
||||||
|
value=current_webhook_url,
|
||||||
|
disabled=not new_webhook_enabled,
|
||||||
|
placeholder="https://oapi.dingtalk.com/robot/send?access_token=...",
|
||||||
|
key="input_webhook_url"
|
||||||
|
)
|
||||||
|
st.session_state.temp_config["WEBHOOK_URL"] = new_webhook_url
|
||||||
|
|
||||||
|
if new_webhook_enabled and new_webhook_url:
|
||||||
|
st.success(f"✅ Webhook配置完整 ({new_webhook_type})")
|
||||||
|
elif new_webhook_enabled:
|
||||||
|
st.warning("⚠️ 请配置Webhook URL")
|
||||||
|
else:
|
||||||
|
st.info("ℹ️ Webhook通知未启用")
|
||||||
|
|
||||||
|
# 显示帮助信息
|
||||||
|
if new_webhook_type == "dingtalk":
|
||||||
|
st.caption("💡 钉钉机器人配置:\n1. 进入钉钉群 → 设置 → 智能群助手\n2. 添加机器人 → 自定义\n3. 复制Webhook地址")
|
||||||
|
else:
|
||||||
|
st.caption("💡 飞书机器人配置:\n1. 进入飞书群 → 设置 → 群机器人\n2. 添加机器人 → 自定义机器人\n3. 复制Webhook地址")
|
||||||
|
|
||||||
|
st.markdown("---")
|
||||||
|
st.info("💡 **使用说明**:\n- 可以同时启用邮件和Webhook通知\n- 实时监测和智策定时分析都会使用配置的通知方式\n- 配置后建议使用各功能中的测试按钮验证通知是否正常")
|
||||||
|
|
||||||
# 操作按钮
|
# 操作按钮
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
col1, col2, col3, col4 = st.columns([1, 1, 1, 2])
|
col1, col2, col3, col4 = st.columns([1, 1, 1, 2])
|
||||||
@@ -2151,6 +2305,19 @@ MINIQMT_ENABLED="{current_config.get('MINIQMT_ENABLED', 'false')}"
|
|||||||
MINIQMT_ACCOUNT_ID="{current_config.get('MINIQMT_ACCOUNT_ID', '')}"
|
MINIQMT_ACCOUNT_ID="{current_config.get('MINIQMT_ACCOUNT_ID', '')}"
|
||||||
MINIQMT_HOST="{current_config.get('MINIQMT_HOST', '127.0.0.1')}"
|
MINIQMT_HOST="{current_config.get('MINIQMT_HOST', '127.0.0.1')}"
|
||||||
MINIQMT_PORT="{current_config.get('MINIQMT_PORT', '58610')}"
|
MINIQMT_PORT="{current_config.get('MINIQMT_PORT', '58610')}"
|
||||||
|
|
||||||
|
# ========== 邮件通知配置(可选)==========
|
||||||
|
EMAIL_ENABLED="{current_config.get('EMAIL_ENABLED', 'false')}"
|
||||||
|
SMTP_SERVER="{current_config.get('SMTP_SERVER', '')}"
|
||||||
|
SMTP_PORT="{current_config.get('SMTP_PORT', '587')}"
|
||||||
|
EMAIL_FROM="{current_config.get('EMAIL_FROM', '')}"
|
||||||
|
EMAIL_PASSWORD="{current_config.get('EMAIL_PASSWORD', '')}"
|
||||||
|
EMAIL_TO="{current_config.get('EMAIL_TO', '')}"
|
||||||
|
|
||||||
|
# ========== Webhook通知配置(可选)==========
|
||||||
|
WEBHOOK_ENABLED="{current_config.get('WEBHOOK_ENABLED', 'false')}"
|
||||||
|
WEBHOOK_TYPE="{current_config.get('WEBHOOK_TYPE', 'dingtalk')}"
|
||||||
|
WEBHOOK_URL="{current_config.get('WEBHOOK_URL', '')}"
|
||||||
""", language="bash")
|
""", language="bash")
|
||||||
|
|
||||||
def display_batch_analysis_results(results, period):
|
def display_batch_analysis_results(results, period):
|
||||||
|
|||||||
@@ -56,6 +56,67 @@ class ConfigManager:
|
|||||||
"required": False,
|
"required": False,
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
|
"EMAIL_ENABLED": {
|
||||||
|
"value": "false",
|
||||||
|
"description": "启用邮件通知",
|
||||||
|
"required": False,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"SMTP_SERVER": {
|
||||||
|
"value": "",
|
||||||
|
"description": "SMTP服务器地址",
|
||||||
|
"required": False,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"SMTP_PORT": {
|
||||||
|
"value": "587",
|
||||||
|
"description": "SMTP服务器端口",
|
||||||
|
"required": False,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"EMAIL_FROM": {
|
||||||
|
"value": "",
|
||||||
|
"description": "发件人邮箱",
|
||||||
|
"required": False,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"EMAIL_PASSWORD": {
|
||||||
|
"value": "",
|
||||||
|
"description": "邮箱授权码",
|
||||||
|
"required": False,
|
||||||
|
"type": "password"
|
||||||
|
},
|
||||||
|
"EMAIL_TO": {
|
||||||
|
"value": "",
|
||||||
|
"description": "收件人邮箱",
|
||||||
|
"required": False,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"WEBHOOK_ENABLED": {
|
||||||
|
"value": "false",
|
||||||
|
"description": "启用Webhook通知",
|
||||||
|
"required": False,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"WEBHOOK_TYPE": {
|
||||||
|
"value": "dingtalk",
|
||||||
|
"description": "Webhook类型(dingtalk/feishu)",
|
||||||
|
"required": False,
|
||||||
|
"type": "select",
|
||||||
|
"options": ["dingtalk", "feishu"]
|
||||||
|
},
|
||||||
|
"WEBHOOK_URL": {
|
||||||
|
"value": "",
|
||||||
|
"description": "Webhook地址",
|
||||||
|
"required": False,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"WEBHOOK_KEYWORD": {
|
||||||
|
"value": "aiagents通知",
|
||||||
|
"description": "Webhook自定义关键词(钉钉安全验证)",
|
||||||
|
"required": False,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def read_env(self) -> Dict[str, str]:
|
def read_env(self) -> Dict[str, str]:
|
||||||
@@ -124,6 +185,24 @@ class ConfigManager:
|
|||||||
lines.append(f'MINIQMT_ACCOUNT_ID="{config.get("MINIQMT_ACCOUNT_ID", "")}"')
|
lines.append(f'MINIQMT_ACCOUNT_ID="{config.get("MINIQMT_ACCOUNT_ID", "")}"')
|
||||||
lines.append(f'MINIQMT_HOST="{config.get("MINIQMT_HOST", "127.0.0.1")}"')
|
lines.append(f'MINIQMT_HOST="{config.get("MINIQMT_HOST", "127.0.0.1")}"')
|
||||||
lines.append(f'MINIQMT_PORT="{config.get("MINIQMT_PORT", "58610")}"')
|
lines.append(f'MINIQMT_PORT="{config.get("MINIQMT_PORT", "58610")}"')
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
# 邮件通知配置
|
||||||
|
lines.append("# ========== 邮件通知配置(可选)==========")
|
||||||
|
lines.append(f'EMAIL_ENABLED="{config.get("EMAIL_ENABLED", "false")}"')
|
||||||
|
lines.append(f'SMTP_SERVER="{config.get("SMTP_SERVER", "")}"')
|
||||||
|
lines.append(f'SMTP_PORT="{config.get("SMTP_PORT", "587")}"')
|
||||||
|
lines.append(f'EMAIL_FROM="{config.get("EMAIL_FROM", "")}"')
|
||||||
|
lines.append(f'EMAIL_PASSWORD="{config.get("EMAIL_PASSWORD", "")}"')
|
||||||
|
lines.append(f'EMAIL_TO="{config.get("EMAIL_TO", "")}"')
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
# Webhook通知配置
|
||||||
|
lines.append("# ========== Webhook通知配置(可选)==========")
|
||||||
|
lines.append(f'WEBHOOK_ENABLED="{config.get("WEBHOOK_ENABLED", "false")}"')
|
||||||
|
lines.append(f'WEBHOOK_TYPE="{config.get("WEBHOOK_TYPE", "dingtalk")}"')
|
||||||
|
lines.append(f'WEBHOOK_URL="{config.get("WEBHOOK_URL", "")}"')
|
||||||
|
lines.append(f'WEBHOOK_KEYWORD="{config.get("WEBHOOK_KEYWORD", "aiagents通知")}"')
|
||||||
|
|
||||||
with open(self.env_file, 'w', encoding='utf-8') as f:
|
with open(self.env_file, 'w', encoding='utf-8') as f:
|
||||||
f.write('\n'.join(lines))
|
f.write('\n'.join(lines))
|
||||||
|
|||||||
+261
-7
@@ -27,7 +27,9 @@ class NotificationService:
|
|||||||
'email_password': '',
|
'email_password': '',
|
||||||
'email_to': '',
|
'email_to': '',
|
||||||
'webhook_enabled': False,
|
'webhook_enabled': False,
|
||||||
'webhook_url': ''
|
'webhook_url': '',
|
||||||
|
'webhook_type': 'dingtalk', # dingtalk 或 feishu
|
||||||
|
'webhook_keyword': 'aiagents通知' # 钉钉自定义关键词
|
||||||
}
|
}
|
||||||
|
|
||||||
# 从环境变量加载配置
|
# 从环境变量加载配置
|
||||||
@@ -43,6 +45,14 @@ class NotificationService:
|
|||||||
config['email_password'] = os.getenv('EMAIL_PASSWORD')
|
config['email_password'] = os.getenv('EMAIL_PASSWORD')
|
||||||
if os.getenv('EMAIL_TO'):
|
if os.getenv('EMAIL_TO'):
|
||||||
config['email_to'] = os.getenv('EMAIL_TO')
|
config['email_to'] = os.getenv('EMAIL_TO')
|
||||||
|
if os.getenv('WEBHOOK_ENABLED'):
|
||||||
|
config['webhook_enabled'] = os.getenv('WEBHOOK_ENABLED').lower() == 'true'
|
||||||
|
if os.getenv('WEBHOOK_URL'):
|
||||||
|
config['webhook_url'] = os.getenv('WEBHOOK_URL')
|
||||||
|
if os.getenv('WEBHOOK_TYPE'):
|
||||||
|
config['webhook_type'] = os.getenv('WEBHOOK_TYPE').lower()
|
||||||
|
if os.getenv('WEBHOOK_KEYWORD'):
|
||||||
|
config['webhook_keyword'] = os.getenv('WEBHOOK_KEYWORD')
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
@@ -75,13 +85,26 @@ class NotificationService:
|
|||||||
|
|
||||||
def send_notification(self, notification: Dict) -> bool:
|
def send_notification(self, notification: Dict) -> bool:
|
||||||
"""发送单个通知"""
|
"""发送单个通知"""
|
||||||
# 优先尝试邮件通知
|
success = False
|
||||||
if self.config['email_enabled']:
|
|
||||||
return self._send_email_notification(notification)
|
|
||||||
|
|
||||||
# 备用方案:在Streamlit界面显示
|
# 尝试webhook通知
|
||||||
self._show_streamlit_notification(notification)
|
if self.config['webhook_enabled']:
|
||||||
return True
|
webhook_success = self._send_webhook_notification(notification)
|
||||||
|
if webhook_success:
|
||||||
|
success = True
|
||||||
|
|
||||||
|
# 尝试邮件通知
|
||||||
|
if self.config['email_enabled']:
|
||||||
|
email_success = self._send_email_notification(notification)
|
||||||
|
if email_success:
|
||||||
|
success = True
|
||||||
|
|
||||||
|
# 如果两者都未启用或都失败,使用界面通知作为备用
|
||||||
|
if not success:
|
||||||
|
self._show_streamlit_notification(notification)
|
||||||
|
success = True
|
||||||
|
|
||||||
|
return success
|
||||||
|
|
||||||
def _send_email_notification(self, notification: Dict) -> bool:
|
def _send_email_notification(self, notification: Dict) -> bool:
|
||||||
"""发送邮件通知"""
|
"""发送邮件通知"""
|
||||||
@@ -262,6 +285,237 @@ class NotificationService:
|
|||||||
self.config['email_to']
|
self.config['email_to']
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _send_webhook_notification(self, notification: Dict) -> bool:
|
||||||
|
"""发送Webhook通知"""
|
||||||
|
try:
|
||||||
|
# 检查webhook配置是否完整
|
||||||
|
if not self.config['webhook_url']:
|
||||||
|
print("⚠️ Webhook URL未配置")
|
||||||
|
return False
|
||||||
|
|
||||||
|
webhook_type = self.config['webhook_type']
|
||||||
|
|
||||||
|
if webhook_type == 'dingtalk':
|
||||||
|
return self._send_dingtalk_webhook(notification)
|
||||||
|
elif webhook_type == 'feishu':
|
||||||
|
return self._send_feishu_webhook(notification)
|
||||||
|
else:
|
||||||
|
print(f"⚠️ 不支持的webhook类型: {webhook_type}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Webhook发送失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _send_dingtalk_webhook(self, notification: Dict) -> bool:
|
||||||
|
"""发送钉钉Webhook通知"""
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# 构建钉钉消息格式(包含自定义关键词)
|
||||||
|
keyword = self.config.get('webhook_keyword', '')
|
||||||
|
title_prefix = f"{keyword} - " if keyword else ""
|
||||||
|
content_prefix = f"### {keyword} - " if keyword else "### "
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"msgtype": "markdown",
|
||||||
|
"markdown": {
|
||||||
|
"title": f"{title_prefix}{notification['symbol']} {notification['name']}",
|
||||||
|
"text": f"""{content_prefix}股票监测提醒
|
||||||
|
|
||||||
|
**股票代码**: {notification['symbol']}
|
||||||
|
|
||||||
|
**股票名称**: {notification['name']}
|
||||||
|
|
||||||
|
**提醒类型**: {notification['type']}
|
||||||
|
|
||||||
|
**提醒内容**: {notification['message']}
|
||||||
|
|
||||||
|
**触发时间**: {notification['triggered_at']}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_此消息由AI股票分析系统自动发送_"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print(f"[钉钉] 正在发送Webhook...")
|
||||||
|
print(f" - URL: {self.config['webhook_url'][:50]}...")
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
self.config['webhook_url'],
|
||||||
|
json=data,
|
||||||
|
headers={'Content-Type': 'application/json'},
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
if result.get('errcode') == 0:
|
||||||
|
print(f"[成功] 钉钉Webhook发送成功")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"[失败] 钉钉Webhook返回错误: {result.get('errmsg')}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print(f"[失败] 钉钉Webhook请求失败: HTTP {response.status_code}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"钉钉Webhook发送异常: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _send_feishu_webhook(self, notification: Dict) -> bool:
|
||||||
|
"""发送飞书Webhook通知"""
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# 构建飞书消息格式
|
||||||
|
data = {
|
||||||
|
"msg_type": "interactive",
|
||||||
|
"card": {
|
||||||
|
"header": {
|
||||||
|
"title": {
|
||||||
|
"content": f"📊 股票监测提醒 - {notification['symbol']}",
|
||||||
|
"tag": "plain_text"
|
||||||
|
},
|
||||||
|
"template": "blue"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"tag": "div",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"is_short": True,
|
||||||
|
"text": {
|
||||||
|
"content": f"**股票代码**\n{notification['symbol']}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_short": True,
|
||||||
|
"text": {
|
||||||
|
"content": f"**股票名称**\n{notification['name']}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "div",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"is_short": True,
|
||||||
|
"text": {
|
||||||
|
"content": f"**提醒类型**\n{notification['type']}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_short": True,
|
||||||
|
"text": {
|
||||||
|
"content": f"**触发时间**\n{notification['triggered_at']}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "div",
|
||||||
|
"text": {
|
||||||
|
"content": f"**提醒内容**\n{notification['message']}",
|
||||||
|
"tag": "lark_md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "hr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "note",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"tag": "plain_text",
|
||||||
|
"content": "此消息由AI股票分析系统自动发送"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print(f"[飞书] 正在发送Webhook...")
|
||||||
|
print(f" - URL: {self.config['webhook_url'][:50]}...")
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
self.config['webhook_url'],
|
||||||
|
json=data,
|
||||||
|
headers={'Content-Type': 'application/json'},
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
if result.get('code') == 0:
|
||||||
|
print(f"[成功] 飞书Webhook发送成功")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"[失败] 飞书Webhook返回错误: {result.get('msg')}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print(f"[失败] 飞书Webhook请求失败: HTTP {response.status_code}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"飞书Webhook发送异常: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def send_test_webhook(self) -> tuple[bool, str]:
|
||||||
|
"""发送测试Webhook"""
|
||||||
|
try:
|
||||||
|
# 检查webhook配置是否完整
|
||||||
|
if not self.config['webhook_url']:
|
||||||
|
return False, "Webhook URL未配置,请检查环境变量设置"
|
||||||
|
|
||||||
|
# 创建测试通知(包含关键词"aiagents通知"以通过钉钉安全设置)
|
||||||
|
test_notification = {
|
||||||
|
'symbol': '测试',
|
||||||
|
'name': 'Webhook配置测试',
|
||||||
|
'type': '系统测试',
|
||||||
|
'message': '如果您收到此消息,说明Webhook配置正确!',
|
||||||
|
'triggered_at': '刚刚'
|
||||||
|
}
|
||||||
|
|
||||||
|
webhook_type = self.config['webhook_type']
|
||||||
|
|
||||||
|
if webhook_type == 'dingtalk':
|
||||||
|
success = self._send_dingtalk_webhook(test_notification)
|
||||||
|
if success:
|
||||||
|
return True, "钉钉Webhook测试成功!请检查钉钉群消息。"
|
||||||
|
else:
|
||||||
|
return False, "钉钉Webhook发送失败,请检查URL和网络连接"
|
||||||
|
|
||||||
|
elif webhook_type == 'feishu':
|
||||||
|
success = self._send_feishu_webhook(test_notification)
|
||||||
|
if success:
|
||||||
|
return True, "飞书Webhook测试成功!请检查飞书群消息。"
|
||||||
|
else:
|
||||||
|
return False, "飞书Webhook发送失败,请检查URL和网络连接"
|
||||||
|
|
||||||
|
else:
|
||||||
|
return False, f"不支持的webhook类型: {webhook_type}"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return False, f"发送失败: {str(e)}"
|
||||||
|
|
||||||
|
def get_webhook_config_status(self) -> Dict:
|
||||||
|
"""获取Webhook配置状态"""
|
||||||
|
return {
|
||||||
|
'enabled': self.config['webhook_enabled'],
|
||||||
|
'webhook_type': self.config['webhook_type'],
|
||||||
|
'webhook_url': self.config['webhook_url'][:50] + '...' if self.config['webhook_url'] else '未配置',
|
||||||
|
'configured': bool(self.config['webhook_url'])
|
||||||
|
}
|
||||||
|
|
||||||
# 全局通知服务实例
|
# 全局通知服务实例
|
||||||
notification_service = NotificationService()
|
notification_service = NotificationService()
|
||||||
+168
-20
@@ -128,36 +128,46 @@ class SectorStrategyScheduler:
|
|||||||
self._send_error_notification(f"分析异常: {str(e)}")
|
self._send_error_notification(f"分析异常: {str(e)}")
|
||||||
|
|
||||||
def _send_analysis_notification(self, result):
|
def _send_analysis_notification(self, result):
|
||||||
"""发送分析结果邮件"""
|
"""发送分析结果通知(邮件和/或webhook)"""
|
||||||
try:
|
try:
|
||||||
# 检查邮件配置
|
|
||||||
config = notification_service.config
|
config = notification_service.config
|
||||||
if not config.get('email_enabled') or not all([
|
predictions = result.get("final_predictions", {})
|
||||||
|
timestamp = result.get("timestamp", datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
|
||||||
|
|
||||||
|
sent_count = 0
|
||||||
|
|
||||||
|
# 尝试发送Webhook
|
||||||
|
if config.get('webhook_enabled') and config.get('webhook_url'):
|
||||||
|
print("[智策定时] [Webhook] 准备发送...")
|
||||||
|
webhook_success = self._send_webhook_direct(predictions, timestamp)
|
||||||
|
if webhook_success:
|
||||||
|
print("[智策定时] ✓ Webhook发送成功")
|
||||||
|
sent_count += 1
|
||||||
|
else:
|
||||||
|
print("[智策定时] ✗ Webhook发送失败")
|
||||||
|
|
||||||
|
# 尝试发送邮件
|
||||||
|
if config.get('email_enabled') and all([
|
||||||
config.get('smtp_server'),
|
config.get('smtp_server'),
|
||||||
config.get('email_from'),
|
config.get('email_from'),
|
||||||
config.get('email_password'),
|
config.get('email_password'),
|
||||||
config.get('email_to')
|
config.get('email_to')
|
||||||
]):
|
]):
|
||||||
print("[智策定时] ⚠️ 邮件配置不完整,跳过发送")
|
print("[智策定时] [邮件] 准备发送...")
|
||||||
return
|
subject = f"智策板块分析报告 - {timestamp}"
|
||||||
|
body = self._format_email_body(predictions, timestamp)
|
||||||
|
email_success = self._send_email_direct(subject, body)
|
||||||
|
if email_success:
|
||||||
|
print("[智策定时] ✓ 邮件发送成功")
|
||||||
|
sent_count += 1
|
||||||
|
else:
|
||||||
|
print("[智策定时] ✗ 邮件发送失败")
|
||||||
|
|
||||||
predictions = result.get("final_predictions", {})
|
if sent_count == 0:
|
||||||
timestamp = result.get("timestamp", datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
|
print("[智策定时] ⚠️ 未配置通知方式或发送全部失败")
|
||||||
|
|
||||||
# 构建邮件内容
|
|
||||||
subject = f"智策板块分析报告 - {timestamp}"
|
|
||||||
body = self._format_email_body(predictions, timestamp)
|
|
||||||
|
|
||||||
# 直接发送邮件
|
|
||||||
success = self._send_email_direct(subject, body)
|
|
||||||
|
|
||||||
if success:
|
|
||||||
print("[智策定时] ✓ 邮件发送成功")
|
|
||||||
else:
|
|
||||||
print("[智策定时] ✗ 邮件发送失败")
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[智策定时] ✗ 邮件发送异常: {e}")
|
print(f"[智策定时] ✗ 通知发送异常: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
@@ -177,6 +187,144 @@ class SectorStrategyScheduler:
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _send_webhook_direct(self, predictions, timestamp):
|
||||||
|
"""发送webhook通知"""
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
|
||||||
|
config = notification_service.config
|
||||||
|
webhook_type = config.get('webhook_type', 'dingtalk')
|
||||||
|
webhook_url = config['webhook_url']
|
||||||
|
|
||||||
|
# 格式化简洁的分析摘要
|
||||||
|
summary = self._format_webhook_summary(predictions, timestamp)
|
||||||
|
|
||||||
|
if webhook_type == 'dingtalk':
|
||||||
|
return self._send_dingtalk(webhook_url, summary, timestamp)
|
||||||
|
elif webhook_type == 'feishu':
|
||||||
|
return self._send_feishu(webhook_url, summary, timestamp)
|
||||||
|
else:
|
||||||
|
print(f"[智策定时] ✗ 不支持的webhook类型: {webhook_type}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[智策定时] ✗ Webhook发送失败: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _send_dingtalk(self, url, summary, timestamp):
|
||||||
|
"""发送钉钉消息"""
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# 获取自定义关键词
|
||||||
|
keyword = notification_service.config.get('webhook_keyword', '')
|
||||||
|
title_prefix = f"{keyword} - " if keyword else ""
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"msgtype": "markdown",
|
||||||
|
"markdown": {
|
||||||
|
"title": f"{title_prefix}智策板块分析报告",
|
||||||
|
"text": summary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(url, json=data, headers={'Content-Type': 'application/json'}, timeout=10)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
return result.get('errcode') == 0
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[智策定时] 钉钉发送异常: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _send_feishu(self, url, summary, timestamp):
|
||||||
|
"""发送飞书消息"""
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# 获取自定义关键词(飞书通常不需要关键词,但保持一致性)
|
||||||
|
keyword = notification_service.config.get('webhook_keyword', '')
|
||||||
|
title_prefix = f"【{keyword} - " if keyword else "【"
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"msg_type": "text",
|
||||||
|
"content": {
|
||||||
|
"text": f"{title_prefix}智策板块分析报告】\n分析时间: {timestamp}\n\n{summary}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(url, json=data, headers={'Content-Type': 'application/json'}, timeout=10)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
return result.get('code') == 0
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[智策定时] 飞书发送异常: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _format_webhook_summary(self, predictions, timestamp):
|
||||||
|
"""格式化webhook摘要(精简版)"""
|
||||||
|
# 获取自定义关键词
|
||||||
|
keyword = notification_service.config.get('webhook_keyword', '')
|
||||||
|
title_prefix = f"{keyword} - " if keyword else ""
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
lines.append(f"### {title_prefix}智策板块分析报告")
|
||||||
|
lines.append(f"**分析时间**: {timestamp}")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
# 板块多空(只显示高信心度的)
|
||||||
|
long_short = predictions.get("long_short", {})
|
||||||
|
if long_short:
|
||||||
|
bullish = [item for item in long_short.get("bullish", []) if item.get('confidence', 0) >= 7]
|
||||||
|
bearish = [item for item in long_short.get("bearish", []) if item.get('confidence', 0) >= 7]
|
||||||
|
|
||||||
|
if bullish or bearish:
|
||||||
|
lines.append("#### 📊 板块多空")
|
||||||
|
if bullish:
|
||||||
|
lines.append("**看多**: " + "、".join([f"{item.get('sector')}({item.get('confidence')}分)" for item in bullish[:3]]))
|
||||||
|
if bearish:
|
||||||
|
lines.append("**看空**: " + "、".join([f"{item.get('sector')}({item.get('confidence')}分)" for item in bearish[:3]]))
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
# 板块轮动(只显示潜力板块)
|
||||||
|
rotation = predictions.get("rotation", {})
|
||||||
|
if rotation:
|
||||||
|
potential = rotation.get("potential", [])[:3]
|
||||||
|
if potential:
|
||||||
|
lines.append("#### 🔄 潜力接力板块")
|
||||||
|
for item in potential:
|
||||||
|
lines.append(f"- {item.get('sector')}: {item.get('advice', 'N/A')}")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
# 板块热度TOP3
|
||||||
|
heat = predictions.get("heat", {})
|
||||||
|
if heat:
|
||||||
|
hottest = heat.get("hottest", [])[:3]
|
||||||
|
if hottest:
|
||||||
|
lines.append("#### 🌡️ 热度TOP3")
|
||||||
|
for idx, item in enumerate(hottest, 1):
|
||||||
|
lines.append(f"{idx}. {item.get('sector')} - {item.get('score', 0)}分")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
# 策略总结
|
||||||
|
summary = predictions.get("summary", {})
|
||||||
|
if summary and summary.get('key_opportunity'):
|
||||||
|
lines.append("#### 💡 核心机会")
|
||||||
|
lines.append(summary['key_opportunity'][:150] + "..." if len(summary.get('key_opportunity', '')) > 150 else summary.get('key_opportunity', ''))
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
lines.append("---")
|
||||||
|
lines.append("*由智策AI系统自动生成*")
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
def _send_email_direct(self, subject, body):
|
def _send_email_direct(self, subject, body):
|
||||||
"""直接发送邮件(参考notification_service的实现)"""
|
"""直接发送邮件(参考notification_service的实现)"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""更新.env.example模板文件"""
|
||||||
|
|
||||||
|
env_example_content = """# ============================================================
|
||||||
|
# AI股票分析系统环境配置模板
|
||||||
|
# ============================================================
|
||||||
|
# 使用说明:
|
||||||
|
# 1. 复制此文件并重命名为 .env
|
||||||
|
# 2. 根据实际情况填写配置项
|
||||||
|
# 3. 敏感信息(如API密钥、密码)请妥善保管,不要提交到版本控制
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# ========== DeepSeek API配置 ==========
|
||||||
|
# DeepSeek API密钥(必填)
|
||||||
|
# 获取地址:https://platform.deepseek.com/api_keys
|
||||||
|
DEEPSEEK_API_KEY=your_actual_deepseek_api_key_here
|
||||||
|
|
||||||
|
# DeepSeek API基础URL(可选,使用默认值即可)
|
||||||
|
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
|
||||||
|
|
||||||
|
|
||||||
|
# ========== Tushare数据接口(可选)==========
|
||||||
|
# Tushare Token(可选,用于获取更多金融数据)
|
||||||
|
# 获取地址:https://tushare.pro/register
|
||||||
|
TUSHARE_TOKEN=
|
||||||
|
|
||||||
|
|
||||||
|
# ========== MiniQMT量化交易配置(可选)==========
|
||||||
|
# 是否启用MiniQMT量化交易接口
|
||||||
|
MINIQMT_ENABLED=false
|
||||||
|
|
||||||
|
# MiniQMT账户ID
|
||||||
|
MINIQMT_ACCOUNT_ID=
|
||||||
|
|
||||||
|
# MiniQMT服务器地址
|
||||||
|
MINIQMT_HOST=127.0.0.1
|
||||||
|
|
||||||
|
# MiniQMT服务器端口
|
||||||
|
MINIQMT_PORT=58610
|
||||||
|
|
||||||
|
|
||||||
|
# ========== 邮件通知配置(可选)==========
|
||||||
|
# 是否启用邮件通知
|
||||||
|
EMAIL_ENABLED=false
|
||||||
|
|
||||||
|
# SMTP服务器地址
|
||||||
|
# 常用邮箱SMTP服务器:
|
||||||
|
# - 163邮箱:smtp.163.com
|
||||||
|
# - QQ邮箱:smtp.qq.com
|
||||||
|
# - Gmail:smtp.gmail.com
|
||||||
|
# - 企业邮箱:根据邮箱服务商提供的信息填写
|
||||||
|
SMTP_SERVER=smtp.163.com
|
||||||
|
|
||||||
|
# SMTP服务器端口
|
||||||
|
# 常用端口:
|
||||||
|
# - 465:SSL加密连接(推荐)
|
||||||
|
# - 587:TLS加密连接
|
||||||
|
SMTP_PORT=465
|
||||||
|
|
||||||
|
# 发件人邮箱地址
|
||||||
|
EMAIL_FROM=your_email@163.com
|
||||||
|
|
||||||
|
# 邮箱授权码(不是登录密码!)
|
||||||
|
# 获取方法:
|
||||||
|
# - 163邮箱:设置 -> POP3/SMTP/IMAP -> 开启服务 -> 获取授权码
|
||||||
|
# - QQ邮箱:设置 -> 账户 -> POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 -> 开启服务 -> 生成授权码
|
||||||
|
EMAIL_PASSWORD=your_email_authorization_code
|
||||||
|
|
||||||
|
# 收件人邮箱地址(接收通知的邮箱)
|
||||||
|
EMAIL_TO=receiver@example.com
|
||||||
|
|
||||||
|
|
||||||
|
# ========== Webhook通知配置(可选)==========
|
||||||
|
# 是否启用Webhook通知(钉钉/飞书)
|
||||||
|
WEBHOOK_ENABLED=false
|
||||||
|
|
||||||
|
# Webhook类型
|
||||||
|
# 可选值:dingtalk(钉钉)、feishu(飞书)
|
||||||
|
WEBHOOK_TYPE=dingtalk
|
||||||
|
|
||||||
|
# Webhook地址
|
||||||
|
# 钉钉机器人:https://oapi.dingtalk.com/robot/send?access_token=YOUR_ACCESS_TOKEN
|
||||||
|
# 飞书机器人:https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_HOOK_ID
|
||||||
|
WEBHOOK_URL=
|
||||||
|
|
||||||
|
# Webhook自定义关键词(仅钉钉需要)
|
||||||
|
# 说明:
|
||||||
|
# - 如果钉钉机器人设置了"自定义关键词"安全验证,请在此填写关键词
|
||||||
|
# - 系统会自动在消息标题和内容中包含此关键词
|
||||||
|
# - 如果不使用关键词验证,可以留空或使用其他安全方式(加签、IP白名单)
|
||||||
|
# - 飞书机器人通常不需要关键词,可以留空
|
||||||
|
# 示例:aiagents通知
|
||||||
|
WEBHOOK_KEYWORD=
|
||||||
|
|
||||||
|
|
||||||
|
# ========== 时区配置 ==========
|
||||||
|
# 系统时区设置(可选)
|
||||||
|
TZ=Asia/Shanghai
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open('.env.example', 'w', encoding='utf-8') as f:
|
||||||
|
f.write(env_example_content)
|
||||||
|
|
||||||
|
print("[OK] .env.example file updated successfully")
|
||||||
|
print("[OK] File encoding: UTF-8")
|
||||||
|
print("[OK] All Chinese characters should display correctly")
|
||||||
|
|
||||||
+49
@@ -53,6 +53,55 @@
|
|||||||
|
|
||||||
- **⚠️ 警告**:量化交易涉及真实资金操作,请谨慎配置和使用!
|
- **⚠️ 警告**:量化交易涉及真实资金操作,请谨慎配置和使用!
|
||||||
|
|
||||||
|
### 4. 通知配置(可选)⭐新增
|
||||||
|
|
||||||
|
#### 📧 邮件通知
|
||||||
|
- **启用开关**
|
||||||
|
- 描述:是否启用邮件通知功能
|
||||||
|
- 默认:关闭
|
||||||
|
- 适用:实时监测和智策定时分析
|
||||||
|
|
||||||
|
- **SMTP服务器地址**
|
||||||
|
- 描述:邮件服务器地址
|
||||||
|
- 示例:`smtp.qq.com`、`smtp.163.com`
|
||||||
|
|
||||||
|
- **SMTP端口**
|
||||||
|
- 描述:邮件服务器端口
|
||||||
|
- 默认:`587` (TLS) 或 `465` (SSL)
|
||||||
|
|
||||||
|
- **发件人邮箱**
|
||||||
|
- 描述:发送通知的邮箱地址
|
||||||
|
- 示例:`your-email@qq.com`
|
||||||
|
|
||||||
|
- **邮箱授权码**
|
||||||
|
- 描述:SMTP服务授权码(不是登录密码)
|
||||||
|
- 获取:邮箱设置 → SMTP服务 → 生成授权码
|
||||||
|
|
||||||
|
- **收件人邮箱**
|
||||||
|
- 描述:接收通知的邮箱地址
|
||||||
|
- 示例:`recipient@qq.com`
|
||||||
|
|
||||||
|
#### 📱 Webhook通知
|
||||||
|
- **启用开关**
|
||||||
|
- 描述:是否启用Webhook通知功能
|
||||||
|
- 默认:关闭
|
||||||
|
- 适用:实时监测和智策定时分析
|
||||||
|
|
||||||
|
- **Webhook类型**
|
||||||
|
- 描述:选择Webhook平台
|
||||||
|
- 选项:钉钉 (`dingtalk`) 或 飞书 (`feishu`)
|
||||||
|
|
||||||
|
- **Webhook地址**
|
||||||
|
- 描述:机器人Webhook URL
|
||||||
|
- 钉钉示例:`https://oapi.dingtalk.com/robot/send?access_token=xxxxx`
|
||||||
|
- 飞书示例:`https://open.feishu.cn/open-apis/bot/v2/hook/xxxxx`
|
||||||
|
- 获取:群设置 → 群机器人 → 添加自定义机器人
|
||||||
|
|
||||||
|
**💡 提示**:
|
||||||
|
- 邮件和Webhook可以同时启用
|
||||||
|
- 配置后建议使用测试功能验证
|
||||||
|
- 详见《Webhook通知配置指南.md》
|
||||||
|
|
||||||
## 使用流程
|
## 使用流程
|
||||||
|
|
||||||
1. **进入配置页面**
|
1. **进入配置页面**
|
||||||
|
|||||||
+236
@@ -0,0 +1,236 @@
|
|||||||
|
# 环境配置快速指南
|
||||||
|
|
||||||
|
## 📋 配置步骤
|
||||||
|
|
||||||
|
### 1. 创建配置文件
|
||||||
|
|
||||||
|
如果您是首次使用,请复制模板文件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Windows PowerShell
|
||||||
|
Copy-Item .env.example .env
|
||||||
|
|
||||||
|
# Linux/Mac
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 配置必填项
|
||||||
|
|
||||||
|
#### ✅ DeepSeek API配置(必填)
|
||||||
|
|
||||||
|
1. 访问 [DeepSeek Platform](https://platform.deepseek.com/api_keys)
|
||||||
|
2. 注册/登录账号
|
||||||
|
3. 创建API密钥
|
||||||
|
4. 在`.env`文件中填写:
|
||||||
|
|
||||||
|
```env
|
||||||
|
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 配置可选项
|
||||||
|
|
||||||
|
#### 📧 邮件通知配置(推荐)
|
||||||
|
|
||||||
|
**配置示例(163邮箱):**
|
||||||
|
|
||||||
|
```env
|
||||||
|
EMAIL_ENABLED=true
|
||||||
|
SMTP_SERVER=smtp.163.com
|
||||||
|
SMTP_PORT=465
|
||||||
|
EMAIL_FROM=your_email@163.com
|
||||||
|
EMAIL_PASSWORD=your_authorization_code
|
||||||
|
EMAIL_TO=receiver@qq.com
|
||||||
|
```
|
||||||
|
|
||||||
|
**获取邮箱授权码:**
|
||||||
|
|
||||||
|
1. **163邮箱**
|
||||||
|
- 登录163邮箱网页版
|
||||||
|
- 设置 → POP3/SMTP/IMAP
|
||||||
|
- 开启"POP3/SMTP服务"
|
||||||
|
- 点击"生成授权码"
|
||||||
|
- 复制授权码(16位字符)
|
||||||
|
|
||||||
|
2. **QQ邮箱**
|
||||||
|
- 登录QQ邮箱网页版
|
||||||
|
- 设置 → 账户
|
||||||
|
- 找到"POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务"
|
||||||
|
- 开启"POP3/SMTP服务"
|
||||||
|
- 点击"生成授权码"
|
||||||
|
- 按提示完成验证
|
||||||
|
|
||||||
|
**常用SMTP配置:**
|
||||||
|
|
||||||
|
| 邮箱类型 | SMTP服务器 | SSL端口 | TLS端口 |
|
||||||
|
|---------|-----------|---------|---------|
|
||||||
|
| 163邮箱 | smtp.163.com | 465 | 587 |
|
||||||
|
| QQ邮箱 | smtp.qq.com | 465 | 587 |
|
||||||
|
| Gmail | smtp.gmail.com | 465 | 587 |
|
||||||
|
| 126邮箱 | smtp.126.com | 465 | 587 |
|
||||||
|
|
||||||
|
#### 📱 Webhook通知配置(可选)
|
||||||
|
|
||||||
|
**钉钉机器人配置:**
|
||||||
|
|
||||||
|
1. 在钉钉群中添加自定义机器人
|
||||||
|
2. 安全设置选择"自定义关键词"
|
||||||
|
3. **关键词必须设置为:`aiagents通知`**
|
||||||
|
4. 复制Webhook地址
|
||||||
|
5. 在`.env`文件中填写:
|
||||||
|
|
||||||
|
```env
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=dingtalk
|
||||||
|
WEBHOOK_URL=https://oapi.dingtalk.com/robot/send?access_token=xxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
**飞书机器人配置:**
|
||||||
|
|
||||||
|
1. 在飞书群中添加自定义机器人
|
||||||
|
2. 复制Webhook地址
|
||||||
|
3. 在`.env`文件中填写:
|
||||||
|
|
||||||
|
```env
|
||||||
|
WEBHOOK_ENABLED=true
|
||||||
|
WEBHOOK_TYPE=feishu
|
||||||
|
WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 📊 Tushare数据接口(可选)
|
||||||
|
|
||||||
|
1. 访问 [Tushare官网](https://tushare.pro/register)
|
||||||
|
2. 注册账号
|
||||||
|
3. 获取Token
|
||||||
|
4. 在`.env`文件中填写:
|
||||||
|
|
||||||
|
```env
|
||||||
|
TUSHARE_TOKEN=your_tushare_token_here
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 💹 MiniQMT量化交易(可选)
|
||||||
|
|
||||||
|
如果您使用MiniQMT进行量化交易:
|
||||||
|
|
||||||
|
```env
|
||||||
|
MINIQMT_ENABLED=true
|
||||||
|
MINIQMT_ACCOUNT_ID=your_account_id
|
||||||
|
MINIQMT_HOST=127.0.0.1
|
||||||
|
MINIQMT_PORT=58610
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 配置测试
|
||||||
|
|
||||||
|
配置完成后,运行测试工具验证配置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Windows
|
||||||
|
.\venv\Scripts\python.exe test_notification_config.py
|
||||||
|
|
||||||
|
# Linux/Mac
|
||||||
|
python test_notification_config.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**测试结果示例:**
|
||||||
|
|
||||||
|
```
|
||||||
|
============================================================
|
||||||
|
通知配置测试工具
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
[邮件] 测试邮件配置
|
||||||
|
- 启用状态: [已启用]
|
||||||
|
- SMTP服务器: smtp.163.com
|
||||||
|
- 配置完整性: [完整]
|
||||||
|
[成功] 测试邮件发送成功!
|
||||||
|
|
||||||
|
[Webhook] 测试Webhook配置
|
||||||
|
- 启用状态: [已启用]
|
||||||
|
- Webhook类型: dingtalk
|
||||||
|
- 配置完整性: [完整]
|
||||||
|
[成功] 钉钉Webhook测试成功!
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
测试结果汇总
|
||||||
|
============================================================
|
||||||
|
邮件通知: [OK] 正常
|
||||||
|
Webhook通知: [OK] 正常
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚠️ 常见问题
|
||||||
|
|
||||||
|
### Q1: 邮件发送失败 - 认证错误
|
||||||
|
|
||||||
|
**问题**:`SMTPAuthenticationError`
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 确认使用的是**授权码**,不是登录密码
|
||||||
|
- 检查邮箱是否开启了POP3/SMTP服务
|
||||||
|
- 163邮箱授权码需要在邮箱设置中生成
|
||||||
|
|
||||||
|
### Q2: 钉钉消息发送失败 - 关键词不匹配
|
||||||
|
|
||||||
|
**问题**:`关键词不匹配`
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 确保钉钉机器人的自定义关键词设置为:**`aiagents通知`**
|
||||||
|
- 或者修改机器人安全设置为"加签"或"IP地址"
|
||||||
|
|
||||||
|
### Q3: 网络连接失败
|
||||||
|
|
||||||
|
**问题**:`getaddrinfo failed` 或 `Connection timeout`
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 检查网络连接
|
||||||
|
- 检查防火墙设置
|
||||||
|
- 确认SMTP服务器地址正确
|
||||||
|
- 尝试使用不同的端口(465或587)
|
||||||
|
|
||||||
|
### Q4: .env文件中文乱码
|
||||||
|
|
||||||
|
**问题**:编辑器显示中文乱码
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 使用UTF-8编码打开文件
|
||||||
|
- VS Code:右下角点击编码 → 选择"UTF-8"
|
||||||
|
- 记事本:另存为时选择"UTF-8"编码
|
||||||
|
|
||||||
|
## 📁 配置文件说明
|
||||||
|
|
||||||
|
```
|
||||||
|
.env.example # 配置模板(提交到版本控制)
|
||||||
|
.env # 实际配置(不提交到版本控制,包含敏感信息)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 安全建议
|
||||||
|
|
||||||
|
1. **不要提交.env文件到版本控制系统**
|
||||||
|
- `.env`文件已在`.gitignore`中
|
||||||
|
- 只提交`.env.example`模板
|
||||||
|
|
||||||
|
2. **定期更换密钥**
|
||||||
|
- 建议定期更换API密钥和授权码
|
||||||
|
- 如发现泄露,立即更换
|
||||||
|
|
||||||
|
3. **权限控制**
|
||||||
|
- 限制`.env`文件的访问权限
|
||||||
|
- 不要在公开场合分享配置信息
|
||||||
|
|
||||||
|
## 📚 相关文档
|
||||||
|
|
||||||
|
- [邮件配置指南.md](邮件配置指南.md) - 详细的邮件配置说明
|
||||||
|
- [Webhook通知配置指南.md](Webhook通知配置指南.md) - Webhook配置详解
|
||||||
|
- [通知功能修复说明.md](通知功能修复说明.md) - 问题排查指南
|
||||||
|
|
||||||
|
## 🆘 需要帮助?
|
||||||
|
|
||||||
|
如遇到问题:
|
||||||
|
1. 运行测试工具查看详细错误信息
|
||||||
|
2. 查看相关文档
|
||||||
|
3. 检查系统日志
|
||||||
|
4. 参考常见问题解答
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**更新时间**: 2025-10-14
|
||||||
|
**版本**: v1.0
|
||||||
|
|
||||||
Reference in New Issue
Block a user