YouTube Shorts
Google OAuth connect, encrypted tokens, and Shorts clip upload for post-now and scheduled dispatch.
YouTube Shorts publishing uses Google OAuth 2.0 with PKCE. Access and refresh tokens are encrypted at rest with INTEGRATIONS_ENCRYPTION_KEY. Uploads run at post-now or cron dispatch time (same pattern as X), not via publishAt scheduling on YouTube's side. Connect ships when enabled in prod (NEXT_PUBLIC_YOUTUBE_CONNECT_ENABLED=true).
Google Cloud setup (Cameron)
- Open Google Cloud Console and create or select a project.
- Enable the YouTube Data API v3 for that project.
- Configure the OAuth consent screen. While the app is in Testing, only Google accounts listed as test users can connect — add yourself (and any pilot emails) under Test users. Production external users require Google verification (out of scope for this MVP).
- Create an OAuth client ID: Application type → Web application.
- Add authorized redirect URI exactly matching
YOUTUBE_CALLBACK_URL(local default:http://localhost:3000/api/oauth/youtube/callback; production example:https://rallyforge.ai/api/oauth/youtube/callback). - Copy Client ID and Client Secret into the server environment (never commit secrets).
Environment variables
GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET— OAuth web clientYOUTUBE_CALLBACK_URL— must match the Google redirect URI (falls back to{APP_ORIGIN}/api/oauth/youtube/callbackif unset;GOOGLE_CALLBACK_URLis also accepted)INTEGRATIONS_ENCRYPTION_KEY— same vault key used for X and Twilio
Scopes requested: youtube.upload and youtube.readonly.
Connect in the app
- Open Connected Accounts in your workspace.
- On the YouTube Shorts card, choose Connect YouTube.
- Authorize RallyForge in the Google consent screen.
- You return to the workspace with the channel title shown — tokens never leave the server in plaintext.
Post a Short
- Attach a vertical clip (MP4/MOV/WebM, ≤250 MB, ideally ≤60s) in Quick Post or the scheduler.
- Select YouTube Shorts and the connected channel.
- Use Post now or schedule; cron at
/api/cron/dispatch-test-postsuploads when due. - Title comes from the post title; description from the body. If
#Shortsis missing, RallyForge appends it (YouTube's Shorts convention).
Test Mode does not redirect YouTube to email. Connected channels still upload for real (same as X).
Ops checklist (Cameron) — go live
- Apply migrations:
20260809000000_project_youtube_accounts.sqland20260809010000_knowledge_base_clip_file_size.sql(raisesknowledge-basebucketfile_size_limitto 250 MiB). - Set
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,YOUTUBE_CALLBACK_URL, and ensureINTEGRATIONS_ENCRYPTION_KEYis set (same vault as X / Twilio). - Confirm Google OAuth redirect URI matches prod, YouTube Data API v3 is enabled, and your Google account is a consent-screen test user while the app is in Testing.
- Smoke-test with a ~50–100 MB vertical Short first (not a full 250 MB file). Confirm Connected Accounts → YouTube, then Post now / scheduled cron dispatch.
Publish path: browser uploads clips direct to Supabase (signed URL). At post-now / cron, the server streams Storage → YouTube in ~8 MiB ranges (no full-file RAM buffer). Wall-clock still matters: Hobby functions cap at ~60s; this app asks for maxDuration = 300 (honored on Pro). Clips over ~40 MB show an in-app warning — 250 MB storage is fine, but a full 250 MB push is not reliable on Hobby.
Limitations (MVP)
- Shorts-oriented clips only — no playlists, thumbnails, or analytics deep dive
- Google OAuth verification required before unverified external users can connect
- YouTube Data API quotas apply (default ~10,000 units/day)
- Aspect ratio / duration are not validated client-side (prefer 9:16 ≤60s)
- No separate long-running worker — large clips need Pro timeouts (or a future queue); Hobby remains best-effort for ~40 MB sync publishes
Related
All connection guides · X (Twitter) · Campaigns & scheduling
