Scheduled Automation

Scheduled YouTube-to-Email Content Digest

A Trigger.dev scheduled task that polls a YouTube channel every 8 hours, pulls transcripts, has Claude extract highlights as structured JSON, and emails a clean HTML digest via Resend — no database required.

What This Builds

This recipe builds a background content-monitoring worker. Every 8 hours a Trigger.dev scheduled task checks a target YouTube channel for new uploads, fetches each video’s transcript, asks Claude to extract a one-liner plus key highlights as structured JSON, formats everything into one HTML digest, and emails it through Resend. If nothing new was published, it exits silently. The same schedule-fetch-summarize-deliver shape extends to RSS feeds, newsletters, and podcast transcripts.

The Stack

  • Trigger.dev runs the durable scheduled task (cron: "0 */8 * * *"), with retries, logging, and a 5-minute maxDuration. The free tier covers this.
  • YouTube Data API v3 search.list with publishedAfter returns only videos from the last window. At 100 units/call and a 10,000-unit/day free quota, one channel costs ~300 units/day.
  • Anthropic | Claude (Sonnet, not Opus, for this task) extracts highlights and returns JSON; cap transcript input around 6,000 characters.
  • Resend delivers the HTML digest; the free tier covers 100 emails/day.
  • Upstash | Redis (optional) stores past digest themes so Claude can flag trends across runs.

Step-by-Step Outline

  1. Scaffold a Trigger.dev project: npm i -g @trigger.dev/cli@latest then npx trigger.dev@latest init (blank template).
  2. Install @anthropic-ai/sdk googleapis resend youtube-transcript.
  3. Set ANTHROPIC_API_KEY, YOUTUBE_API_KEY, RESEND_API_KEY, DIGEST_RECIPIENT, and YOUTUBE_CHANNEL_ID (channel IDs start with UC) in the Trigger.dev dashboard.
  4. Write getRecentVideos() using search.list with publishedAfter set to 8 hours ago — the time window is the state, so no seen-IDs store is needed.
  5. Write getTranscript() with a try/catch fallback to the video description when captions are missing.
  6. Write extractHighlights() to send title + transcript to Claude and parse the JSON response (fall back to the description on parse failure).
  7. Define the schedules.task with the 8-hour cron, loop videos, build the HTML in formatDigest(), and send via Resend. Deploy with npx trigger.dev@latest deploy.

Why This Shape Works

Using publishedAfter = now - 8h as the dedup mechanism removes the need for any persistent store — the window is the state. The try/catch around transcript fetching and JSON parsing keeps the worker resilient when captions lag an upload or Claude wraps its JSON in prose. Sonnet is the right altitude: summarization does not need Opus-level reasoning, so cost stays under ~$1/month for a personal digest.

Source

MindStudio, “How to Build an AI News Digest Agent with Claude Code and Trigger.dev”: https://www.mindstudio.ai/blog/ai-news-digest-agent-claude-code-trigger-dev