Overview
Watch a YouTube channel for new uploads, pull metadata and auto-captions via Scavio YouTube endpoint, summarize with GPT/Claude, post to a Slack channel on a daily schedule.
Trigger
Daily cron (e.g. 08:00 UTC)
Schedule
Daily cron
Workflow Steps
Query Scavio YouTube endpoint for channel
POST /api/v1/search with platform=youtube and the channel name or topic query.
Filter new videos since last run
Compare publish dates against a last_seen timestamp stored in SQLite or Redis.
Extract transcript for each new video
Use Scavio extract endpoint or YouTube auto-captions field from the search result.
Summarize with LLM
Send transcript to Claude or GPT with a system prompt: '3-bullet summary, key takeaways, any action items.'
Post to Slack via webhook
Format as a Slack Block Kit message with video title, thumbnail URL, and summary bullets.
Update last_seen timestamp
Persist the latest publish date so next run skips already-processed videos.
Python Implementation
import requests, os, json
key = os.environ["SCAVIO_API_KEY"]
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": key},
json={"query": "channel:@3blue1brown", "platform": "youtube", "limit": 5})
videos = resp.json().get("results", [])
for v in videos:
summary = call_llm(v.get("transcript", v["snippet"]))
requests.post(os.environ["SLACK_WEBHOOK"],
json={"text": f"*{v['title']}*\n{summary}\n{v['url']}"})JavaScript Implementation
const resp = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: { "x-api-key": process.env.SCAVIO_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ query: "channel:@3blue1brown", platform: "youtube", limit: 5 })
});
const { results } = await resp.json();
for (const v of results) {
const summary = await callLLM(v.transcript ?? v.snippet);
await fetch(process.env.SLACK_WEBHOOK, {
method: "POST", body: JSON.stringify({ text: `*${v.title}*\n${summary}\n${v.url}` })
});
}Platforms Used
YouTube
Video search with transcripts and metadata