Cosine Gallery Bot

Cosine Gallery Bot

Telegram 艺术作品聚合机器人,多平台抓取 + Rust 原生图片压缩 + 智能去重

Node.js
TypeScript
Grammy
PostgreSQL
AWS S3
September 1, 2025

项目简介

基于 Grammy 框架开发的 Telegram 机器人,用于自动抓取、处理并发布来自 Pixiv 和 Twitter 的艺术作品至 Telegram 频道,服务于 @CosineGallery 社区。该项目为 NahidaBot 的重构版本,采用现代化技术栈实现了更高的性能和可维护性。

项目周期:2024.05 - 2025.09(持续维护中,累计 60+ 次提交)

核心技术栈

后端开发

  • 运行环境:Node.js + TypeScript (严格类型检查)
  • Bot 框架:Grammy (Telegram Bot API 封装)
  • 数据库:PostgreSQL + Prisma ORM (从 SQLite 迁移)
  • 图片处理:@napi-rs/image (Rust 原生绑定,高性能压缩)
  • 云存储:AWS S3 SDK (图片备份与归档)
  • 进程管理:PM2 (守护进程 + 自动重启)

开发工具

  • 测试框架:Jest + ts-jest
  • 代码规范:ESLint + Prettier
  • 日志系统:Pino (高性能结构化日志)
  • 版本管理:Git + git-cliff (自动生成 CHANGELOG)

项目亮点

1. 多平台内容聚合与去重

  • 智能去重机制:基于作品 ID 的数据库去重,防止重复发布
  • 多源支持:同时支持 Pixiv 和 Twitter/X 平台,自动识别 URL 类型
  • API 策略:Pixiv 使用 AJAX API + Cookie 认证,Twitter 集成 FxTwitter API

2. 高性能图片处理流程

  • 双文件策略:原图保存至本地/S3,自动生成压缩版本(<10MB)
  • Rust 原生压缩:使用 @napi-rs/image 实现接近无损压缩,平均压缩率 60-70%,速度提升 3-5 倍
  • 批量下载:Promise.all 并发下载,支持单帖多图同时处理

3. 复杂的批量发布逻辑

实现了灵活的参数化批量发布系统:

  • 参数格式/post URL [batch_page_batchSize] [#tag1] [#tag2]
  • 典型场景
    • 1_0_6 → 发送第 1 批的所有图片(每批 6 张)
    • 0_1_6 → 发送所有批次中的第 1 张图片
    • 2_3_10 → 发送第 2 批的第 3 张图片(每批 10 张)
  • 智能分组:自动处理 Telegram 的 10 张/组限制

4. 数据库架构升级(SQLite → PostgreSQL)

  • 平滑迁移:编写数据迁移脚本,保证历史数据完整性
  • 序列重置:解决 PostgreSQL 自增 ID 序列同步问题
  • 性能优化:多对多关系建模(图片-标签),支持高效的标签搜索

5. 智能标签处理系统

  • Pixiv 标签优化:中英混合场景下优先保留中文原标签
  • 纯日文标签自动翻译:自动翻译为英文
  • 过滤特殊字符:确保 Telegram 标签可点击
  • 标签去重:使用 es-toolkituniq 函数合并标签

6. 自动化运维与监控

  • 远程管理命令
    • /update → 自动 git pull + PM2 重启
    • /restart → 服务热重启
    • /s3upload → 批量上传图片到 S3
    • /compress → 压缩下载目录中的图片
  • S3 集成:定期备份数据库和图片,支持按日期归档
  • 进程守护:PM2 管理 + 优雅关闭

7. 用户交互优化

  • 实时预览/echo 命令预览图片信息和格式
  • 投稿系统:支持 /submit 命令或 #投稿 话题触发
  • 随机图片/random 命令从数据库随机返回作品,附带”换一换”按钮
  • 评论区自动回复:检测频道消息自动转发到评论群组

8. NSFW 内容检测

  • Twitter 敏感内容:集成自定义 NSFW 检测逻辑
  • Pixiv 分级:解析 xRestrict 字段识别 R-18 作品
  • AI 作品识别:基于 aiType 字段自动标注 AI 生成图片

技术难点与解决方案

1. Telegram API 限制处理

问题:Telegram mediaGroup 每组最多 10 张图片,文件 >10MB 必须使用 Document

解决方案

  • 实现 chunkMedias 工具函数,自动按 batchSize 分组
  • 动态判断文件大小,智能切换 sendPhoto / sendDocument API
  • 压缩策略确保大部分图片 <10MB

问题:Pixiv 需要登录态 Cookie 才能访问高清图

解决方案

  • 使用 tough-cookie 库持久化 Cookie 状态
  • Axios 实例配置自动携带 Cookie,支持 Referer 伪造

3. 频道评论区自动回复的异步协调

问题:频道消息发送后,评论群组的转发消息事件是异步的

解决方案

  • 使用全局对象建立 channel_message_id → media_group 映射
  • 监听 message:forward_origin:channel 事件
  • 发送后清空映射,避免内存泄漏

项目成果

  1. 性能提升:相比旧版 NahidaBot,图片处理速度提升 3-5 倍
  2. 代码质量:TypeScript 严格模式 + ESLint,类型安全覆盖率 100%
  3. 可扩展性:模块化架构,新增平台仅需实现 Artwork Fetcher 接口
  4. 用户体验:支持预览、投稿、随机图片等丰富交互
  5. 运维效率:远程管理命令 + S3 备份,减少 90% 手动运维工作