Prodelaya/auto-reddit
GitHub: Prodelaya/auto-reddit
一款AI驱动的Reddit商机检测系统,帮助营销团队自动化发现和筛选目标帖子并生成回复建议,通过Telegram推送供人工决策。
Stars: 0 | Forks: 0
# auto-reddit
## 项目概述
auto-reddit 是一个针对使用 Odoo 的营销和内容团队的每日 Reddit 参与机会检测系统。
该产品解决了一个具体的运营问题:手动跟踪 Reddit 以检测一家在 Odoo 方面有经验的公司可以提供价值的帖子既耗时又难以系统化。auto-reddit 自动化了这种监控,并每天提供一组经过过滤和评估的机会,直接发送到 Telegram,并提供足够的上下文供人工决定是否介入。
该产品的指导原则很明确:**AI 提议,人类决定并发布**。该系统从未自主在 Reddit 上发布内容。其唯一功能是减少检测和准备工作,将标准和最终行动始终掌握在团队手中。
主要用户是营销和内容团队。第一个切片的数据源是 `r/Odoo`。
当前与 Reddit 集成的操作参考是 `docs/integrations/reddit/api-strategy.md`。
供维护者查阅的完整文档地图:[`docs/README.md`](docs/README.md)。
## 技术栈
| 组件 | 技术 |
|---|---|
| 语言 | Python 3.14 |
| 依赖管理器 | uv |
| 部署 | Docker on VPS (临时容器 + 外部 cron) |
| 持久化 | SQLite (Docker 卷中的文件) |
| 内部合约 | Pydantic |
| 配置和密钥 | pydantic-settings + `.env` |
| AI 评估 | DeepSeek via OpenAI SDK |
| 通知 | Telegram Bot API |
| 数据源 | RapidAPI (reddit3, reddit34, reddapi, reddit-com) |
| CI | GitHub Actions |
运营模式是一个临时容器:启动,执行完整的每日流程,然后消亡。没有持续运行的后台进程。VPS 上的外部 cron 负责调度。
## 安装和运行
### 依赖项
```
uv sync --extra dev
```
### 配置
复制示例文件并填写 4 个必填变量:
```
cp .env.example .env
```
`.env` 中的必填变量:
| 变量 | 描述 |
|---|---|
| `DEEPSEEK_API_KEY` | 用于 AI 评估的 DeepSeek API key |
| `TELEGRAM_BOT_TOKEN` | 用于通知的 Telegram bot token |
| `TELEGRAM_CHAT_ID` | 发送通知的聊天 ID |
| `REDDIT_API_KEY` | 用于访问 Reddit 的 RapidAPI API key |
可选变量(带默认值):
| 变量 | 默认值 | 描述 |
|---|---|---|
| `REVIEW_WINDOW_DAYS` | `7` | 搜索窗口(天) |
| `DAILY_REVIEW_LIMIT` | `8` | 每次执行最多审查的候选数 |
| `MAX_DAILY_OPPORTUNITIES` | `8` | 每天最多提供的机会数 |
| `DB_PATH` | `auto_reddit.db` | SQLite 文件路径 |
| `DEEPSEEK_MODEL` | `deepseek-chat` | 要使用的 DeepSeek 模型 |
### 运行测试
```
uv run pytest tests/ -x --tb=short
```
### VPS 部署
运营模式是一个**临时容器**:启动,执行完整的 pipeline,然后消亡。没有持久进程。为了每天运行,你需要在 VPS 上有一个外部 cron。
#### 步骤 1 — 准备环境
```
# 如果端口 22 (SSH) 被阻止,使用 HTTPS:
git clone https://github.com/Prodelaya/auto-reddit.git
cd auto-reddit
cp .env.example .env
# 编辑 .env 并填写 4 个必填变量:
# DEEPSEEK_API_KEY, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID, REDDIT_API_KEY
```
#### 步骤 2 — 安装 Docker(如果尚未安装)
```
sudo apt install -y docker.io docker-compose-v2
```
#### 步骤 3 — 构建并验证
```
sudo docker compose up --build
```
容器启动,执行完整的 pipeline 并结束。如果以 `exited with code 0` 结束且消息到达 Telegram,则部署正确。周末 pipeline 会自动跳过(guard 在 `main.py` 中,不在 cron 中)。
#### 步骤 4 — 配置 cron
每日执行由服务器的外部 cron 控制,而非容器:
```
sudo crontab -e
```
添加(示例为服务器时间 10:30):
```
30 10 * * * cd /opt/auto-reddit && docker compose up >> /var/log/auto-reddit.log 2>&1
```
周末 guard 在代码(`main.py`)中,不在 cron 中,因此条目可以每周 7 天运行:脚本自行决定是否执行。
完整的部署指南位于 [`docs/deployment.md`](docs/deployment.md)。
#### 查看日志
```
# 最后一次执行的日志
cat /var/log/auto-reddit.log
# 或查看最后一个容器的日志
docker compose logs auto-reddit
```
#### 持久化
SQLite 数据库位于一个 Docker 卷(`sqlite_data:/data`)中。数据在容器执行之间持久保存,无需人工干预。通过以下方式验证:
```
docker volume ls
```
## 访问操作部署
本项目不暴露公共 Web 界面。系统在 VPS 上运行,其实际操作输出在 Telegram 中交付,这是团队查阅每次每日执行并审查检测到的机会的渠道。
此外,仓库在 `TFM/presentacion.html` 中包含项目的 HTML 演示。
可以在任何浏览器中直接从该文件在本地打开。
该演示已发布并公开在 GitHub Pages 上,URL 如下:
https://prodelaya.github.io/auto-reddit/TFM/presentacion.html
实际运营频道:
https://t.me/+wp1xd6Rgik9lNWQ0
生产环境中的频道视觉参考:

## 项目结构
```
auto-reddit/
├── assets/
│ └── auto-reddit-logo.png
├── src/
│ └── auto_reddit/
│ ├── __init__.py
│ ├── main.py # orquestador del proceso diario
│ ├── reddit/ # extraccion de candidatos y contexto
│ │ ├── __init__.py
│ │ ├── _constants.py # categorias, idiomas, constantes del modulo
│ │ ├── client.py # cliente HTTP para Reddit API
│ │ └── comments.py # recuperacion de comentarios de hilo
│ ├── evaluation/ # evaluacion IA con DeepSeek
│ │ ├── __init__.py
│ │ └── evaluator.py # logica de evaluacion y resumen
│ ├── delivery/ # entrega por Telegram
│ │ ├── __init__.py
│ │ ├── renderer.py # renderizado de mensajes para Telegram
│ │ ├── selector.py # seleccion y priorizacion de candidatos
│ │ └── telegram.py # envio via Telegram Bot API
│ ├── persistence/ # memoria operativa SQLite
│ │ ├── __init__.py
│ │ └── store.py # CRUD de posts y estado de entrega
│ ├── shared/ # contratos Pydantic compartidos
│ │ ├── __init__.py
│ │ └── contracts.py # modelos Post, Candidate, Opportunity
│ └── config/ # settings con pydantic-settings
│ ├── __init__.py
│ └── settings.py # carga y validacion de variables de entorno
├── tests/
│ ├── __init__.py
│ ├── conftest.py # fixtures compartidos
│ ├── test_main.py # test del orquestador principal
│ ├── test_import_smoke.py # smoke test de imports
│ ├── test_ci_workflow.py # validacion de workflow CI
│ ├── test_infra_hardening.py # hardening de infraestructura
│ ├── test_settings_govern_runtime.py # settings gobiernan el runtime
│ ├── test_reddit/
│ │ ├── __init__.py
│ │ ├── conftest.py # fixtures especificos de Reddit
│ │ ├── test_client.py
│ │ └── test_comments.py
│ ├── test_evaluation/
│ │ ├── __init__.py
│ │ ├── test_contracts.py
│ │ └── test_evaluator.py
│ ├── test_delivery/
│ │ ├── __init__.py
│ │ ├── test_deliver_daily.py
│ │ ├── test_renderer.py
│ │ ├── test_selector.py
│ │ └── test_telegram.py
│ ├── test_persistence/
│ │ ├── __init__.py
│ │ └── test_store.py
│ └── test_integration/
│ ├── __init__.py
│ └── test_operational.py # tests de integracion operacional
├── scripts/
│ ├── README.md
│ └── reddit_api_raw_snapshot.py # snapshot crudo de Reddit API para debugging
├── skills/
│ ├── deepseek-integration/ # skill: integracion con DeepSeek
│ ├── docker-deployment/ # skill: despliegue Docker
│ └── python-conventions/ # skill: convenciones de codigo Python
├── .github/
│ └── workflows/
│ └── ci.yml # pipeline CI: pytest en cada push y PR
├── docs/
│ ├── architecture.md # decisiones arquitectonicas
│ ├── operations.md # guia operativa
│ ├── integrations/
│ │ └── reddit/
│ │ ├── comparison.md # comparativa de APIs evaluadas
│ │ └── api-strategy.md # estrategia vigente de seleccion y fallback
│ ├── product/
│ │ ├── product.md # fuente de verdad del producto
│ │ └── ai-style.md # comportamiento y estilo de la IA
│ └── discovery/ # documentacion historica de ideacion
├── openspec/ # planning SDD por changes
├── TFM/ # documentacion academica del proyecto
├── pyproject.toml
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md
```
## 主要功能
- **`r/Odoo` 中的每日机会检测**:每天系统收集 `r/Odoo` 中可配置窗口(`review_window_days`)内的所有帖子,为内部 pipeline 规范化它们,并最多审查 `daily_review_limit` 个按时效性优先排序的合格候选。每天提供的最大机会数由 `max_daily_opportunities` 控制。
- **按机会类别过滤**:帖子被分类到一个封闭的分类法中:Odoo 的功能和配置、开发、关于 Odoo 是否值得的疑问,以及与其他选项的比较。
- **AI 评估**:DeepSeek 评估每个候选以决定其是否代表有效机会,为内部团队用西班牙语总结上下文,并包含一条供人工审查的西班牙语和一条英语建议回复。
- **每日通过 Telegram 交付**:团队收到一条包含日期、审查帖子数和检测到的机会数的摘要消息,随后是每个机会的消息,包含标题、链接、帖子语言、类型、摘要和建议回复。
- **按需线程上下文**:评论仅针对 selector 为后续流程选定的帖子进行检索;它们不是初始候选收集的一部分。这在 `delivery/selector.py` 和 `reddit/comments.py` 中实现。
- **重复数据控制和幂等性**:每个帖子只记录和发送一次。不存在明确的 backlog 或 `approved` 状态;`rejected` 是最终的业务丢弃,`not selected today` 不是持久状态,如果 Telegram 在 AI 接受后失败,则重试发送而不重新评估。
## 测试和 CI
项目有 **396 个测试通过,4 个跳过**(无凭据的 live smoke tests)。
- **单元测试**:每个模块在 `tests/test_
/` 中都有相应的套件。
- **操作集成测试**:`tests/test_integration/test_operational.py` 覆盖每日流程的端到端流程。
- **Smoke tests**:`tests/test_import_smoke.py` 验证导入,`test_ci_workflow.py` 和 `test_infra_hardening.py` 验证 CI 和基础设施配置。
- **Settings govern runtime**:`tests/test_settings_govern_runtime.py` 验证实际设置(`review_window_days`、`daily_review_limit`、`max_daily_opportunities`)控制运行时行为。
带有 GitHub Actions 的 CI 在每次推送到 `main` 和 PR 时运行 `uv run pytest tests/ -x --tb=short`。标签:AI写作助手, DeepSeek, DLL 劫持, Docker, ERP, GitHub Actions, Odoo, OpenAI SDK, Pydantic, Python, RapidAPI, Reddit营销, SQLite, Telegram机器人, uv, 人工智能, 人机协同, 内容营销, 商机挖掘, 大语言模型, 安全防御评估, 数字营销工具, 无后门, 熵值分析, 用户模式Hook绕过, 社媒聆听, 线索生成, 自动化监控, 自动笔记, 请求拦截