Files

143 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Daily News Digest
这是一个面向个人服务器的资讯日报项目,第一阶段不接入 AI:n8n 负责定时抓取 RSS,按关键词分类、去重并写入 PostgreSQL;网页读取 PostgreSQL 展示当天和历史记录;邮件发送当天完整日报。
## 当前范围
- AI 与 Agent
- 农业硬件
- 农业方案落地
- 农业服务
- 政策与市场
- 国内与国际资讯
## 数据库初始化
1. 在 PostgreSQL 中创建一个独立数据库和用户,例如 `news_digest` / `news_app`
2. 使用 `db/schema.sql` 建表:
```bash
psql -h 127.0.0.1 -p 15432 -U news_app -d news_digest -f db/schema.sql
```
Windows PowerShell 示例:
```powershell
psql -h 127.0.0.1 -p 15432 -U news_app -d news_digest -f .\db\schema.sql
```
如果 PostgreSQL 不在本机,先建立 SSH 隧道:
```bash
ssh -N -L 15432:127.0.0.1:5432 <ssh-user>@<server-ip>
```
这会把本机 `127.0.0.1:15432` 转发到 SSH 服务器可访问的 `127.0.0.1:5432`。数据库本身不需要暴露公网端口。
## Docker 中访问 SSH 隧道
如果 n8n 或网页容器运行在 Docker 中,容器里的 `127.0.0.1` 指向容器自身,不是宿主机。此时:
- Linux Docker:让隧道监听宿主机地址,并将 `host.docker.internal` 映射到宿主机网关;
- Docker Desktop:通常可直接使用 `host.docker.internal`
- `.env` 中的 `PGHOST` 应填写 `host.docker.internal``PGPORT` 填写隧道本地端口(默认 `15432`)。
本项目不会自动保存或生成 SSH 私钥。建议使用 systemd、Windows 服务或 Docker sidecar 管理 SSH 隧道,并为隧道设置自动重连。
Linux 云服务器上推荐使用 `docker-compose.host-network.yml`SSH 隧道监听宿主机 `127.0.0.1:15432`,网页容器使用宿主机网络,`.env` 中填写 `PGHOST=127.0.0.1``PGPORT=15432`。这样不会把数据库隧道端口暴露到公网。模板见 `deploy/daily-news-db-tunnel.service.example`
网页服务可由 Nginx 代理到宿主机本地端口。使用 `docker-compose.host-network.yml` 时,覆盖配置会让网页只监听 `127.0.0.1:3100`;不要直接把 3100 暴露给公网。
## 配置
复制 `.env.example``.env`,再在服务器上填写实际值。仓库中不提交 `.env`、密码、SMTP 授权码或 SSH 私钥。
## 当前完成度
- 网页日报和历史查询已完成
- 收件邮箱、多模块订阅设置已完成
- PostgreSQL 访问层和 Docker 部署配置已完成
- n8n RSS 抓取、日报生成和 SMTP 发送工作流待接入
网页和邮件会读取同一份 PostgreSQL 数据,因此当天内容与历史记录保持一致。
`news_articles.category` 用于主要栏目;`news_articles.topics` 支持一篇文章同时标记多个主题,例如同时属于 `ai_agent``agri_solutions`。历史搜索由网页服务使用 `ILIKE` 查询标题、摘要和关键词,避免依赖 PostgreSQL 内置的中文分词。
外文翻译是可选的独立步骤,不等同于 AI 内容分析。`news_articles.title``summary` 保留原文;`translated_title``translated_summary` 保存中文翻译。`translation_status` 记录是否翻译成功。翻译服务可以使用阿里云机器翻译、DeepL、Google Cloud Translation,或以后改成本地翻译服务;API 密钥只放在服务器 `.env` 中。
## 用户和邮件订阅
`app_users` 保存网页用户账号;密码只保存 Argon2id/bcrypt 哈希,不保存明文密码。`newsletter_recipients` 保存实际收件邮箱,`recipient_modules` 是邮箱与模块的多对多关系,因此一个邮箱可以选择多个模块。`newsletter_modules` 是可扩展的模块目录。
如果原始 `schema.sql` 已经执行过,请按顺序执行:
```text
db/migrations/002_users_and_subscriptions.sql
db/migrations/003_translation_fields.sql
```
不要为了增加用户功能删除已有表。以后新环境从零创建时,直接执行完整的 `db/schema.sql` 即可。
示例:创建一个收件邮箱并订阅多个模块:
```sql
INSERT INTO newsletter_recipients (email, display_name)
VALUES ('your@example.com', '我的日报')
RETURNING id;
-- 将上一步返回的 id 替换为 1
INSERT INTO recipient_modules (recipient_id, module_key)
VALUES
(1, 'ai_agent'),
(1, 'agri_solutions'),
(1, 'agri_services');
```
## Gitea 部署方式
项目完成后,将整个 `daily-news-digest` 目录作为一个独立仓库推送到 Gitea。服务器只保存运行所需的工作副本,实际配置文件 `.env` 在服务器本地填写,不提交到 Gitea。
推荐的第一阶段流程:
```text
本地修改
提交并推送到 Gitea
服务器 git pull
docker compose up -d --build
```
使用 Linux 主机网络时改为:
```bash
docker compose -f docker-compose.yml -f docker-compose.host-network.yml up -d --build
```
后续如果启用 Gitea Actions 或 Woodpecker CI,可以把最后两步自动化;在当前没有业务代码、需要先稳定运行的阶段,先采用服务器手动拉取更新更容易排错。
服务器首次部署时大致是:
```bash
git clone <你的 Gitea 仓库地址> /opt/daily-news-digest
cd /opt/daily-news-digest
cp .env.example .env
# 只在服务器本地填写 .env
docker compose up -d --build
```
SSH 隧道、PostgreSQL 密码、SMTP 授权码都不放进仓库;Gitea 只管理源码、SQL、工作流模板和部署文件。
## 网页和收件人设置
网页服务默认监听 `3000` 端口。部署前在服务器 `.env` 中填写:
```env
APP_ADMIN_TOKEN=请设置一个随机的长令牌
```
打开 `/settings` 后输入这个令牌,即可添加、编辑和删除收件邮箱,并为每个邮箱选择一个或多个推送模块。令牌只保存在当前浏览器会话中;没有配置令牌时,邮箱管理接口会拒绝请求。
日报页面地址为 `/`,设置页面地址为 `/settings`。网页只读取 PostgreSQL 中的日报和订阅设置,邮件实际发送仍由后续 n8n 工作流完成。