Integración de 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

¡Acabo de ejecutar Manus! Veremos si da algún resultado concluyente.

Primera versión realizada por Manus 1.6.

No tendré la oportunidad de probar hoy, pero si alguien tiene prisa por probar, una imagen de prueba está disponible en el repositorio de GitHub.

Desde la página de integraciones, haga clic en el botón « Instalar desde GitHub » y pegue el enlace:

https://github.com/gboulvin/Gladys-Immich

He podido probar la conexión y está bien, pero al añadir un dispositivo tengo este error:

La integración ha publicado un dispositivo incompleto o inválido: Gladys se ha negado a registrarlo.

Detalles técnicos:

HTTP 422 — <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="robots" content="nofollow,noarchive,noindex">
  <title data-l10n>Entidad no procesable</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
  <!--  -->
  <meta name="title" content="422: Entidad no procesable">
  <meta name="description" content="">
  <meta property="og:title" content="422: Entidad no procesable">
  <meta property="og:description" content="">
  <meta property="og:locale" content="en_US">
  <meta property="twitter:title" content="422: Entidad no procesable">
  <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 segunda iteración (0.1.2) está lista y probada en mi caso.

  1. Crear una clave API en tu servidor Immich
  2. Completar los campos en la integración externa de Immich
  3. Guardar, probar la conexión y actualizar el diaporama
  4. En la pestaña « descubrimiento », guardar el dispositivo (cambiar su nombre si se desea). Es posible elegir la habitación en la pestaña « Dispositivos »
  5. Hay que añadir una… « cámara Immich » en el dashboard deseado y ¡listo!

¡Lo publico en la tienda, adelante con sus comentarios!

Edición:

Voy a seguir probando, pero creo que tendré un mejor resultado si añado la cámara en el dashboard antes de actualizar el diaporama. Parece que si se actualiza primero, la foto es demasiado grande, mientras que en el sentido contrario, se reduce.

Edición 2: No, es solo que la imagen es muy grande si está en modo retrato…

Tengo un error cuando pongo el uuid de un álbum:

[2026-08-13T22:03:12.795Z] [ERROR] [immich-slideshow] No se pudo publicar la siguiente diapositiva de Immich EmptyPhotoSourceError: No hay imágenes disponibles en “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'
}

Sin embargo, tengo imágenes en este álbum

Cuando pongo la fuente en « Recuerdos - Ese día » todo funciona correctamente :slight_smile:

Otro pequeño problema, no hay portada en la integración

Y si es posible en las mejoras poder agregar varios álbumes - 1 álbum por dispositivo sería genial creo :grinning_face:

También he tenido este error:

[2026-08-13T22:09:51.808Z] [ERROR] [immich-slideshow] No se pudo publicar la siguiente diapositiva de Immich Error: publishCameraImage: el tamaño máximo de la imagen es de 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] Publicado “20250812_123806_1800.jpeg” de Recuerdos — en este día

¡Hola!

¡Gracias por tu respuesta!

Sí, lo sé, pero no entiendo por qué. Cuando lo lanzo en modo desarrollador, lo tengo, pero no en la versión de lanzamiento. Tengo el mismo problema con las otras integraciones desarrolladas o en desarrollo…

Por lo demás, lo miro hoy :wink:

¡Listo, actualización disponible!

Ahora es posible listar los UUID de los 50 últimos álbumes, ¡más práctico! Para ello, una nueva acción está disponible al final de la página de configuraciones.

Atención, ahora es necesario que el asset.read esté marcado en los permisos de la clave API en Immich.

Lo miro esta noche :wink:

Y para la portada, quizá funcione la próxima vez, tengo buenas esperanzas :smiley:

El error está bien corregido :wink:
Gracias @GBoulvin
Y gracias de antemano por el resto :grinning_face:

¡Et voilà! ¡Nueva versión!

  • Posibilidad de seleccionar varios álbumes
  • Posibilidad de mostrar una leyenda
  • Por fin una imagen de portada (pero… Quizás la modifique en una próxima versión, ya que no es muy legible) Edito: Y además, no es un diaporama de videos. En fin…

Parece interesante, pero como no tengo un servidor immich, ¿alguien tendría un tutorial fácil para configurar este servidor?

Con docker: Docker Compose [Recommended] | Immich
Y encontrarás otros tipos de instalación.
En mi caso seguí Installer Immich sur un NAS Synology (Guide complet 2026) - Cachem pero hay que tener un Synology.

Seguí la documentación de Immich.

En resumen, hay que elegir una carpeta donde se guardarán las fotos y ejecutar el comando de Docker (no me acuerdo exactamente, pero primero hay que descargar un archivo, editarlo y luego ejecutar el comando).

Edición: @mutmut fue más rápido :smiley: Ya está instalado en mi Beelink S13

Gracias por esta versión @GBoulvin

En realidad, yo veía más la posibilidad de tener varios dispositivos aquí para reproducir un álbum en un dispositivo y otro álbum en otro dispositivo:

Mi solicitud puede que no sea pertinente, así que habrá que debatirlo seguro :wink:

¡Ahhh, de acuerdo!

Le preguntaré a Manus mañana :innocent:

Gracias por esta bonita integración :clap:
Creo que a largo plazo sería más interesante que el widget de Fotos tenga en cuenta esta fuente de fotos adicionales (en lugar de reutilizar la Cámara).

¿Qué opinas? En ese caso, puedo hacer una solicitud de funcionalidad en el núcleo de Gladys + SDK :thinking:

Sería Gladys quien contamina Immich y no una generación de instantáneas, imagino que también sería mejor en términos de recursos…

Efectivamente, te dejo hacerlo, ¡no me siento capaz!

¡Ya está hecho!

Por mi parte, no estoy convencido porque solo hay la posibilidad de configurar un segundo servidor vinculado a un segundo reproductor de diapositivas, pero funciona como se solicitó :wink:

Aquí tienes Widget Photo - sources issues d'intégrations (Immich)