Pular para o conteúdo

Foto do grupo

Retorna a foto de um grupo do WhatsApp: redireciona (302) para uma URL pré-assinada quando a foto está no seu BYO Storage; caso contrário, responde 200 com o objeto picture (estado e motivo). O formato da resposta é o mesmo do endpoint de foto de perfil de contato, mas o que acontece quando a URL pré-assinada não pode ser gerada é diferente nos dois: veja Comportamento por picture.kind.

Endpoint

GET /v1/groups/{group_id}/picture

Escopo obrigatório: groups:read. Para números extras: GET /v1/numbers/{ref}/groups/{group_id}/picture, onde {ref} é o number_id do envelope do evento do grupo (num_…, não muda) ou o alias atual do número. group_id é o id público (grp_{hex32}).

Comportamento por picture.kind

O picture retornado tem apenas dois estados possíveis: available (foto no seu BYO Storage) ou unavailable (qualquer outra situação, com a causa em reason):

picture.kindResposta HTTP
available302 Found: URL pré-assinada do BYO Storage (R2/S3/Supabase), nunca a chave do objeto no bucket
unavailable200 OK: corpo JSON { "kind": "unavailable", "reason": ..., "setup_hint"?: ... } (ver campo reason abaixo)

O valor picture.kind = "pending" só aparece em payloads de webhook: este endpoint de leitura nunca o retorna.

Se a foto já está no seu BYO Storage mas a URL pré-assinada não pôde ser gerada nesta requisição, o endpoint responde 200 OK com unavailable e a causa em reason. Ele nunca retorna 404 para foto indisponível.

O Turbo Notify reavalia a foto marcada como unavailable na próxima mensagem de um membro do grupo (ou enviada pelo próprio celular) depois que você habilita o BYO Storage, respeitada a janela de 6 horas se já houve consulta. Mensagens enviadas só pela API não disparam a busca (veja Quando as fotos aparecem e a foto fica disponível depois).

Exemplo: foto disponível

Terminal window
curl -I "https://api.turbonotify.com/v1/groups/grp_.../picture" \
-H "Authorization: Bearer SUA_CHAVE"
HTTP/1.1 302 Found
Location: https://<bucket>.r2.cloudflarestorage.com/groups/.../picture.jpg?...
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache

A URL pré-assinada tem validade curta: 15 minutos por padrão (configurável entre 1 minuto e 1 hora na sua integração de armazenamento).

Exemplo: foto indisponível (sem armazenamento)

Status HTTP: 200
{
  "kind": "unavailable",
  "reason": "no_storage",
  "setup_hint": {
    "setup_url": "https://dashboard.turbonotify.com/storage",
    "docs_url": "https://docs.turbonotify.com/general/byo-storage-setup/",
    "message": "Configure object storage (S3, Cloudflare R2, or Supabase Storage, free tiers available) to receive media. Visit your dashboard or read the docs."
  }
}

O campo reason indica a causa: no_storage (sem armazenamento configurado), storage_circuit_open (o seu armazenamento vinha falhando e o envio foi suspenso temporariamente), upload_failed (o envio da foto para o seu bucket falhou desta vez) ou peer_has_none (o grupo não tem foto). O setup_hint só é preenchido para no_storage e storage_circuit_open. Para upload_failed e peer_has_none ele vem como null. É o mesmo formato usado pela mídia e pela foto de contato.

Campo picture em GET /v1/numbers/{ref}/groups/{group_id}

O campo picture no payload completo do grupo mostra o mesmo estado: traz a URL pré-assinada quando a foto está disponível e o reason e o setup_hint corretos quando ela está unavailable.

Cache

  • A resposta vem com Cache-Control: no-store, no-cache, must-revalidate e Pragma: no-cache: ela não deve ser guardada em cache, inclusive o redirecionamento 302. Refaça a chamada sempre que precisar do estado atual. A URL pré-assinada indicada em Location continua válida pelo próprio prazo dela, e é essa URL que você deve reutilizar se quiser evitar um novo download.
  • A URL pré-assinada tem validade curta: 15 minutos por padrão (configurável entre 1 minuto e 1 hora). Não reutilize a URL além desse prazo; refaça a chamada para obter uma nova.