Open-Source Cold Email & Warmup Platform
Warmbly는 메일함을 예열하고 캠페인 전송·답변 triage를 지원하는 오픈소스 콜드 이메일 플랫폼입니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Everything goes live.
FullSend is an autonomous marketing/content engine for applications. Connect a GitHub repository and FullSend builds verified product intelligence, a marketing plan, Instagram content, creative, scheduling, publishing, and analytics.
Major operations are persisted as jobs. Closing the browser does not stop work. Refreshing the application does not restart completed stages. Retries resume the failed operation rather than restarting the whole pipeline.README 전문 보기 ↗Everything goes live.
FullSend is an autonomous marketing/content engine for applications. Connect a GitHub repository and FullSend builds verified product intelligence, a marketing plan, Instagram content, creative, scheduling, publishing, and analytics.
GitHub repository
↓
Product Intelligence (durable)
↓
Marketing Plan (durable)
↓
Instagram Content (durable jobs)
↓
Creative / Media (durable public URLs)
↓
Review / Approval
↓
Schedule
↓
Background Worker
↓
Instagram Publishing
↓
Analytics
↓
Optimization
Major operations are persisted as jobs. Closing the browser does not stop work. Refreshing the application does not restart completed stages. Retries resume the failed operation rather than restarting the whole pipeline.
An HTTP request creates durable jobs and returns. A worker pass runs separately and is bounded three ways, each closing a different route back to a request that outlives its own invocation:
Publishing is durable in the same sense. Instagram publishes in two calls — create a media container, then publish it — and the container id is written down before the publish call, the submission timestamp immediately before it goes out. If the response is lost, the next attempt asks Instagram what actually happened rather than publishing again. A unique index on the receipt is the backstop.
Instagram is the only active production social destination. TikTok exists in the codebase but is gated off by default (FULLSEND_TIKTOK_ENABLED; see OPERATOR_ACTIONS.md). The production content, scheduling, media, and publishing flow is Instagram-focused.
Plans live in src/lib/billing/plans.ts: Free / Send ($29) / Full Send ($79) / Agency ($249).
STRIPE_SECRET_KEY → billing is off; every account gets the full product with no limits.active or trialing subscription. Checkout and the Customer Portal handle cards — FullSend never sees card numbers.FULLSEND_ADMIN_EMAILS (or users.is_admin) get unlimited plan limits while still using the app normally — they are not free-plan capped when Live billing is on. Set [email protected] on Vercel for the creator account./api/billing/webhook keep the subscriptions row in sync. In-app UI: /app/billing.Owner setup (Dashboard + Vercel env) is documented in the Stripe billing pull request checklist.
Requires Node.js 22.x.
npm ci
npm run dev
Useful commands:
npm run typecheck
npm run lint
npm test
npm run build
npm run e2e
npm run worker
Linting is the ESLint CLI against eslint.config.mjs. Next 16 removed next lint, and next build no longer lints.
FullSend uses Next.js/Vercel for the application and Supabase for persistence, authentication, and media storage.
Run the database migrations in supabase/migrations/ in order:
| Migration | What it adds |
|---|---|
0001_fullsend_init.sql | Every table, and the RLS policies that keep tenants apart. |
0002_creative_storage.sql | The public fullsend-creative bucket Instagram fetches media from. |
0003_durable_publishing.sql | The columns that make a publish recoverable, and the unique index that makes publishing the same post twice impossible. |
0004_analysis_commit.sql | The commit an analysis was derived from, so the same commit is never analysed twice. |
0005_project_brand_identity.sql | Each project's own colours, type and marks, so no product is marketed in FullSend's identity. |
0006_generation_state.sql | Whether a post actually finished being made, and the vault column for a Facebook Page token. |
A migration file in the repository is not a migration in the database. GET /api/health checks each one against the live schema — including whether the storage bucket exists and is public — and names the file to run for anything missing.
Required production configuration includes:
NEXT_PUBLIC_APP_URL
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
FULLSEND_ENCRYPTION_KEY
CRON_SECRET
ANTHROPIC_API_KEY or OPENAI_API_KEY
GitHub Actions drives the background queue/heartbeat. The worker claims jobs with a lease, persists results, retries bounded failures, and recovers stale work.
.github/workflows/heartbeat.yml asks for */5 * * * *. GitHub does not honour it. Scheduled workflows are throttled hard on quiet repositories, and in practice this one fires anywhere from 45 minutes to four hours apart.
Nothing in the schedule can fix that, so the run compensates for it: the queue job stays up and sweeps continuously — polling every 15 seconds while there is work and every 60 seconds when idle — until the next firing cancels and replaces it. Coverage comes from runs being long rather than from the schedule being punctual.
On a public repository this is free: Actions minutes are unmetered. On a private repository it is not — a continuous sweep will consume your monthly Actions allowance. There, either shorten the deadline in the workflow or use an external pinger instead.
For a genuinely punctual worker, point any scheduler at the queue endpoint:
POST https://<your-app>/api/cron/queue
Authorization: Bearer <CRON_SECRET>
Every five minutes is a sensible interval; each call is a bounded worker pass and returns as soon as it has done its allowance. Free services that do this include cron-job.org, Cronitor and UptimeRobot. On Vercel Pro you can use native crons in vercel.json instead — disable the Actions workflow if you do, so the jobs are not driven twice.
Whatever drives it, treat anything other than HTTP 200 as a failure — a redirect especially. Vercel answers 308 for any origin that is not the canonical one: http:// rather than https, a www/apex mismatch, a deployment alias pointing at the production domain. Most HTTP clients neither follow a redirect by default nor call it an error, so a wrong URL returns a success with a body of Redirecting... and the queue silently never runs. This is not hypothetical: it stalled this deployment for days, wearing the exact costume of a healthy system. Point the scheduler at the origin the deployment reports as appUrl on /api/health, and alert on the status code rather than on the request failing.
FullSend does not invent product capabilities. Marketing claims must be supported by repository evidence or explicit product information. Failed jobs remain visible with their error and retry state instead of being presented as successful.