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) 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 :
- 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 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
- 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 ?
Je viens de lancer Manus dessus. On verra si ça donne quelque chose de concluant !
Première version réalisée par Manus 1.6.
Je n’aurai pas l’occasion de tester aujourd’hui mais si quelqu’un est impatient d’essayer, une image de test est disponible sur le dépôt GitHub.
Depuis la page intégrations, cliquer sur le bouton « Installer depuis GitHub » et coller le lien :
https://github.com/gboulvin/Gladys-Immich
J’ai pu tester la connexion est ok par contre l’ajout d’un appareil j’ai cette erreur :
L’intégration a publié un appareil incomplet ou invalide : Gladys a refusé de l’enregistrer.
Détail technique :
HTTP 422 — <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="robots" content="nofollow,noarchive,noindex">
<title data-l10n>Unprocessable Entity</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<!-- -->
<meta name="title" content="422: Unprocessable Entity">
<meta name="description" content="">
<meta property="og:title" content="422: Unprocessable Entity">
<meta property="og:description" content="">
<meta property="og:locale" content="en_US">
<meta property="twitter:title" content="422: Unprocessable Entity">
<meta property="twitter:description" content="">
<meta name="format-detection" content="telephone=no">
<style>
:root {
--color-bg-primary: #ffffff;
--color-text-primary: #000000;
--color-text-emphasis: #333333;
--color-text-heading: #444444;
--color-text-secondary: #555555;
--color-text-subtle: #888888;
--color-illust-ink: #263238;
…
La seconde itération (0.1.2) est prête et testée chez moi.
- Créer une clé API dans votre serveur Immich
- Compléter les champs dans l’intégration externe Immich
- Sauvegarder, tester la connexion et actualiser le diaporama
- Dans l’onglet « découverte », sauvegarder l’appareil (changer son nom si désiré). Il est possible de choisir la pièce dans l’onglet « Appareils »
- Il faut ajouter une… « caméra Immich » dans le dashboard voulu et c’est parti !
Je publie sur le store, Go pour vos retours !
Edit :
Je vais encore tester mais je pense avoir un meilleur résultat si j’ajoute la caméra sur le dashboard avant d’actualiser le diaporama. Il semble que si on actualise d’abord, la photo est trop grande alors que dans le sens contraire, elle est réduite.
Edit 2: Non, c’est juste que l’image est fort grande si elle est en mode portrait…
J’ai une erreur lorsque je mets l’uuid d’un album :
[2026-08-13T22:03:12.795Z] [ERROR] [immich-slideshow] Failed to publish the next Immich slide EmptyPhotoSourceError: No images are available in “MonAlbum”.
at ImmichSlideshow.next (file:///app/src/slideshow.js:118:13)
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
at async publishNextSlide (file:///app/src/devices/slideshowCamera.js:61:17)
at async publish (file:///app/src/devices/slideshowCamera.js:118:9) {
code: 'EMPTY_SOURCE'
}
Pourtant j’ai bien des images dans cet album
Quand je mets la sources sur « Souvenirs - Ce jour là » tout fonctionne correctement 
Autre petit problème, il n’y a pas de cover sur l’intégration
Et si possible dans les améliorations pouvoir rajouter plusieurs albums - 1 album par appareil serait cool je pense 
J’ai également eu cette erreur :
[2026-08-13T22:09:51.808Z] [ERROR] [immich-slideshow] Failed to publish the next Immich slide Error: publishCameraImage: maximum image size is 153600 bytes (150 KB)
at GladysIntegration.publishCameraImage (/app/node_modules/@gladysassistant/integration-sdk/lib/gladys-integration.js:606:13)
at publishNextSlide (file:///app/src/devices/slideshowCamera.js:63:16)
at async publish (file:///app/src/devices/slideshowCamera.js:118:9)
[2026-08-13T22:10:51.644Z] [INFO] [immich-slideshow] Published “20250812_123806_1800.jpeg” from Memories — on this day
Salut!
Merci pour ton retour !
Oui, je sais mais je ne comprends par pourquoi. Quand je lance en mode développeur, je l’ai mais plus dans la release. J’ai le même problème avec les autres intégrations développées ou en développement…
Pour le reste, j’y regarde dans la journée 
Voilà, mise à jour disponible.
Il est désormais possible de lister les UUID des 50 derniers albums, plus pratique ! Pour ce faire, une nouvelle action est disponible en bas de la page de configurations.
Attention, il faut désormais que l’asset.read soit coché dans les autorisations de la clef API dans Immich.
J’y regarde ce soir 
Et pour la cover, peut-être que ça fonctionnera la prochaine fois, j’ai bon espoir 
Le bug est bien corrigé 
Merci @GBoulvin
Et merci d’avance pour le reste 
Et hop ! Nouvelle version !
- Possibilité de choisir plusieurs albums
- Possibilité d’afficher une légende
- Enfin une image de cover (mais euh… Je vais peut-être bien modifier dans une prochaine release car pas hyper lisible) Edit : Et en plus, ce n’est pas un diaporama de vidéos. Bref…
ça m’a l’air intéressant, mais comme je n’ai pas de serveur immich, quelqu’un aurait-il un tuto facile pour mettre en place ce serveur ?
Avec docker : Docker Compose [Recommended] | Immich
Et tu trouveras les autres types d’install.
Chez moi j’ai suivi Installer Immich sur un NAS Synology (Guide complet 2026) - Cachem mais il faut avoir un syno.
J’ai suivi la doc de Immich.
En gros, il faut choisir un dossier dans lequel seront stockées les photos et lancer la commande docker (je ne sais plus exactement mais il y a d’abord un fichier à télécharger, l’éditer puis lancer la commande).
Edit : @mutmut a été plus rapide
C’est installé sur mon Beelink S13
Merci pour cette version @GBoulvin
En faite je voyais plus la possibilité d’avoir plusieurs appareils ici afin de jouer un album via un appareil et un autre album dans un autre appareil :
Ma demande est peut être pas pertinente donc à débattre surement 
Ahhh, d’accord !
Je demanderai à Manus demain 
Merci pour cette belle intégration 
Je pense qu’il serait plus intéressant à terme que le widget Photos prenne en compte cette source de photos supplémentaires (plutôt que réutiliser Caméra).
Qu’est-ce que tu en penses ? Dans ce cas-là, je peux faire une demande de fonctionnalité dans le core Gladys + SDK 
Ce serait Gladys qui poll Immich et non une génération de snapshots, j’imagine que ce serait mieux également en termes de ressources…
Effectivement, je te laisse faire ça, je ne m’en sens pas capable !
Voilà qui est fait !
Perso, je ne suis pas convaincu car il y a juste la possibilité de configurer un deuxième serveur lié à un second slideshow mais cela fonctionne comme demandé 