Skip to main content

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

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.