Run a YouTube channel's daily operations through the YouTube Data and Analytics APIs: scheduled/resumable video uploads, comment sweeps with moderation, and analytics pulls for week-over-week reporting. Use when someone asks to automate YouTube uploads, schedule videos for later release, reply to or moderate YouTube comments, pull channel or video analytics, or run YouTube channel ops on a schedule.
./install.sh youtube-connector-workflowsname: youtube_connector_workflows description: Run a YouTube channel's daily operations through the YouTube Data and Analytics APIs: scheduled/resumable video uploads, comment sweeps with moderation, and analytics pulls for week-over-week reporting. Use when someone asks to automate YouTube uploads, schedule videos for later release, reply to or moderate YouTube comments, pull channel or video analytics, or run YouTube channel ops on a schedule.
A bare connector reads YouTube. This skill runs the channel: the full operations loop a channel manager repeats weekly. Three playbooks cover it: scheduled uploads with the resumable protocol, comment operations (sweep, reply, moderate), and analytics pulls that produce a reportable numbers block. Each playbook pairs curl-grade endpoint knowledge with bin/yt-channel.py, a stdlib-only CLI that builds and (outside dry-run) executes the calls.
bin/yt-channel.py — one file, no dependencies beyond the Python standard library. Subcommands mirror the three playbooks:
yt-channel.py auth # refresh an OAuth access token, print it
yt-channel.py upload # resumable upload, optional --publish-at scheduling
yt-channel.py comments # list comment threads for a video or the channel
yt-channel.py reply # post a reply to a comment thread
yt-channel.py moderate # set moderation status (published | heldForReview | rejected, --ban-author)
yt-channel.py analytics # reports.query pull with metrics/dimensions/filters
Every subcommand accepts --dry-run: it prints the exact HTTP method, URL, headers, and body it would send, then stops. Use dry-run before any live run against a real channel. Live runs need env vars YT_CLIENT_ID, YT_CLIENT_SECRET, YT_REFRESH_TOKEN.
YouTube does not support service accounts for ordinary channel work. Authenticate once as the channel owner with OAuth 2.0 for installed apps, keep the refresh token, reuse it forever (or until revoked).
YT_REFRESH_TOKEN.yt-channel.py auth exchanges it for a fresh access token on every run. Access tokens last about an hour; the CLI handles refresh automatically.Scope ladder, least privilege first:
| Task | Scope | |---|---| | Read public/private video and channel metadata | https://www.googleapis.com/auth/youtube.readonly | | Analytics reads | https://www.googleapis.com/auth/yt-analytics.readonly (+ -monetary.readonly for revenue data) | | Upload only | https://www.googleapis.com/auth/youtube.upload | | Full channel management, comment writes and moderation | https://www.googleapis.com/auth/youtube.force-ssl or https://www.googleapis.com/auth/youtube |
Watch for: projects created after 2020-07-28 whose audit is not passed get all API uploads forced to private. This is Google's documented restriction, not a bug in your call. The audit lives at the quota and compliance page linked in references/.
videos.insert 100 calls/day, search.list 100 calls/day, everything else 10,000 units/day (reads cost 1, writes cost 50). Resets midnight Pacific. Full cost table in references/. Before any batch run, estimate the call count and compare; a batch that cannot finish in quota gets split across days, never retried in a tight loop.308 Resume Incomplete continue from the Range header offset, in 256KB chunk multiples. Retry transient 5xx with exponential backoff and jitter.status.publishAt (RFC 3339 timestamp) requires privacyStatus: private on upload; YouTube flips it public at the scheduled time. To reschedule, videos.update the status part.comments.setModerationStatus needs the channel/video owner's OAuth. Up to 50 comment IDs per call. rejected also hides all replies to the comment; you cannot re-publish a rejected comment; comments.delete works only for the comment's own author. banAuthor=true only pairs with rejected.reports.query data is complete only through the last day where all requested metrics are available; recent days may be partial. Never mix partial trailing days into week-over-week math. day and month cannot both be dimensions.videos.list, comments with commentThreads.list, analytics eyeball-checked against the response row count. Report what the API returned, not what was requested.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.