Menuabrir
EstávelAtualizado em 14 de mai. de 2026, 00:06

Este módulo depende de

2
  • marketingPlugin dentro do Hub framework de marketing
  • attributionCria attribution_campaign(kind=organic_youtube) via attribution_bridge

Módulos que dependem deste

0

Nenhum módulo depende deste hoje.

YouTube

Status: 🟢 Estável (Hub.6 deployado) Code: backend/app/modules/youtube UI: frontend/src/app/(admin)/[slug]/admin/marketing (seção YouTube) Última revisão deste doc: 2026-05-13 por Felipe + Claude Dependências fortes: marketing (Hub framework), attribution (campaign bridge)


1. Identidade

O que faz (uma frase)

Plugin YouTube do Mandir Hub — observa canal via Data API v3 + Analytics API v2, persiste canal, vídeos, métricas diárias, traffic sources, search terms, geography, demographics, playlists em 9 tabelas L0, e expõe 6 tools pro Conselheiro de Conteúdo & Marca.

Por que existe (negócio)

YouTube é canal de aquisição de longo prazo do Mais Consciente. Sem este módulo:

  • Felipe abre YouTube Studio toda vez.
  • Conselheiro Content & Brand não tem acesso a métricas pra responder "qual vídeo tá performando?".

Hub.6 traz histórico no DB + 6 tools no Conselho:

  • Top videos por views/watch_time.
  • Traffic sources (busca interna, sugeridos, externo).
  • Search terms (o que público buscou pra chegar).
  • Geography + demographics.

Status atual

  • Hub.6 deployado em 2026-05-13 (commit 613450e, alembic 0107).
  • OAuth Brand Account configurado — quirks documentados na memória [[oauth-brand-account-youtube]].

2. Cases de uso reais

Case 1: Felipe pergunta "qual vídeo bombou semana passada?"

Fluxo: Conselheiro Content & Brand chama read_youtube_top_videos(window_days=7, sort_by=views) → top 10 vídeos com views, watch_time, likes → Conselheiro sintetiza e propõe ação ("repostar formato X").

Case 2: Detecção de queda de subs

Beat marketing.run_observe(provider=youtube) → updates youtube_channel_daily.subscribers_lost → se queda > threshold → emit anomaly → intelligence.


3. Oportunidades de negócio

  • YouTube SEO insights: search_term_daily ajuda otimizar títulos/descrições — produto pra creators.
  • Cross-channel content tracking: vídeo X gera tráfego pro site (via GA4) — bridge YouTube → GA4.
  • Brand Account multi-channel: se cliente tem N canais, consolidar tudo num painel.

Riscos: Brand Account exige Workspace owner direto (não Manager pessoal); Analytics API quota 500M units/dia/projeto; subscribers_gained pode ser 0 em dias com baixa atividade.


4. Arquitetura interna

Arquivos

ArquivoPropósito
__init__.pyregister_plugin(YouTubePlugin())
plugin.pyImplementa observe() (Operate vem em Hub.9)
client.pyWrappers Data API v3 + Analytics API v2 (OAuth user consent)
models.py9 tabelas
sync.pysync_channel, sync_videos_catalog, sync_channel_daily, sync_video_daily (top 200), sync_traffic_sources, sync_search_terms, sync_geography, sync_demographics, sync_playlists
attribution_bridge.pyCria attribution_campaign(kind=organic_youtube)

Auth

  • OAuth user consent (access_token + refresh_token) cifrado em marketing_credential.secret_envelope.
  • Refresh automático via credentials.mark_token_refreshed.
  • Brand Account: requer Workspace owner direto, app GCP em Production.

5. Tabelas (9)

youtube_channel

Snapshot canal (Data API channels.list).

ColunaNotas
external_idChannel ID (ex: UCH6kecvLOgXgk3HmJ0CuF1w)
handle / title / description / custom_url
country / default_language
thumbnail_url / published_at
subscriber_count / hidden_subscriber_count
view_count / video_count
uploads_playlist_idPra paginação de vídeos

youtube_channel_daily

Métricas diárias (Analytics API).

ColunaNotas
views / estimated_minutes_watchedINT
average_view_duration_seconds / average_view_percentage
subscribers_gained / subscribers_lost
likes / dislikes / comments / shares
annotation_* / card_*Engagement detail
estimated_revenue / estimated_ad_revenue / estimated_red_partner_revenueDECIMAL
cpm / playback_based_cpm
monetized_playbacks / ad_impressions

youtube_video

Catálogo (Data API videos.list).

ColunaNotas
external_idVideo ID
title / description / published_at
thumbnail_url / duration_seconds
definition / caption_available / licensed_content
privacy_status / upload_status
category_id / default_language
made_for_kids
tags (JSONB)
is_short (BOOL)<60s vertical
view_count / like_count / comment_count / favorite_count

youtube_video_daily

Métricas por vídeo × dia (Analytics API + filter video=). Similar a channel_daily mas com video_external_id. Limita top 200 vídeos por economia de quota.

youtube_traffic_source_daily

ColunaNotas
sourceYT_SEARCH / EXTERNAL / RELATED_VIDEO / SUBSCRIBER / BROWSE_FEATURES / SHORTS / etc.
views

youtube_search_term_daily

ColunaNotas
search_termTexto buscado
views / estimated_minutes_watched

youtube_geography_daily

ColunaNotas
countryISO code
views

youtube_demographics

Snapshot mensal (não diário — dedupe por (tenant, channel, snapshot_date, age_group, gender)).

ColunaNotas
age_groupage13-17 / age18-24 / ... / age65-
genderfemale / male / user_specified / unknown

youtube_playlist

Catálogo playlists.

Relacionamentos cross-módulo

DireçãoOutro móduloComo
↘ EscreveattributionCria attribution_campaign(kind=organic_youtube) por novo channel/video
↘ Toolscouncil6 tools

6. API / Endpoints

MétodoRotaO que faz
GET/api/marketing/youtube/summaryViews, minutes, subs gained/lost, likes, comments, revenue (window)
GET/api/marketing/youtube/videosTop vídeos por métrica (views/minutes/likes/comments/revenue)
GET/api/marketing/youtube/traffic-sourcesBreakdown por source
GET/api/marketing/youtube/geographyViews por país
GET/api/marketing/youtube/demographicsAge/gender (latest snapshot)
GET/api/marketing/youtube/search-termsTop searches

7. Tools no Council (6)

read_youtube_summary, read_youtube_top_videos, read_youtube_traffic_sources, read_youtube_search_terms, read_youtube_geography, read_youtube_demographics.


8. Configuração

Credencial

CampoValor
provideryoutube
account_external_idchannel_id
auth_kindoauth2
secret_envelope{channel_id, access_token, refresh_token}
scope["https://www.googleapis.com/auth/youtube.readonly", "https://www.googleapis.com/auth/yt-analytics.readonly"]

Setup OAuth Brand Account (memória [[oauth-brand-account-youtube]])

  • App GCP em Production (não Testing).
  • Login com Workspace dona direta (não Manager pessoal).
  • OOB deprecou — usar loopback localhost.
  • Felipe ignora warning "app não verificado" (interno).

9. Operações

Como conectar canal

  1. UI Marketing → Conectar YouTube → OAuth flow.
  2. User autoriza no Google.
  3. Backend cifra secret + cria credencial.
  4. Trigger sync inicial: POST /sync/run?provider=youtube&credential_id=Y.

Troubleshooting

Sintoma: Sync falha com unauthorized

Causa: Token expirou e refresh falhou. Fix: Reconectar (gera novo refresh_token).

Sintoma: Demographics vazio

Causa: Canal pequeno (< threshold YouTube reporta). Tratamento: Esperado.


10. Limitações e débitos técnicos

#Item
12 dias delay reporting
2Brand Account quirks
3Top 200 vídeos no daily
4Demographics snapshot mensal
5MIGRATION_DATABASE_URL hardcoded

11. Histórico

  • 2026-05-13 (commit 613450e, alembic 0107) — Hub.6 deployado. 9 tabelas + 6 tools. Memória [[sessao-2026-05-13-hub56]].