Armazenamento (R2)
Bucket S3-compatible pra imagens do chat — Cloudflare R2.
O chat de texto guarda imagens anexadas num bucket S3-compatible. O OpenCall usa Cloudflare R2: free tier generoso (10GB grátis) e, ao contrário do S3, sem custo de egress — você não paga pra servir as imagens de volta pros usuários.
Não precisa configurar CORS
O upload não sai direto do navegador pro R2: o arquivo sobe pro Next.js
(/api/chat/uploads), que valida e só então grava no bucket usando as
credenciais do servidor. Isso significa que a política de CORS do bucket
não entra em jogo — só a leitura pública (passo 4 abaixo) precisa estar
ativada.
Passos
No dashboard da Cloudflare, vá em R2
Object Storage → Create bucket. Dê um nome (ex: opencall-uploads).
Região: Automatic está ótimo.

Manage API Tokens (no painel do R2, não o de API Tokens geral da conta) → Create API Token. Dê permissão de Object Read & Write, e restrinja ao bucket criado no passo 1 (não precisa de acesso a todos os buckets da conta).
Isso gera:
- Access Key ID →
R2_ACCESS_KEY_ID - Secret Access Key →
R2_SECRET_ACCESS_KEY

O Account ID aparece no canto direito de qualquer página do dashboard
Cloudflare (inclusive a home do R2) → vira R2_ACCOUNT_ID.
Volte no bucket criado → Settings → Public Access. Ative a URL
pública padrão (formato pub-xxxxxxxx.r2.dev) — ou, se preferir um domínio
próprio, conecte um domínio/subdomínio seu ali mesmo.

Essa URL (com https:// na frente, sem barra no final) vira
NEXT_PUBLIC_R2_PUBLIC_BASE_URL.
Por que isso precisa ser público
Sem público, as imagens do chat não carregam pra ninguém — inclusive quem já está logado. O bucket guarda só as imagens que os próprios usuários anexam no chat (nada sensível do sistema), então deixar essa leitura pública é o comportamento esperado, não um risco de configuração.
Variáveis desta etapa
| Variável | Valor |
|---|---|
R2_ACCOUNT_ID | Passo 3 |
R2_ACCESS_KEY_ID | Passo 2 |
R2_SECRET_ACCESS_KEY | Passo 2 |
R2_BUCKET | Nome do bucket do passo 1 |
NEXT_PUBLIC_R2_PUBLIC_BASE_URL | URL pública do passo 4 |
NEXT_PUBLIC_ vai pro bundle do navegador
NEXT_PUBLIC_R2_PUBLIC_BASE_URL não é segredo — é só a URL de leitura
pública, então não tem problema ela aparecer no código do client. As outras
três (R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY) são
credenciais de escrita e ficam só no servidor.