Intégration Immich

Intégration Immich pour le Photo Widget

1. Contexte & objectif

Gladys disposera bientôt d’un Photo Widget de dashboard (box.type = 'photo') qui affiche
un diaporama à partir d’une liste d’URLs saisies à la main ({ url, caption }). Les images sont
récupérées via un proxy serveur (GET /api/v1/dashboard/photo/proxy?url=) pour rester
accessible à distance (Gladys Plus).

Objectif : permettre à l’utilisateur d’alimenter automatiquement ce diaporama depuis
un serveur Immich (gestionnaire de photos auto-hébergé).

L’utilisateur connecte son Immich une fois, puis choisit une source dynamique (un album,
ou ses souvenirs « ce jour-là ») ; le widget affiche les photos correspondantes et se
rafraîchit tout seul.

Périmètre v1

  • Sources : Album au choix + Souvenirs « ce jour-là »
  • Qualité d’image : preview (~1440px)
  • Architecture : service Immich complet (page de config + proxy authentifié)

2. L’API Immich — ce qu’elle permet

2.1 Authentification

  • Toutes les requêtes portent le header x-api-key: <clé>.
  • La clé se génère dans Immich : Account Settings → API Keys. Permissions minimales
    utiles : album.read, asset.read, memory.read.
  • Base URL = adresse du serveur Immich, ex. http://192.168.1.20:2283. Tous les chemins
    ci-dessous sont préfixés par /api.

Point structurant : le proxy actuel de Gladys (dashboard.getPhoto.js) fait un GET sans
header
→ il ne peut pas parler à Immich. Il faut donc un proxy dédié Immich qui injecte
x-api-key et pointe sur la base URL configurée.

2.2 Choisir quelles photos afficher (les sources)

Source Endpoint Réponse utile
Liste des albums GET /api/albums [{ id, albumName, assetCount, albumThumbnailAssetId, shared }] — sert à peupler le sélecteur d’album
Contenu d’un album GET /api/albums/{id} { albumName, assets: [{ id, type, originalFileName, fileCreatedAt, exifInfo }] }
Souvenirs « ce jour-là » GET /api/memories [{ id, type:"on_this_day", memoryAt, data:{ year }, assets:[{ id, ... }] }] — un groupe par année passée à la même date

2.3 Récupérer le fichier image d’un asset

Chaque photo est identifiée par un UUID asset.id. Trois rendus :

Variante Endpoint Usage
Preview (~1440px) :white_check_mark: v1 GET /api/assets/{id}/thumbnail?size=preview Bon compromis qualité/poids pour un diaporama
Vignette GET /api/assets/{id}/thumbnail?size=thumbnail Petite miniature (timeline)
Original GET /api/assets/{id}/original Qualité max, fichiers potentiellement lourds (>5 Mo)

Réponse = flux binaire image/*. Le proxy Immich le convertit au format déjà attendu par
le widget : "<contentType>;base64,<data>".

2.4 Champs d’asset exploitables pour la légende

originalFileName, fileCreatedAt / localDateTime, et exifInfo (description, city,
dateTimeOriginal). Permet d’auto-générer une légende (ex. « Rome — 12 août 2019 »).

3. Comportement fonctionnel attendu

3.1 Connexion de l’intégration (une fois)

  • Nouvelle carte Immich dans la liste des intégrations.
  • Page de config demandant URL du serveur + clé API.
  • Bouton « Tester la connexion » → appelle GET /api/albums pour valider URL + clé, et
    remonte une erreur claire si échec (URL injoignable, 401 clé invalide).

3.2 Configuration du widget (par l’utilisateur, à l’édition du dashboard)

Le Photo Widget gagne un choix de mode de source :

  1. URLs manuelles — comportement actuel, inchangé (rétrocompatibilité totale).
  2. Immich — Album — un menu déroulant liste les albums (via GET /api/albums) ;
    l’utilisateur en choisit un.
  3. Immich — Souvenirs — affiche les photos renvoyées par GET /api/memories
    (« il y a X ans, ce jour-là ».

Options existantes conservées et applicables à tous les modes : cadrage (cover/contain),
intervalle de défilement, affichage/masquage des légendes, titre du widget.

Pour les modes Immich, la légende peut être auto-générée depuis les métadonnées de l’asset (date + lieu) plutôt que saisie à la main.

3.3 Affichage (runtime)

  • À l’ouverture, le widget résout la source Immich en liste d’assets (album ou souvenirs),
    puis affiche chaque image en preview via le proxy Immich authentifié.
  • Diaporama : défilement automatique selon l’intervalle, navigation avant/arrière et
    indicateurs (déjà présents dans PhotoBox.jsx).
  • Cache image en mémoire + préchargement de l’image suivante (déjà présents), réutilisés tels quels.
  • Rafraîchissement de la liste : la liste d’assets (surtout « souvenirs », qui change
    chaque jour) est ré-interrogée périodiquement / au montage du widget, à décider.

3.4 Cas limites & décisions fonctionnelles à valider

  • Album vide / souvenirs vides du jour → état vide explicite (message), pas d’erreur.
  • Vidéos dans un album (asset.type = VIDEO) → filtrées (on ne garde que IMAGE) ou
    affichage de leur poster ? → à trancher (proposition : ignorer les vidéos en v1).
  • Gros albums → limiter le nombre d’assets chargés (ex. plafond + éventuel ordre
    aléatoire) pour éviter des milliers d’entrées ? → à trancher.
  • Ordre d’affichage : chronologique (par fileCreatedAt), inverse, ou aléatoire ?
    à trancher (proposition : plus récent d’abord).
  • Plafond 5 Mo du proxy : preview reste largement sous la limite, donc conservé. À
    revoir seulement si on ajoute le mode « original » ou vidéo plus tard.

4. Sources d’API (référence)

  • Doc API Immich : API | Immich · endpoints : Immich - API Documentation
  • Albums : getAllAlbums, getAlbumInfo · Souvenirs : searchMemories (GET /api/memories)
  • Image : viewAsset / GET /api/assets/{id}/thumbnail?size=preview
  • Random (réf.) : POST /api/search/random · Métadonnées : POST /api/search/metadata

5. Questions ouvertes avant passage à l’implémentation

  1. Vidéos dans les albums : ignorer, ou afficher un poster ? (proposition : ignorer v1)
  2. Ordre d’affichage : chronologique inverse, chronologique, ou aléatoire ?
  3. Plafond du nombre de photos par source (perf) ?
  4. Légende : auto-générée (date + lieu) par défaut, ou pas de légende pour Immich ?

Idées de maquettes