ShrimpReel 是什么?
ShrimpReel 是一个开源 SaaS 模板,用于构建将一张上传的照片转换为基于病毒式传播格式的 AI 生成视频的网站。预期工作流程是:为每个热门关键词创建单独的代码仓库,修改网站配置和双语内容,替换媒体资源,然后将完成的应用部署到 Cloudflare。
该技术栈结合了 TanStack Start、React 19 和 Tailwind CSS 4,用于前端和服务端渲染。Hono API 负责处理 /api/* 下的路由、媒体传输、robots 指令、站点地图和 IndexNow 验证。服务器入口点是 src/server.ts。
该应用围绕 Cloudflare Workers、D1、R2、KV、Queues、Rate Limiting 和 Cron Triggers 设计。英文页面从 / 提供,中文页面位于 /zh 下。
项目状态:根据 README,完整工作流程已通过本地单元测试和 Playwright 端到端测试,但该模板尚未经过生产部署验证。在依赖各项集成连接真实服务之前,请先查看
ROADMAP.md。
主要功能
账户、账单和积分
- 支持 Google 登录,包括 Google One Tap,以及仅限 localhost 的开发登录。
- 积分包,以及可选的月度或年度订阅。
- 积分账本、兑换码、推荐链接、账单历史、可打印的订单详情、账户删除和数据导出。
- 默认支付服务商 Waffo Pancake,或可选用 Dodo Payments。
- 支持部分和全额退款,并自动扣回相应积分。
视频生成
- 默认使用 fal.ai 队列 API 作为视频服务商。
- 支持可选地通过 yir.ai 路由请求。
- 本地开发和测试期间,模拟服务商会复制模板视频。
- 生成队列、死信队列,以及生成失败时自动退还积分。
- 用户可以按视频启用公开视频分享页面。
增长、管理和运营
- 使用 UTM 值和广告点击标识符进行首次触点和末次触点归因。
- 访问到生成的转化漏斗,以及受同意控制的 GA4 事件。
- 提供用户、订单、生成记录、支付事件、下架处理、举报、邮件、审计记录、推荐、运行时设置和连接测试的管理界面。
- 服务商成本和毛利率报告。
- 维护模式、公告、每日生成限制、健康警报、浏览器错误报告和支付通知。
- 每日将 D1 备份到 R2。
安全、数据保留和 SEO
- 上传内容审核,以及视频上的 AI 生成标签。
- 七天后自动删除照片,30 天后自动删除视频。
- 48 小时下架队列:移除由同一源照片制作的视频,并屏蔽该照片。
- 联系表单和举报表单支持 Turnstile。
- 规范 URL、hreflang 元数据、JSON-LD、站点地图、法律页面、指南、相关文章和代码分割的本地化文案。
- 可通过
npm run seo:check使用全站 SEO 检查器。
前置要求
安装 Node.js 和 npm 11.19 或更高版本。较旧的 npm 版本可能会以某种形式重写 package-lock.json,之后导致持续集成中的 npm ci 失败。
要进行生产部署,还需要 Cloudflare 账户、支付服务商账户、视频服务商 API 密钥和 Google OAuth 凭据。只有使用随附脚本重新生成占位媒体时才需要 FFmpeg。
在本地安装并运行 ShrimpReel
1. 安装依赖并创建本地变量
npm install
cp .dev.vars.example .dev.vars打开 .dev.vars,至少设置 SESSION_SECRET。生产环境和预发布环境要求使用至少 32 个字符的强值。README 建议使用以下命令生成:
openssl rand -hex 322. 准备本地数据库和媒体存储
npm run seed:local此命令会应用 D1 迁移,并将 seed/templates/*.mp4 中的文件上传到本地模拟的 R2 存储。
3. 启动开发服务器
npm run dev -- --host 127.0.0.1打开 http://127.0.0.1:3000。在 Windows 上明确使用 127.0.0.1 还可以避免测试工具将 localhost 解析为 IPv6 时出现问题。
不要在
0.0.0.0上运行开发服务器,也不要直接将其暴露到互联网。开发登录、模拟支付和/api/dev/*仅用于直接的 localhost 请求。
尝试基本工作流程
默认本地配置使用 PAYMENT_PROVIDER=mock、VIDEO_PROVIDER=mock 和 MODERATION_PROVIDER=mock。这样可以在不扣款或向外部视频服务提交任务的情况下体验产品。
- 打开登录页面,并使用生产环境之外显示的开发登录方式。
- 选择积分包。模拟结账会模拟支付,但不会产生任何扣款。
- 上传照片并开始生成。
- 模拟视频服务商会复制预置的模板视频,而不是调用 AI 模型。
- 打开控制面板,查看生成的视频、积分账本、账单记录和分享设置。
要模拟上传被拒绝,请在上传表单中提交 mockOutcome=reject。如果希望在本地禁用 Turnstile,请将 TURNSTILE_SITE_KEY 留空。
你还可以测试当前已登录用户媒体的保留清理功能:
POST /api/dev/sweep
Content-Type: application/json
{"days": 8}本地邮件投递为模拟操作。使用以下命令查看发件箱:
GET /api/dev/emails?to=user@example.com&ref=<order-or-takedown-id>为新趋势创建网站
1. 克隆仓库,同时保留上游历史记录
git clone https://github.com/qianshuixia/shrimpreel.git moonhop
cd moonhop
git remote rename origin upstream
git remote add origin git@github.com:<owner>/moonhop.git如果希望合并未来的模板更新,请不要使用 GitHub 的模板按钮。通过这种方式创建的仓库与源仓库没有共享历史记录。使用带有 upstream 远程仓库的普通克隆可以保留合并基点。
2. 运行网站脚手架
先执行试运行,检查拟进行的更改,然后添加 --write:
node scripts/new-site.mjs --keyword "Moon Hop" --domain moonhop.ai --keywords "AI dance video,Moon Hop filter"
node scripts/new-site.mjs --keyword "Moon Hop" --domain moonhop.ai --keywords "AI dance video,Moon Hop filter" --write脚手架会更新 site.ts、wrangler.jsonc 中的 Cloudflare 资源名称以及软件包名称。它会重置部署专用标识符,并移除模板的暂存环境配置。随后,它会输出剩余手动操作的检查清单。
3. 配置定价和生成设置
编辑 src/config/site.ts。检查 packages 中的积分包、subscriptionsEnabled 开关、订阅 plans、可用的 durations 以及 video.falModel。
如果网站只应销售一次性积分包,请将 subscriptionsEnabled 设置为 false。积分包可以使用 anchorPriceCents 显示划线的对比价格,但 README 警告,该价格应当确实是该积分包曾经实际销售时的价格。新网站通常不设置此字段。
4. 重写本地化内容
替换 src/content/en.ts 和 src/content/zh.ts 中与趋势相关的文案。至少要重写主视觉区、说明、创意、常见问题以及两篇内置文章。可选的问题和对比模块也应重写或设置为 null。
避免只在现有文本中机械地替换关键词。模板明确提醒,机械复制的网站可能会被搜索引擎视为规模化内容滥用。
要添加文章,请先在 site.ts 的 articles 部分创建其元数据条目,然后为每种语言环境添加匹配的内容键。文章会自动加入指南中心、网站地图以及已配置的相关文章链接。请保留现有的 trend 和 howTo 条目,因为首页会链接到它们。
5. 替换所有占位媒体
- 将源生成视频片段放入
seed/templates/,并使用<template.id>-<seconds>s.mp4格式。 - 替换
public/demo/中的首页视频和海报图。 - 替换
public/og.png和public/favicon.svg。 - 仅使用原创或获得许可的演示媒体,并将其署名记录在
site.examples.*.credit中。
如果系统提供 FFmpeg,可使用以下命令重新生成项目原有的占位媒体:
node scripts/generate-placeholder-media.mjs更改 template.id 后,请从 seed/templates/ 中删除过时的模板文件。
配置真实服务提供商
运行时变量
在 wrangler.jsonc 中设置非机密的生产环境变量。重要值包括 SITE_URL、APP_ENV=production、PAYMENT_PROVIDER、VIDEO_PROVIDER、MODERATION_PROVIDER、TURNSTILE_SITE_KEY、ADMIN_EMAILS、EMAIL_FROM、产品映射以及 GOOGLE_CLIENT_ID。
支付服务提供商的产品价格具有权威性。网站显示的价格必须与服务提供商控制台保持同步。产品映射会将每个已配置的积分包或计划关联到其服务提供商产品 ID。
密钥
根据所选集成,密钥可能包括 SESSION_SECRET、GOOGLE_CLIENT_SECRET、Waffo 凭据、Dodo 凭据、FAL_KEY、可选的 YIR_API_KEY、用于审核的可选 OPENAI_API_KEY 以及 TURNSTILE_SECRET_KEY。
使用以下命令设置单个密钥:
npx wrangler secret put <NAME>或者,复制并填写生产环境变量文件,检查执行计划,然后应用缺失的密钥:
cp .dev.vars.example .dev.vars.production
node scripts/sync-secrets.mjs
node scripts/sync-secrets.mjs --apply同步脚本不会输出密钥值。除非提供 --overwrite,否则现有的远程密钥会被保留。
配置 Cloudflare 资源
为每个关键词网站创建独立的资源集。名称必须与 wrangler.jsonc 中的绑定一致。
npx wrangler d1 create <name>
npx wrangler r2 bucket create <name>-media
npx wrangler kv namespace create <name>-kv
npx wrangler queues create <name>-jobs
npx wrangler queues create <name>-jobs-dlq
npm run db:migrate:remote
npx wrangler r2 object put <name>-media/templates/<file>.mp4 --file seed/templates/<file>.mp4 --content-type video/mp4 --remote将生成的 D1 数据库 ID 和 KV 命名空间 ID 复制到 wrangler.jsonc 中。每个网站的速率限制 namespace_id 在 Cloudflare 账户内也必须保持唯一。
按照项目中的说明配置 R2 生命周期规则,使上传的照片和生成的视频分别遵循七天和 30 天的保留期限。在事务性电子邮件正常工作之前,还必须先通过 Cloudflare Email Service 完成发送域名的接入。
验证并部署
运行本地质量检查
npm run typecheck
npm test
npm run test:e2e
npm run seo:check部署前,运行配置诊断工具:
npm run doctor该工具会检查环境、域名、所选提供商、产品映射、Cloudflare 资源绑定、队列、Cron 配置、必需的密钥名称、尚未应用的迁移,以及未解决的 TODO(site) 标记。当远程检查暂时不可用时,使用 --offline。
部署并运行冒烟测试
npm run deploy
SMOKE_BASE_URL=https://<domain> npm run test:smokenpm run deploy 会先运行部署前检查。部署后,在 Cloudflare 中绑定自定义域名,并确保 SITE_URL 与 site.domain 完全一致。规范 URL、站点地图以及同源 CSRF 检查都依赖这一匹配关系。
自定义域名正常工作后,将 workers_dev 和 preview_urls 设置为 false。否则,生产 Worker 仍可通过公开的 Cloudflare 开发和版本 URL 访问,并使用相同的 D1 和 R2 资源。
完成 SEO 上线任务
npm run seo:check -- --base https://<domain> --production
npm run seo:indexnow -- --submit仅在配置好 site.seo.indexNowKey 后运行 IndexNow 命令。在 Google Search Console 和 Bing Webmaster Tools 中验证域名,然后提交 https://<domain>/sitemap.xml。
高级技巧
确保生产环境不使用模拟实现
如果所选提供商仍设置为 mock,生产环境和预发布环境会对结账、生成和上传请求返回 503 响应并拒绝处理。开发环境登录、模拟结账路由和开发环境 API 端点在这些环境中会返回 404。请将其视为安全机制,而不是运行 npm run doctor 的替代方案。
合并模板更新,而不是复制补丁
将站点专属的工作保留在 src/config/site.ts、src/content/*、public/*、seed/、wrangler.jsonc 以及 package name 中。共享修复应在模板中完成,然后合并到每个站点。
git fetch upstream
git show upstream/main:scripts/sync-plan.mjs > .tmp/sync-plan.mjs
node .tmp/sync-plan.mjs
git merge --no-ff upstream/main
npm install
npm run typecheck
npm test
npm run test:e2e
npm run db:migrate:remote使用合并提交,不要使用压缩合并、变基或拣选提交。同步计划依赖 git merge-base HEAD upstream/main。记录合并时,将 Template-sync: <template commit sha> 放在提交消息末尾。
在部署期间保持向后兼容
如果迁移运行后部署失败,可以回滚新的 Worker 版本,但 D1 迁移不会自动撤销。请确保迁移与之前的应用版本兼容,以便能够回滚。
适时使用随附的 Claude Code 工作流
仓库包含用于搭建趋势主题站点的 new-hot-site 技能、用于合并模板变更的 sync-upstream 技能,以及用于上线前和线上检查的只读 launch-audit 技能。这些工具不能替代人工审核:生成的文案、获得授权的媒体资源、域名、提供商产品、OAuth 设置、电子邮件接入和生命周期策略仍需核验。
修改核心逻辑前先查阅项目文档
修改积分、支付履约、双语内容、迁移或端到端测试之前,请查阅 AGENTS.md。更多详情请参阅 docs/env.md、docs/payments.md、docs/subscriptions.md、docs/SEO_AUDIT.md 和 docs/SAAS_VIDEO_FEATURES.md。README 说明这些文档目前使用中文编写。
结语
ShrimpReel 为以关键词为重点的 AI 视频 SaaS 提供了全面的起点,涵盖生成队列、计费、积分、管理、保留策略、合规工作流、分析、SEO 和 Cloudflare 运维。请从安全的模拟工作流开始,定制所有站点专属层,将占位内容替换为获得授权的资源,核验所有提供商和 Cloudflare 设置,并仅在完整的测试、诊断、SEO 和冒烟测试流程全部通过后部署。
