Automatisation de la génération de texte de Lightroom vers Instagram avec Claude AI
Ceci est unSocial Media, Multimodal AIworkflow d'automatisation du domainecontenant 14 nœuds.Utilise principalement des nœuds comme Set, Code, Sort, SplitOut, DataTable. Utiliser Claude AI en tant que générateur de texte pour automatiser de Lightroom vers Instagram
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
Nœuds utilisés (14)
Catégorie
{
"meta": {
"instanceId": "57636d705a86a73b059f5900e8853e2c306d74773d27ee7f6c0fae07093009ef"
},
"nodes": [
{
"id": "466448fc-8554-49c7-a6e7-8e5ded1d43ea",
"name": "Note adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
0
],
"parameters": {
"width": 464,
"height": 400,
"content": "### Lightroom → Instagram: Photos-to-Post Queue (n8n)\n\n**Purpose** \nWatch a Lightroom Cloud album, store new assets in a **Photos** Data Table, and generate AI alt text for captions/accessibility.\n\n**Must-configure**\n- **Lightroom API:** OAuth (Adobe) + **X-API-Key**; set your **LR catalog ID** and **LR album ID**.\n- **n8n base URL:** Publicly reachable; used by the image proxy webhook.\n- **LLM credentials:** Anthropic (or equivalent) for alt text.\n- **Data Table (Photos) minimal schema:** `lr_asset_id` (unique), `lr_asset` (JSON string), `alt` (string).\n- **Schedule:** How often to poll the album.\n- **Dedupe:** Use **rowNotExists** on `lr_asset_id` to avoid duplicates.\n- **Params Node**"
},
"typeVersion": 1
},
{
"id": "2694839a-5677-4a39-951d-d1d1a773d756",
"name": "Requête HTTP",
"type": "n8n-nodes-base.httpRequest",
"position": [
736,
480
],
"parameters": {
"url": "=https://lr.adobe.io/v2/catalogs/{{ $json[\"LR catalog ID\"] }}/albums/{{ $json[\"LR album ID\"] }}/assets?embed=asset ",
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"headerParameters": {
"parameters": [
{
"name": "X-API-Key",
"value": "={{ $json[\"LR API key\"] }}"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "nv3KEXFaYuFgl9pg",
"name": "Lightroom Camille"
},
"httpBearerAuth": {
"id": "HSch2E1Drk2LTOp0",
"name": "Instagram @camillerouxphoto"
}
},
"typeVersion": 4.2
},
{
"id": "387d3cfb-7315-4d17-a528-09e9c1e0688c",
"name": "Code en JavaScript",
"type": "n8n-nodes-base.code",
"position": [
960,
480
],
"parameters": {
"jsCode": "/**\n * Nettoie le préfixe XSSI \"while(1){}\" des réponses Adobe Lightroom\n * puis parse en JSON. L'item résultant contient:\n * - parsed: l'objet JSON parsé\n * - raw: le texte brut nettoyé (optionnel, utile pour debug)\n *\n * Le code gère aussi les cas où l'entrée serait déjà un objet,\n * ou si la chaîne ne contient pas le préfixe.\n */\n\nfunction stripAdobePrefix(s) {\n // supprime \"while(1){}\" avec ou sans espaces\n const re = /^\\s*while\\s*\\(\\s*1\\s*\\)\\s*{\\s*}\\s*/;\n return s.replace(re, '');\n}\n\nlet input = $json;\n\n// Si le node précédent a renvoyé la réponse sous un autre champ,\n// adapte cette ligne (par ex. input.body, input.data, etc.)\nif (typeof input !== 'string') {\n // tente quelques emplacements possibles\n if (typeof input.body === 'string') input = input.body;\n else if (typeof input.data === 'string') input = input.data;\n else if (typeof input.string === 'string') input = input.string;\n else if (typeof input === 'object') {\n // déjà un objet ? On renvoie tel quel.\n return {\n parsed: input,\n raw: JSON.stringify(input),\n _note: 'Entrée déjà objet — pas de nettoyage nécessaire.'\n };\n } else {\n // fallback: stringify\n input = JSON.stringify(input);\n }\n}\n\nconst cleaned = stripAdobePrefix(input);\n\n// Essaie de parser proprement\ntry {\n const parsed = JSON.parse(cleaned);\n return {\n parsed,\n raw: cleaned\n };\n} catch (err) {\n // En cas d’erreur, on renvoie quand même la chaîne nettoyée pour debug\n return {\n parsed: null,\n raw: cleaned,\n error: `JSON.parse a échoué: ${err && err.message ? err.message : String(err)}`\n };\n}\n"
},
"typeVersion": 2
},
{
"id": "56501cf9-12bb-4e24-a27e-6d45d2b65c9d",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
1184,
480
],
"parameters": {
"options": {},
"fieldToSplitOut": "parsed.resources"
},
"typeVersion": 1
},
{
"id": "6c46f47f-ba78-490f-90eb-b5d6f4a5f7cf",
"name": "Analyze image",
"type": "@n8n/n8n-nodes-langchain.anthropic",
"position": [
2336,
512
],
"parameters": {
"text": "You are a photography-savvy describer. Analyze the image and write a factual, SEO-oriented English alt description (single paragraph, up to 500 characters). Focus on visible subject, composition/framing/perspective, lighting (type, direction, quality), colors/contrast, mood, setting/background, and any clearly legible text. Avoid guesses about brand, gear, identities, dates, or locations unless unambiguously visible. No sensitive attributes, no hashtags/emojis, no calls to action. Output only the paragraph.\n",
"modelId": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "claude-sonnet-4-5-20250929"
},
"options": {},
"resource": "image",
"imageUrls": "={{ $('Params').item.json[\"n8n instance URL\"] }}/webhook/lr-image?catalogId={{ $('Params').item.json[\"LR catalog ID\"] }}&assetId={{ $json.asset.id }}&format=1280 "
},
"credentials": {
"anthropicApi": {
"id": "9xU4CUFgJLLaeCNB",
"name": "Anthropic account"
}
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "86e95eea-9e5c-4791-ac93-938daee1f480",
"name": "If row does not exist",
"type": "n8n-nodes-base.dataTable",
"position": [
1632,
480
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "lr_asset_id",
"keyValue": "={{ $json.asset.id }}"
}
]
},
"operation": "rowNotExists",
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "Z4VvX6MjrmHmlAiY",
"cachedResultUrl": "/projects/wrMsdivh0K45jnU5/datatables/Z4VvX6MjrmHmlAiY",
"cachedResultName": "Photos"
}
},
"typeVersion": 1
},
{
"id": "28ffac78-712b-4405-a9e7-161edfb4bce4",
"name": "Insert row",
"type": "n8n-nodes-base.dataTable",
"position": [
2560,
512
],
"parameters": {
"columns": {
"value": {
"alt": "={{ $json.content[0].text }}",
"lr_asset": "={{ JSON.stringify($('Split Out').item.json.asset) }}",
"lr_asset_id": "={{ $('Split Out').item.json.asset.id }}"
},
"schema": [
{
"id": "lr_asset_id",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "lr_asset_id",
"defaultMatch": false
},
{
"id": "lr_album_id",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "lr_album_id",
"defaultMatch": false
},
{
"id": "ig_posted_at",
"type": "dateTime",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "ig_posted_at",
"defaultMatch": false
},
{
"id": "ig_link",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "ig_link",
"defaultMatch": false
},
{
"id": "ig_caption",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "ig_caption",
"defaultMatch": false
},
{
"id": "lr_asset",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "lr_asset",
"defaultMatch": false
},
{
"id": "alt",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "alt",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "Z4VvX6MjrmHmlAiY",
"cachedResultUrl": "/projects/wrMsdivh0K45jnU5/datatables/Z4VvX6MjrmHmlAiY",
"cachedResultName": "Photos"
}
},
"typeVersion": 1
},
{
"id": "0bfc2470-666e-4aa9-94a5-c5e781fd931d",
"name": "Trier",
"type": "n8n-nodes-base.sort",
"position": [
1408,
480
],
"parameters": {
"options": {},
"sortFieldsUi": {
"sortField": [
{
"fieldName": "asset.payload.captureDate"
}
]
}
},
"typeVersion": 1
},
{
"id": "b4b23fa3-b7cb-441d-8d32-5d7e04745e38",
"name": "Déclencheur planifié",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
480
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "66066e44-0326-4f2e-9870-3c35818e75df",
"name": "Boucler sur les éléments",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2080,
480
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "7fbb8e78-78de-494e-b090-f1b1805c3714",
"name": "Params",
"type": "n8n-nodes-base.set",
"position": [
208,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d354b020-5d5c-4270-8dfb-0dc02e9bd9db",
"name": "LR catalog ID",
"type": "string",
"value": "..."
},
{
"id": "ec256e0e-71d9-43bd-8913-99213526b776",
"name": "LR API key",
"type": "string",
"value": "..."
},
{
"id": "fde215d4-14d4-4659-9f57-defdb3c4733f",
"name": "LR album ID",
"type": "string",
"value": "..."
},
{
"id": "978ee1e9-3d6f-4d87-afaf-c9926a20b690",
"name": "n8n instance URL",
"type": "string",
"value": "..."
}
]
}
},
"typeVersion": 3.4
},
{
"id": "43bc3fd0-5578-4070-bd2a-2562d20e5ded",
"name": "Note adhésive1",
"type": "n8n-nodes-base.stickyNote",
"position": [
624,
320
],
"parameters": {
"color": 5,
"width": 512,
"height": 400,
"content": "## STEP1 = Download the image list from Lightroom Cloud\n\n"
},
"typeVersion": 1
},
{
"id": "642efa01-7722-4390-beaa-a3665d184133",
"name": "Note adhésive2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1168,
320
],
"parameters": {
"color": 5,
"width": 720,
"height": 400,
"content": "## STEP2 = Split and sort them\n\n\n"
},
"typeVersion": 1
},
{
"id": "267c95f8-1000-4ce7-8bd9-a2221f554923",
"name": "Note adhésive3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1920,
320
],
"parameters": {
"color": 5,
"width": 848,
"height": 400,
"content": "## STEP3 = Analyse them with IA then save them in the Data Table\n\n\n"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Sort": {
"main": [
[
{
"node": "86e95eea-9e5c-4791-ac93-938daee1f480",
"type": "main",
"index": 0
}
]
]
},
"7fbb8e78-78de-494e-b090-f1b1805c3714": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"56501cf9-12bb-4e24-a27e-6d45d2b65c9d": {
"main": [
[
{
"node": "Sort",
"type": "main",
"index": 0
}
]
]
},
"28ffac78-712b-4405-a9e7-161edfb4bce4": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "387d3cfb-7315-4d17-a528-09e9c1e0688c",
"type": "main",
"index": 0
}
]
]
},
"6c46f47f-ba78-490f-90eb-b5d6f4a5f7cf": {
"main": [
[
{
"node": "28ffac78-712b-4405-a9e7-161edfb4bce4",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "6c46f47f-ba78-490f-90eb-b5d6f4a5f7cf",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "7fbb8e78-78de-494e-b090-f1b1805c3714",
"type": "main",
"index": 0
}
]
]
},
"387d3cfb-7315-4d17-a528-09e9c1e0688c": {
"main": [
[
{
"node": "56501cf9-12bb-4e24-a27e-6d45d2b65c9d",
"type": "main",
"index": 0
}
]
]
},
"86e95eea-9e5c-4791-ac93-938daee1f480": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Intermédiaire - Réseaux sociaux, IA Multimodale
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Camille Roux
@camillerouxPartager ce workflow