> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchbord.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Avatares de contato

> Como as fotos de perfil de contato são renderizadas e gerenciadas no inbox e nos contatos.

# Avatares de contato

## Por que não buscamos automaticamente as fotos de perfil do WhatsApp

A Cloud API do WhatsApp, da Meta, **não** expõe fotos de perfil dos usuários finais. O
webhook `messages` entrega um payload `contacts[].profile` que inclui apenas
`name`. O campo `profile_picture_url` existe apenas em
`/whatsapp_business_profile` — ou seja, o perfil *da própria empresa* — não o dos
contatos usuários finais que enviam mensagens para você.

Isso é consistente em todos os BSPs da plataforma (360dialog, Twilio, Infobip,
etc.). Não existe API pública, edge do Graph, ou campo de webhook que retorne
o avatar do cliente.

## O que renderizamos

1. **Fallback de iniciais (padrão).** Renderizamos as iniciais do contato sobre
   um selo de cor determinístico derivado de um hash do `wa_id` do contato
   (com fallback para o número de telefone, e depois para o nome). O mesmo
   contato sempre recebe a mesma cor entre sessões e dispositivos.
2. **Substituição enviada pelo operador.** Operadores podem enviar um JPG / PNG / WEBP
   de até 2 MB pelo painel de detalhes do contato no inbox. A imagem é reconvertida
   para um JPG quadrado de 256×256 (com EXIF removido) e armazenada no
   object store `workspace-attachments`, em
   `contacts/{workspaceId}/{contactId}/avatar-{hash}.jpg`. A URL é persistida
   em `public.contacts.avatar_url` e renderizada em todos os lugares em que o contato
   aparece (barra lateral do inbox, cabeçalho do inbox, lista de contatos, layouts mobile).

## Fluxo de trabalho do operador

* Abra uma conversa → painel de detalhes à direita → seção **Profile** →
  botões **Upload** / **Replace** / **Remove**.
* Os uploads acessam `POST /api/contacts/[contactId]/avatar` (multipart/form-data,
  campo `file`); a remoção acessa `DELETE /api/contacts/[contactId]/avatar`.
* Ambas as rotas exigem uma verificação ativa de acesso ao workspace do operador
  e confirmam que o contato pertence ao workspace de quem faz a chamada antes de alterar dados.

## Modelo de dados

```sql theme={null}
alter table public.contacts add column if not exists avatar_url text;
```

`avatar_url` é anulável (nullable). Nulo significa "renderizar o fallback de iniciais".

## Componente compartilhado

`@repo/design-system/components/contact-avatar` expõe `<ContactAvatar>` com
`size` de `xs`, `sm`, `md`, `lg`. Use-o em qualquer lugar em que um contato seja
listado, para manter o comportamento de fallback consistente.
