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-keyet 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) |
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/albumspour 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 :
- URLs manuelles — comportement actuel, inchangé (rétrocompatibilité totale).
- Immich — Album — un menu déroulant liste les albums (via
GET /api/albums) ;
l’utilisateur en choisit un. - 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 dansPhotoBox.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 queIMAGE) 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
- Vidéos dans les albums : ignorer, ou afficher un poster ? (proposition : ignorer v1)
- Ordre d’affichage : chronologique inverse, chronologique, ou aléatoire ?
- Plafond du nombre de photos par source (perf) ?
- Légende : auto-générée (date + lieu) par défaut, ou pas de légende pour Immich ?

