Inspiration

We've all doom-scrolled, argued online at 2 AM, or refreshed our feed one more time. Screen time warnings don't work. Friends telling us to touch grass don't work. But what if the person calling you out was literally you—from the year 2050?

We wanted to make digital wellness feel less like a lecture and more like a roast. The idea: your future self travels back through a time portal to roast you for your worst social media habit. It's funny, shareable, and hits different because it's your own face telling you to put the phone down.

What it does

DoomPortal lets users enter their X or Instagram handle, pick one of 12 "social sins" (Doom Scroller, Crypto Degenerate, Meme Lord, 3AM Poster, Selfie Addict, Reply Guy, and more), and generate a personalized AI video where their future self steps through a neon portal to roast them for that habit.

  • Profile pic integration: Fetches profile pictures via unavatar.io and uses them as the base for AI-generated video
  • AI video generation: Magic Hour's image-to-video API creates short, personalized roast videos with audio
  • Loading experience: AI-generated preview images rotate while the video renders (2–4 minutes)
  • Auth & library: Google OAuth via Better Auth; users can save roasts to "My Roasts" and control gallery visibility
  • Shareable links: Each roast gets a short URL for sharing; view counts are tracked
  • Public gallery: A "Wall of Shame" shows trending roasts, with opt-in for authenticated users

How we built it

  • Frontend: Next.js 15 (App Router), React 19, Tailwind CSS, shadcn/ui, and a cyberpunk-style theme
  • Video & images: Magic Hour API (image-to-video with Kling, plus AI image generation for loading previews)
  • Profile pictures: unavatar.io for X/Instagram handles, then upload to Vercel Blob for Magic Hour
  • Database: MongoDB Atlas for remix metadata (handle, sin, video URL, views, user association)
  • Auth: Better Auth with Google OAuth and MongoDB adapter
  • Storage: Vercel Blob for profile images and generated videos
  • Deployment: Vercel (serverless)

To handle long video generation times, we split the flow into a 3-step async pipeline: a kickoff API starts the job and returns a project ID; the client polls for status; and a completion API downloads the video, uploads it to Blob, and saves metadata in MongoDB.

Challenges we ran into

  • Vercel serverless timeout: Magic Hour videos can take several minutes. A single long request would hit the 60s limit. We switched to an async pipeline with client-side polling so the server only does quick start/status/complete steps.

  • Magic Hour 422 "invalid image extension": unavatar.io redirect URLs don’t have image extensions. Magic Hour rejects them. We solved this by downloading the image, re-uploading it to Vercel Blob with a proper filename (e.g. .png or .jpg), and passing that URL to the API.

  • OAuth & session issues: Better Auth with Google caused redirect_uri_mismatch and ERR_TOO_MANY_REDIRECTS. We fixed this by updating Authorized redirect URIs in Google Cloud Console, disabling cookie cache, adding trusted origins, and using getSessionCookie in middleware plus a getServerSession() helper for consistent session handling on Vercel.

  • Client/server boundaries: MongoDB and other server-only modules ended up in the client bundle, causing "Module not found" for net, tls, etc. We moved server logic into server-only modules and kept client imports clean.

Accomplishments that we're proud of

  • A full end-to-end flow: handle → profile pic → AI video → shareable link → gallery
  • Async video generation that avoids timeouts while keeping the experience smooth
  • A loading experience with rotating AI preview images instead of a static spinner
  • Clean separation of concerns and type-safe validation (Zod)
  • A fun, meme-style UI that matches the concept
  • Production-ready setup on Vercel with rate limiting and security headers

What we learned

  • Async design is essential for long-running AI APIs on serverless: kickoff, poll, complete instead of one long request.
  • External APIs often have strict validation (e.g. image URLs with extensions); sometimes you need a small proxy step.
  • Session and cookie handling can behave differently in serverless environments; explicit session helpers help avoid redirect loops.
  • server-only and careful imports are important when mixing MongoDB and client components in Next.js.
  • Good loading UX (dynamic messages, preview images) makes long generation times feel shorter.

What's next for DoomPortal

  • More platforms: Add TikTok, LinkedIn, and other profile sources
  • Custom roasts: Let users write their own roast scripts or pick tone (savage vs. friendly)
  • Remix from template: Choose from preset roast styles and templates
  • Mobile app: React Native or PWA for easier sharing
  • Roast history & insights: Show which sins users get roasted for most and trends over time
  • Faster models: Integrate newer Magic Hour models as they release for quicker, higher-quality output

Built With

  • betterauth
  • googlesignin
  • magichour
  • mongodb
  • next.js
  • vercel
Share this project:

Updates