这个烤肉机,其实是个推特嵌字机。
出现的初衷因该是,嵌字这件事儿,大家都爱不动了。
来回p图一样的东西,有些伤不起啊。
于是,为了解决重复性工作,工坊招了程序员,也终于搞出来了这个项目。
此项目主要感谢以下贡献者
FzXiao b站
飞雪 b站
鱼鱼 b站
- 接受
7216_2nd、@7216_2nd、x.com/7216_2nd等主页输入 - 接受带或不带
https://的x.com/.../status/...、twitter.com/.../status/...单推链接 - 主页模式列出多条近期公开推文,默认预览前三条,可任意勾选
- 单推模式同时列出上下文、目标推文和其他用户回复,可逐条选择、逐条翻译
- 保留旧版翻译组 Logo 和
{T}HTML 模板,并内置、逐份验证 toastTemplates 的 49 个可见模板 - 完整素材库可搜索,只有用户钉住的常用项才进入日常下拉菜单
- 常用模板、最近选择、自定义 Logo、高级 HTML 草稿和命名模板均保存在浏览器本地,刷新后继续使用
- Logo 按素材原始 CSS 像素等比显示,仅在超过 568px 出图内容区时防溢出,不再统一压小
- 预览和下载共用 Chromium 渲染面;导出为 640 CSS px / 1280 实际像素的 2x PNG
- 兼容旧 Bot 的
/api/auto+/api/get_task=<id>异步协议 - 默认使用免费公开的 FxTwitter/FxEmbed API,可切换到自建实例
镜像由 GitHub Actions 发布到 GHCR,不需要在服务器现场构建:
docker run -d \
--name tweettoaster \
--restart unless-stopped \
--shm-size=512m \
-p 127.0.0.1:8082:8082 \
-v tweet-cache:/app/Matsuri_translation/frontend/cache \
ghcr.io/cn-matsuri/tweettoaster:latest仓库内的 Compose 文件同样只拉镜像:
docker compose pull
docker compose up -d
curl http://127.0.0.1:8082/api/health每个同仓库 PR 还会发布 pr-<编号> 测试标签;合并到 master 后发布 latest,版本 tag 会发布同名镜像标签。
镜像清单同时包含 linux/amd64 与 linux/arm64。它可以直接运行在 Linux Docker,以及 macOS/Windows 的 Docker Desktop;这是 Linux 容器,不是 Windows 原生容器。
在 Nginx、Caddy 或 Cloudflare Tunnel 中把域名反代到 127.0.0.1:8082 即可。默认只监听本机,避免绕过反向代理直接暴露端口。
| 变量 | 默认值 | 用途 |
|---|---|---|
PORT |
8082 |
HTTP 端口 |
HOST |
0.0.0.0 |
监听地址 |
CHROMIUM_PATH |
自动发现 | Bot/下载截图使用的 Chromium;镜像内已配置 |
TWEET_PROVIDER_URL |
https://api.fxtwitter.com/2 |
免费推文数据源根地址;也可指向自建 FxEmbed |
TWEET_PROVIDER_TIMEOUT_MS |
15000 |
数据源超时毫秒数 |
TWEET_TIMELINE_COUNT |
12 |
主页最多显示的近期推文数,范围 1–20 |
TWEET_REPLY_COUNT |
20 |
单推最多显示的回复数,范围 0–30 |
TEMPLATE_ALLOWED_HOSTS |
x.wudifeixue.com,raw.githubusercontent.com |
Bot 可下载模板的 HTTPS 域名白名单 |
创建任务:
POST /api/auto
Content-Type: application/json
{
"tweet": "https://x.com/user/status/123",
"translate": "翻译文字",
"template": "https://tweet.wudifeixue.com/template/matsuri.txt",
"noLikes": false,
"logo": "official"
}返回 200 {"task_id":"..."}。轮询 GET /api/get_task=<task_id>;成功时 state 为 SUCCESS,result 是文件名,图片位于 /cache/<result>.png。
旧 Bot 的多条翻译格式继续可用:
##1
第一条翻译
##2
第二条翻译
tweet 现在也可以传主页或用户名。template 可留空、直接传模板 HTML、传 /template/name.txt 本地路径,或传白名单内的 HTTPS 模板地址。远程模板限制为 64 KB,并拒绝内网地址。
经过整理的 toastTemplates 已随程序和预构建镜像发布,无需在服务器再 clone。/template/*.txt、/templates/*.txt、?template=/template/*.txt 和旧模板的多样式注释格式继续兼容。维护者可以在相邻源码目录运行 pnpm templates:sync 重新导入上游目录;生成的 frontend/templates/ 不包含废弃的 25 MB 远程字体。
“管理常用与上传”会打开完整素材库;搜索到需要的字幕组后点“加入常用”,它才会出现在日常下拉菜单。上传 Logo 和保存高级 HTML 模板后也会自动加入常用,并写入浏览器 IndexedDB。
- 自定义 Logo 仅接受 PNG、JPEG、WebP,保留原图尺寸和比例。
- 本地素材没有 50 KB 的产品限制,实际容量由浏览器配额决定;服务器不会建立用户素材库副本。
- 下载 PNG 时,当前 Logo 会临时随出图请求送入同一台 TweetToaster 的 Chromium 进程,任务结束后不保留。为防止单次请求耗尽公共服务内存,临时出图数据上限为 32 MB。
- 如果未来实现账户/服务端同步,服务端持久化 Logo 应另行执行 50 KB 限制;当前版本没有服务端同步。
- 高级模板必须包含
{T}。输入会自动保存草稿,也可以命名保存多份模板;危险标签、事件属性和远程资源会在出图前移除。
需要 Node.js 22+ 和 Chrome/Chromium:
corepack enable
pnpm install
pnpm test
pnpm start打开 http://localhost:8082。真实免费数据源回归测试单独运行:
pnpm test:livePR 会执行单元测试、浏览器下载回归、依赖审计,以及 amd64/arm64 镜像构建。回归测试会用 Chromium 逐一真实渲染全部 51 个模板入口,并检查素材加载、原始尺寸、宽高比和 640px 出图面溢出;另有超过 2 MB 的浏览器本地 Logo 与模板刷新持久化测试。
默认数据来自免费的 FxEmbed/FxTwitter 公开 API,不需要 API Key,不接入任何付费 X API。公共实例可能调整限流或可用性;长期部署可自建 FxEmbed,再修改 TWEET_PROVIDER_URL,TweetToaster 本身无需改代码。
旧版使用方法:打开烤肉机后,输入需要查询的推特永久链接;查询、输入翻译内容,满意后下载图片。模板可以完全自定义,自己写 HTML 即可。
烤肉机模板源码地址:cn-matsuri/toastTemplates


