> ## 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.

# Avatar dei contatti

> Come vengono rese e gestite le foto profilo dei contatti nella posta in arrivo e nei contatti.

# Avatar dei contatti

## Perché non recuperiamo automaticamente le foto profilo di WhatsApp

La Cloud API di WhatsApp di Meta **non** espone le foto profilo degli utenti finali. Il
webhook `messages` fornisce un payload `contacts[].profile` che include solo
`name`. Il campo `profile_picture_url` esiste solo su
`/whatsapp_business_profile` — cioè il profilo *dell'azienda stessa* — non sui
contatti utenti finali che ti scrivono.

Questo è coerente su tutti i BSP della piattaforma (360dialog, Twilio, Infobip,
ecc.). Non esiste alcuna API pubblica, edge Graph o campo webhook che restituisca
l'avatar del cliente.

## Cosa rendiamo

1. **Fallback con iniziali (default).** Rendiamo le iniziali del contatto su uno
   swatch di colore deterministico derivato da un hash del `wa_id` del contatto
   (fallback sul numero di telefono, fallback sul nome). Lo stesso contatto riceve
   sempre lo stesso colore, tra sessioni e dispositivi diversi.
2. **Override caricato dall'operatore.** Gli operatori possono caricare un JPG / PNG / WEBP fino
   a 2 MB dal pannello dei dettagli del contatto nella posta in arrivo. L'immagine viene ricodificata in un
   JPG quadrato 256×256 (EXIF rimosso) e archiviata nell'object store
   `workspace-attachments` sotto
   `contacts/{workspaceId}/{contactId}/avatar-{hash}.jpg`. L'URL viene salvato
   in `public.contacts.avatar_url` e reso ovunque il contatto appaia
   (barra laterale della posta in arrivo, intestazione della posta in arrivo, elenco contatti, layout mobile).

## Flusso di lavoro dell'operatore

* Apri una conversazione → pannello dei dettagli a destra → sezione **Profilo** →
  pulsanti **Carica** / **Sostituisci** / **Rimuovi**.
* I caricamenti raggiungono `POST /api/contacts/[contactId]/avatar` (multipart/form-data,
  campo `file`); la rimozione raggiunge `DELETE /api/contacts/[contactId]/avatar`.
* Entrambe le rotte richiedono un controllo di accesso attivo dell'operatore all'area di lavoro e verificano
  che il contatto appartenga all'area di lavoro del chiamante prima di effettuare modifiche.

## Modello dati

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

`avatar_url` è nullable. Null significa "rendi il fallback con le iniziali".

## Componente condiviso

`@repo/design-system/components/contact-avatar` esporta `<ContactAvatar>` con
`size` pari a `xs`, `sm`, `md`, `lg`. Usalo ovunque un contatto sia elencato per mantenere
coerente il comportamento del fallback.
