Resumen
Rastrea un establecer of YouTube playlists you care about (course contenido, industria talks, competidor canales) y alertas cuando videos obtener removed o hecho private. Esencial for educators preserving enlace equity y investigadores seguimiento platform-moderation eventos.
Desencadenador
Cron programar (cada 6 horas)
Programación
Every 6 horas
Pasos del flujo de trabajo
Cargar tracked playlists
Leer playlist IDs de un archivo de configuracion (typically 5 to 100 playlists).
Scavio YouTube playlist obtener
Pull actual video lista via Scavio YouTube plataforma con playlist parametro.
Diff vs snapshot
Comparar to el last almacenado snapshot y identificar removed video IDs.
Resolve removed videos
Try fetching cada removed video to distinguish deleted vs private vs geo-blocked.
Log takedown eventos
Persist to Postgres con playlist ID, video ID, removal reason, marca de tiempo.
Slack alerta on takedown
Publicar un notificacion con video titulo (de snapshot) y removal reason.
Implementacion en Python
import os, requests, json
API_KEY = os.environ["SCAVIO_API_KEY"]
H = {"x-api-key": API_KEY}
PLAYLISTS = ["PLxxxxxxxxxxxxxxxxxxxxxx"]
def fetch(playlist_id):
r = requests.post("https://api.scavio.dev/api/v1/search",
headers=H, json={"platform": "youtube", "playlist": playlist_id})
return {v["id"]: v["title"] for v in r.json().get("videos", [])}
prev = json.load(open("snapshot.json")) if os.path.exists("snapshot.json") else {}
cur = {p: fetch(p) for p in PLAYLISTS}
for p, videos in cur.items():
removed = set(prev.get(p, {})) - set(videos)
for vid in removed:
print(f"REMOVED {vid} from {p}: {prev[p][vid]}")
json.dump(cur, open("snapshot.json", "w"))Implementacion en JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
const H = { "x-api-key": API_KEY, "content-type": "application/json" };
const PLAYLISTS = ["PLxxxxxxxxxxxxxxxxxxxxxx"];
const fs = require("fs");
async function fetchPl(id) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({ platform: "youtube", playlist: id })
}).then(r => r.json());
return Object.fromEntries((r.videos || []).map(v => [v.id, v.title]));
}
const prev = fs.existsSync("snapshot.json") ? JSON.parse(fs.readFileSync("snapshot.json")) : {};
const cur = {};
for (const p of PLAYLISTS) cur[p] = await fetchPl(p);
for (const [p, videos] of Object.entries(cur)) {
const removed = Object.keys(prev[p] || {}).filter(k => !videos[k]);
for (const vid of removed) console.log("REMOVED", vid, prev[p][vid]);
}
fs.writeFileSync("snapshot.json", JSON.stringify(cur));Plataformas utilizadas
YouTube
Búsqueda de videos con transcripciones y metadatos