极简 Node.js 推特监控 → Telegram 推送工具。基于 bird CLI,纯 Node.js 实现,带 Web 管理面板,网页与后台 worker 同进程运行,开箱即用。核心仅需一个 server.js 加 lib/ 下的几个小模块,使用 JSON 文件管理配置,运行依赖仅 express + bcryptjs。
💡 版本
3.4.2:再经三轮详细审计,补强凭据隔离、认证竞态、异常 bcrypt 哈希、系统时钟回拨、空时间线水位、首次配置回滚、多标签页保存竞态与静态资源缓存更新;现有 87 项自动化回归测试。详见 CHANGELOG。功能面延续 3.2.0:监控台式面板(账号状态卡片 + 顶部指标 + 实时活动流,配置收进设置抽屉)、深浅双主题、bird 路径自动检测;单 Node 进程同时承载面板与后台监控 worker,用 SSE 实时推送状态与日志、用 systemd 常驻,无前端框架、无构建步骤。
⚠️ 从 3.4.1 或更早版本升级,请务必同步更新 systemd 与 Nginx 配置:生成TRUST_PROXY_TOKEN,并加入文档中的EnvironmentFile和 Nginxinclude。若从 3.2.x 升级,还需加入X-Forwarded-For(X-Real-IP不能替代它)。缺少共享令牌时服务端会忽略 XFF/XFP,公网请求将共用回环 IP 限流桶,且 HTTPS 登录无法签发 Secure Cookie(见生产部署)。
- 📡 监控多个 Twitter/X 账号的新推文
- 📲 新推文实时推送到 Telegram(区分原创 / 转推)
- ⚙️ 网页面板与后台 worker 同进程,worker 随服务自动启动,无需 Cron、无需独立守护进程
- 🖥️ 监控台式面板:打开即见每账号状态卡片(状态灯 / 上次检查·推送 / 最近推文 / 推送量走势 / 下次检查倒计时)+ 顶部指标(账号数·今日推送·运行时长·下次检查)+ 实时活动流;配置收进右上角 ⚙ 设置抽屉
- 🌗 深色 / 浅色 / 跟随系统 主题一键切换(记忆选择)
- 🔍 bird CLI 路径自动检测(面板一键查找并填入)
- 🔒 密码保护 + 安全加固(bcrypt、无状态签名会话、CSRF、登录限流、防敏感字段回显、data 目录隔离)
- 🧠 智能去重(ID 集合,首次运行不推送旧推文)
- ♻️ 每账号独立设置拉取条数和检查频率,保存后下一轮自动热加载,无需重启
- 🔁 瞬时网络失败自动重试(最多 3 次、间隔 2 秒);Telegram 429 会立即进入全局退避并按
retry_after顺延推送 - ✂️ 超长推文自动截断(>4000 字符),避免 Telegram API 报错
- 📋 Web 端实时查看运行日志(SSE 推送,内存环形缓冲 500 条,同时打到 journald)
- 🚀 纯 Node,无前端框架、无构建步骤
Tweet-Watcher 面向以下场景:
- 想以极低依赖部署一个 Twitter/X → Telegram 监控工具
- 希望直接在服务器上用 Node.js + bird CLI 跑通,不引入复杂框架
- 需要一个简单可视化的 Web 面板管理 Cookie、Bot Token、监控账号和监控开关
- 接受当前项目以单机部署、轻量运维为主,而不是大规模分布式设计
如果你想要的是一个超轻量、可直接用 systemd 常驻 + Nginx 反代的监控工具,这个仓库就是为这种用途准备的。
├── server.js # 单 Node 进程:Web 面板 + 后台监控 worker
├── package.json # 依赖与启动脚本
├── lib/
│ ├── config.js # config.json / secrets.json 读写与字段校验
│ ├── auth.js # bcrypt 密码、HMAC 签名会话、CSRF 令牌
│ ├── state.js # 运行时状态 + 日志环形缓冲 + 事件总线(SSE 源)
│ ├── store.js # 原子 JSON 读写(临时文件 + rename)
│ ├── bird.js # 调用 bird CLI 拉取推文并解析
│ ├── telegram.js # 消息格式化 + Telegram Bot API 发送
│ └── worker.js # 调度:按账号间隔拉取、去重、重试推送
├── public/ # 纯静态前端(无构建、无框架)
│ ├── index.html # 面板页面
│ ├── app.js # 前端逻辑
│ └── style.css # 样式
├── test/ # Node 内置测试运行器的回归测试
├── SECURITY.md # 私密漏洞报告说明
├── README.md # 项目说明
├── LICENSE # 开源许可证
└── data/ # 运行时数据(自动创建,位于静态 Web 根 public/ 之外)
├── config.json # 普通配置(账号、tg_chat_id、bird_path、paused)
├── secrets.json # 敏感凭据(auth_token / ct0 / tg_bot_token,明文)
├── password.json # 访问密码(bcrypt 哈希)
├── session_secret.json # 会话 HMAC 密钥 + epoch
└── sent_ids.json # 已推送推文 ID(去重用)
| 依赖 | 说明 |
|---|---|
| Node.js ≥ 22 | 运行环境(实测 v24.18.0,与固定的 bird 0.8.0 要求一致);使用内置 fetch、execFile 等,无需额外扩展 |
| npm 依赖 | 仅 express + bcryptjs,建议用 npm ci 按锁文件安装 |
| bird CLI | npm install -g @steipete/bird@0.8.0,用于拉取推文(当前已验证版本) |
| Telegram Bot | Bot Token + Chat ID |
| Twitter Cookie | auth_token + ct0 |
💡 无需 PHP,也不依赖
pcntl/posix/proc_open之类的能力。监控 worker 在 Node 进程内直接作为定时循环运行,不 fork 独立守护进程。
⚠️ bird CLI 是外部命令,由 Node 通过execFile调用(带 30 秒超时)。请确保运行服务的用户对bird_path指向的可执行文件有执行权限。
npm install -g @steipete/bird@0.8.0验证安装:
bird --version
# 查看安装路径(也可在面板设置里点「🔍 自动检测」自动填入)
which bird💡 面板设置页的 bird CLI 路径支持 🔍 自动检测:会在常见位置(与运行 node 同目录、
which bird、/usr/local/bin、/usr/bin)自动找到 bird 并填入,无需手动which;找不到时会提示安装或手动填写。默认路径为/www/server/nodejs/v24.18.0/bin/bird。
git clone https://github.com/xxvcc/Tweet-Watcher.git
cd Tweet-Watcher
npm cinode server.js
# 或
npm start默认监听 127.0.0.1:8787,可用环境变量覆盖:
HOST=0.0.0.0 PORT=9000 node server.js服务启动后,网页面板与后台监控 worker 会在同一个进程内一起运行,日志同时打到终端(stdout)。
先从启动终端日志取得一次性 setup_token;systemd 部署可执行 journalctl -u tweet-watcher -n 20 查看。浏览器访问面板地址(本机为 http://127.0.0.1:8787),输入该令牌并设置访问密码(至少 8 个字符、最多 72 个 UTF-8 字节)。
登录后进入监控台(默认视图):账号状态卡片、顶部指标、右侧实时活动流一目了然。点右上角 ⚙ 设置 打开配置抽屉,填写:
- 监控账号列表:每个账号可单独设置拉取条数和检查频率
- Twitter 认证:
auth_token和ct0(已保存时显示一行圆点,留空即保持不变;点 👁 可明文核对) - Telegram 推送:Bot Token 和 Chat ID
- bird CLI 路径:可点 🔍 自动检测 自动填入
- 点击 💾 保存配置(几秒内热加载生效,无需重启)
- 点击各个 🧪 测试 按钮验证连接是否正常
右上角 🌙 可在 深色 / 浅色 / 跟随系统 间切换主题;⏸ 暂停 / ▶ 恢复 可随时停/启监控。
保存后 worker 会在下一轮 tick(几秒内)自动读取新配置,无需重启。
systemd 常驻 —— 先创建独立、不可登录的服务用户和数据目录。不要复用 Nginx/PHP 的 www 用户;独立 UID 同时隔离运行时数据、子进程环境与会话凭据。
useradd --system --home-dir /nonexistent --shell /usr/sbin/nologin tweet-watcher
chown -R root:root /www/tweet-watcher
chmod 0755 /www/tweet-watcher
install -d -o tweet-watcher -g tweet-watcher -m 0700 /www/tweet-watcher/data
chown -R tweet-watcher:tweet-watcher /www/tweet-watcher/data
find /www/tweet-watcher/data -type f -exec chmod 0600 {} +再生成一份只允许 root 读取的反代共享令牌;Nginx 用它认证转发头,Node 服务通过 systemd 环境文件读取同一个值:
install -d -o root -g root -m 0700 /etc/tweet-watcher
PROXY_TOKEN="$(openssl rand -hex 32)"
printf 'TRUST_PROXY_TOKEN=%s\n' "$PROXY_TOKEN" > /etc/tweet-watcher/proxy-token.env
printf 'proxy_set_header X-Tweet-Watcher-Proxy-Token "%s";\n' "$PROXY_TOKEN" > /etc/tweet-watcher/proxy-token-nginx.conf
chmod 0600 /etc/tweet-watcher/proxy-token.env /etc/tweet-watcher/proxy-token-nginx.conf
unset PROXY_TOKEN代码保持 root:root 只读,只有 data/(包括升级时已有的配置文件)归服务用户所有并允许写入。然后新建 /etc/systemd/system/tweet-watcher.service:
[Unit]
Description=Tweet Watcher
After=network.target
StartLimitIntervalSec=300
StartLimitBurst=10
[Service]
Type=simple
User=tweet-watcher
Group=tweet-watcher
WorkingDirectory=/www/tweet-watcher
ExecStart=/usr/bin/node server.js
Environment=HOST=127.0.0.1
Environment=PORT=8787
EnvironmentFile=/etc/tweet-watcher/proxy-token.env
UMask=0077
Restart=on-failure
RestartSec=3
# 基础沙箱:仅 data/ 可写;网络仍保留给 Twitter 与 Telegram
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/www/tweet-watcher/data
ProtectProc=invisible
ProcSubset=pid
RestrictSUIDSGID=true
LockPersonality=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
[Install]
WantedBy=multi-user.target启用并查看日志:
systemctl daemon-reload
systemctl enable --now tweet-watcher
journalctl -u tweet-watcher -f升级旧部署时先用 systemctl list-unit-files | grep tweet-watcher 核对只启用了一个服务单元;两个单元同时启动同一目录会争用 8787 端口并触发 EADDRINUSE。上面的启动频率限制会在持续失败时停止重试,修复原因后执行 systemctl reset-failed tweet-watcher 再启动。
Nginx 反代 + HTTPS —— 面板只监听回环,由 Nginx 对外提供 HTTPS:
server {
listen 443 ssl;
server_name 你的域名;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8787;
proxy_set_header Host $host;
# $proxy_add_x_forwarded_for 把 Nginx 看到的真实连接 IP 追加为最右项;
# 服务端只在下面的私密令牌验证成功后使用该项。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
include /etc/tweet-watcher/proxy-token-nginx.conf;
# SSE 实时日志:关闭缓冲,保持长连接
proxy_buffering off;
proxy_read_timeout 3600s;
}
}
⚠️ 令牌文件、X-Forwarded-For和X-Forwarded-Proto缺一不可。 未经私密令牌认证的转发头会被忽略,防止同机进程直连8787后轮换伪造 IP 绕过登录限流。直接访问 Node、不使用反代时可以不设置TRUST_PROXY_TOKEN,此时只采用真实 socket 地址且不会信任任何转发头。
⚠️ 面板端口只监听回环,请务必只从本机 Nginx 反代,不要直接对公网开放。
💡 无需
.htaccess:仓库内的data/与public/并列,Node 只静态伺服public/,因此运行时数据不经 Web 暴露。
Twitter、Telegram 与监控配置均通过 Web 页面管理。生产反代另有一份只含 TRUST_PROXY_TOKEN 的 root-only systemd 环境文件;业务数据持久化到 data/ 目录下的几个 JSON 文件:
| 文件 | 内容 |
|---|---|
config.json |
账号列表、tg_chat_id、bird_path、paused(暂停开关)及内部配置版本 |
secrets.json |
auth_token、ct0、tg_bot_token(明文存储,目录权限保护) |
password.json |
访问密码的 bcrypt 哈希 |
session_secret.json |
会话 HMAC 密钥与 epoch |
sent_ids.json |
每账号已推送 ID(去重表) |
首次运行无需任何配置文件即可启动,config.js 内置默认值(当然需要在 Web 页面填写 Token 才能正常工作)。
| 配置项 | 说明 | 默认值 |
|---|---|---|
bird_path |
bird CLI 可执行文件路径 | /www/server/nodejs/v24.18.0/bin/bird |
auth_token |
Twitter Cookie 认证令牌 | - |
ct0 |
Twitter Cookie CSRF Token | - |
tg_bot_token |
Telegram Bot Token | - |
tg_chat_id |
Telegram Chat ID | - |
accounts |
监控的 Twitter 账号列表(对象数组) | [] |
每个账号对象支持以下字段:
| 字段 | 说明 | 默认值 |
|---|---|---|
username |
Twitter 用户名(不含 @,需匹配 ^[A-Za-z0-9_]{1,15}$) |
(必填) |
fetch_count |
每次拉取推文条数(1–50) | 10 |
check_interval |
检查频率(秒,30–3600) | 300 |
💡 修改任何配置后点击「保存配置」即可生效,worker 会在下一轮 tick(每 5 秒一轮)自动读取新值,无需重启。已保存的密文字段(
auth_token/ct0/tg_bot_token)在页面上不回显,留空即保持不变。
- 浏览器登录 x.com
- 按
F12打开开发者工具 - 切换到 Application(应用程序)标签页
- 左侧找到 Cookies →
https://x.com - 复制
auth_token和ct0的值
⚠️ Cookie 会过期。如果推送停止工作,请重新获取 Cookie 并在 Web 页面更新。
- 在 Telegram 搜索 @BotFather
- 发送
/newbot,按提示创建 - 获得格式如
123456789:ABCdefGHIjklMNOpqrsTUVwxyz的 Token
- 在 Telegram 搜索 @userinfobot
- 发送任意消息,获得你的 Chat ID
💡 推送到群组:把 Bot 拉入群组,使用群组 Chat ID(以
-开头)。
- 首次访问 Web 页面时需设置密码(至少 8 位)
- 密码以 bcrypt(cost 12)哈希存储在
data/password.json;兼容旧$2y$前缀(自动改写为$2b$)。新密码要求至少 8 个字符且不超过 72 个 UTF-8 字节(bcrypt 的有效输入上限);旧版生成的未标记哈希保持登录兼容,并在安全边界内自动升级元数据。结构非法或工作因子异常高的持久哈希会快速 fail-closed,避免登录请求陷入指数级 CPU 消耗 - 密码使用异步 bcrypt(不阻塞事件循环),错误时固定延迟 1 秒响应(防暴力破解)
- 登录限流(按经过私密代理令牌认证的
X-Forwarded-For末项分桶;未经认证的转发头一律忽略):累计失败 5 次锁 5 分钟、10 次锁 30 分钟、20 次锁 60 分钟。锁定期满只放行下一次尝试而不清零计数,因此升级档位真正可达;计数在登录成功或1 小时无新失败时清除。限流表有界(惰性回收 + 硬上限,防内存耗尽) - 首次设置令牌:无密码时服务端启动会先吊销全部旧会话,再在日志打印一次性
setup_token;/api/setup必须携带它才能设密,杜绝公网面板的无认证首次抢注(TOFU)。若password.json损坏(包括合法 JSON 但结构非法),hasPassword判定为 fail-closed(视为已设置),不会重开无认证设置 - 会话:HMAC-SHA256 签名的无状态 Cookie(有效期 7 天),内含 epoch —— 登出或改密会
bumpepoch,使所有已签发会话立即失效;签发时间会严格校验并只容忍 5 分钟时钟偏差,畸形 Cookie/会话一律返回 401(不再有 500 堆栈泄露) - CSRF 双提交令牌:所有改动型接口校验,
timingSafeEqual常量时间比较;/api/logout仅在持有效会话+CSRF 时才全局吊销,未认证请求无法借此制造登出 DoS - 安全响应头:CSP(脚本与样式均严格同源,无
unsafe-inline;含form-action 'none')、X-Content-Type-Options: nosniff、X-Frame-Options: DENY、Referrer-Policy,并关闭X-Powered-By;所有/api/*响应带Cache-Control: no-store - 凭据(
auth_token/ct0/tg_bot_token)在日志输出中自动 redact,替换为*** data/目录权限0700、文件写入0600,并位于静态 Web 根public/之外(Node 只对public/使用express.static)- 文件写入使用原子替换(临时文件 +
fsync+rename+ 目录fsync),防止崩溃/断电导致半写损坏;读取时区分「文件不存在」与「存在但损坏」,损坏不静默当作「未设置」 - 损坏或结构非法的
config.json/secrets.json会 fail-closed;已有敏感配置、或当前 worker 已加载过有效配置时,意外缺失的config.json也不会被当成首次空配置(包括运行中data/挂载消失)。单独迁移sent_ids.json仍受支持,配置落盘前 worker 会保留其中的去重记录。系统不会覆盖损坏文件,worker 会停止并报为不健康,Web 进程保持在线。请从 journald 查看错误并从备份恢复,不要直接删除敏感配置后带空值继续运行 bird_path只接受绝对路径、限定字符集、无..、且文件名必须为bird——防止已认证用户将其改指向/bin/sh等宿主二进制。注意该校验拦不住一个名为bird的符号链接指向别处(利用它需要已认证 + 对宿主有写权限)- 子进程调用 bird 带 30 秒超时保护,防止挂起;Twitter Cookie 通过 bird 0.8.0 支持的
AUTH_TOKEN/CT0环境变量传递,不进入可被其他本机用户读取的进程命令行,并且子进程只继承运行所需的最小环境变量集合 - 忘记密码时,需停服 → 删除
password.json→ 重启,重启后从服务端日志读取新的一次性setup_token再走首次设置:
systemctl stop tweet-watcher
rm /www/tweet-watcher/data/password.json
systemctl start tweet-watcher
journalctl -u tweet-watcher -n 20 | grep 首次设置令牌 # 取出 setup_token重启后下次访问面板会回到「首次设置密码」流程,需在页面填入日志中的令牌。
原创推文:
🐦 新推文 @elonmusk
发布时间:2026/2/26 10:00:00
X链接:https://x.com/elonmusk/status/1234567890
内容:
推文内容在这里...
转推:
🔁 转推 @elonmusk
发布时间:2026/2/26 10:05:00
X链接:https://x.com/elonmusk/status/1234567890
内容:
转推内容在这里...
💡 时间由推文原始时间戳解析后转为北京时间(
Asia/Shanghai),以zh-CN、24 小时制显示;无法解析时原样保留。整条消息超过 4000 字符会自动截断并追加「…(内容已截断)」。
| 策略 | 说明 |
|---|---|
| ID 集合 | 每个账号维护已推送的推文 ID 列表,持久化到 sent_ids.json |
| 首次静默 | 账号首次运行只记录当前推文 ID,不推送旧推文;若首次时间线为空,则持久化当前 Twitter Snowflake 时间水位,确保之后发布的第一条推文不会再次被当成基线漏掉 |
| 集合上限 | 每个账号最多保留 200 条 ID |
| 置顶推保护 | 淘汰时优先保留"仍出现在本次拉取窗口内"的 ID —— 否则长期置顶的推文会被挤出去重表并每满 200 条重推一次 |
| 历史推文保护 | 未知但小于或等于已知最高雪花 ID 的条目视为置顶/扩窗带回的旧推文,不补发;真正的新推文按 ID 从旧到新发送 |
| 孤立清理 | 从配置中删除账号后,worker 自动清理其去重记录、计时与状态 |
| 转推识别 | 兼容显式转推字段,并识别 bird 0.8.0 精简输出中的标准 RT @账号: 前缀;转推标记为 🔁,原创推文标记为 🐦 |
| 按账号落盘 | 每个账号一轮检查推送完毕后统一写盘 sent_ids.json(而非每条一次),降低写放大;语义仍是 at-least-once —— 崩溃至多导致"已发未记",下轮重发 |
| 损坏即重建 | sent_ids.json 整体损坏或某账号的值不是数组时,按"首次运行"处理(重建基线、不推送),而不是把整条时间线当新推文全量推出 |
瞬时网络失败最多重试 3 次,重试间隔为 2 秒。任何 Telegram 429 都会立即建立 bot 级全局退避窗口(最长 1 小时),本轮不再占用 worker 槽位等待,并按 retry_after 把当前及后续推文顺延。永久性 4xx 不重试;全部失败时记录日志、保留该 ID 未推状态,下轮仍可再试。旧推文失败时不会越过它发送更新推文。
Web 页面: 监控台右侧的「实时活动」列即为日志流。日志通过 SSE(/api/stream)从服务端实时推送到面板,来源是内存里的环形缓冲(最多保留 500 条)。
命令行 / 服务器: 日志同时写到进程 stdout,交给 systemd/journald 留存与轮转:
# 查看最近日志
journalctl -u tweet-watcher -n 50
# 实时跟踪
journalctl -u tweet-watcher -f💡 本项目不再写
data/cron.log文件,也没有 2MB 上限那套自建日志轮转 —— 落盘与轮转交给 journald 处理。
面板本身走 SSE,不调用下面两个接口;它们是留给健康检查与日志抓取的(均需携带有效会话 Cookie):
| 接口 | 用途 |
|---|---|
GET /api/status |
运行状态 + 每账号指标;healthy 表示 worker 在 60 秒内有过心跳(长 tick 期间也会持续更新,不会误判) |
GET /api/logs |
取最近 200 条日志(JSON 数组) |
迁移到新服务器:
- 拷贝整个项目目录(含
server.js、lib/、public/、package.json) - 新服务器安装 Node.js ≥ 22 与已验证的 bird CLI:
npm install -g @steipete/bird@0.8.0 npm ci --omit=dev按锁文件安装运行依赖- (可选)拷贝
data/目录以保留配置、凭据、密码与去重记录;若只想保留去重记录,单独拷贝data/sent_ids.json - 配好 systemd / Nginx 后启动服务,访问面板确认状态
💡 拷贝
data/后请确认目录权限仍为0700、文件为0600,且属主是运行服务的用户。
- 查看日志:面板「实时日志」或
journalctl -u tweet-watcher -n 50 - 检查面板「监控状态」是否为运行中、是否被「暂停监控」
- 检查 Twitter Cookie 是否过期:
AUTH_TOKEN=YOUR_TOKEN CT0=YOUR_CT0 bird user-tweets elonmusk --json -n 1 --no-color
- 重新获取 Cookie,在 Web 页面更新即可(下一轮 tick 自动生效)
- 确认服务在运行:
systemctl status tweet-watcher - 确认监听地址端口:默认
127.0.0.1:8787,可用HOST/PORT环境变量覆盖 - 若通过公网访问,确认 Nginx 已正确反代到
127.0.0.1:8787并配好 HTTPS
多半是 bird CLI 路径不对、Cookie 失效或未填。可在服务器终端手动排查:
# 检查安装与路径
bird --version
which bird
# 手动测试拉取(与服务端调用一致)
AUTH_TOKEN=YOUR_TOKEN CT0=YOUR_CT0 bird user-tweets elonmusk --json -n 1 --no-color
⚠️ bird_path会经过格式校验:必须是绝对路径、限定字符集、不含..,且文件名必须为bird(防止改指向其它宿主二进制)。请填写 bird 可执行文件的真实绝对路径,如which bird的输出。
监控 worker 在 node server.js 进程内随服务自动启动,只要保证这个进程一直活着即可。除了 systemd,也可以用 pm2、supervisor 等进程管理器守护。注意本项目没有 start / stop 守护进程子命令,也没有 Cron 单次运行模式 —— 面板上的「暂停 / 恢复监控」控制的是同一个进程里的监控开关,而不是进程本身的启停。
- 创建 Telegram 群组,把 Bot 和所有人拉进去,使用群组 Chat ID(以
-开头) - 或复制项目到另一个目录、用不同的
PORT再跑一份,配置不同的 Chat ID
不需要。保存配置后 worker 会在下一轮 tick(每 5 秒一轮)读取最新的 config.json,账号增删、频率与条数调整都会自动生效。
欢迎提交 Issue、Pull Request 或部署经验反馈。请只依据代码中真实存在的能力提交问题与改进,附上脱敏后的日志(凭据在服务端日志中已自动 redact)与环境信息(Node 版本、bird 版本、部署方式)。
如果你在使用中遇到问题,建议按以下顺序排查:
- 阅读本 README 对应章节
- 查看面板「实时日志」或
journalctl -u tweet-watcher -f - 检查 bird CLI、Twitter Cookie 和 Telegram 配置(用面板的 🧪 测试按钮)
- 提交 Issue,并附上脱敏后的日志与环境信息
本项目基于 MIT License 开源,详见 LICENSE。
推特数据拉取由 bird CLI 提供支持。