iMessage food photo nutritional analysis (GPT-4 visual and memory storage)

Avancé

Ceci est unPersonal Productivity, AI Chatbotworkflow d'automatisation du domainecontenant 19 nœuds.Utilise principalement des nœuds comme If, Code, Webhook, Aggregate, HttpRequest. Analyse nutritionnelle des photos de nourriture iMessage (stockage visuel et mémoire GPT-4)

Prérequis
  • Point de terminaison HTTP Webhook (généré automatiquement par n8n)
  • Peut nécessiter les informations d'identification d'authentification de l'API cible
  • Clé API OpenAI
  • Informations de connexion à la base de données PostgreSQL
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "meta": {
    "instanceId": "9fe2e2e308ee9fa575b11a458a16465194c029a4f53a09a925eb0b5fa7b5761a",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "22f351db-4581-450b-a260-b50962f4f35a",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1220,
        0
      ],
      "parameters": {
        "width": 880,
        "height": 1000,
        "content": "## Using the n8n HTTP Request Node to Send a Blooio.com Message\n\nFollow these steps to configure your existing HTTP Request node in n8n so you can send SMS or email via the Blooio.com API.\n\n---\n\n### 1. Open Your HTTP Request Node\n\n- In your workflow, click on the HTTP Request node you’ve already added (e.g. **Send Message**).\n\n---\n\n### 2. Set Up the Request\n\n| Field                 | Value                                              |\n|-----------------------|----------------------------------------------------|\n| **Request Method**    | `POST`                                             |\n| **URL**               | `https://api.blooio.com/send-message`              |\n| **Response Format**   | `JSON`                                             |\n| **Body Content Type** | `JSON (application/json)`                          |\n\n---\n\n### 3. Add Required Headers\n\nAdd three headers exactly as shown:\n\n```text\nAccept:        application/json\nAuthorization: Bearer YOUR_API_TOKEN\nContent-Type:  application/json"
      },
      "typeVersion": 1
    },
    {
      "id": "334e086c-872b-4a75-8a33-aaec66ec3f02",
      "name": "Envoyer un message",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1280,
        780
      ],
      "parameters": {
        "url": "https://api.blooio.com/send-message",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "identifier",
              "value": "={{ $('Receive Message (From Blooio)').item.json.body.message.sender }}"
            },
            {
              "name": "message",
              "value": "={{ $json.output }}"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpBearerAuth": {
          "id": "WxjvtozS2uLOEBkw",
          "name": "Blooio Bearer Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d4df3023-17d3-44f1-bafd-1a70a370f98f",
      "name": "Note adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        980
      ],
      "parameters": {
        "color": 3,
        "width": 780,
        "height": 360,
        "content": "## Message Read Webhook:\n```\n{\n  \"type\": \"updated-message\",\n  \"message\": {\n    \"messageId\": \"218BCBB7-92E5-455B-AF47-380DB39ACD16\",\n    \"content\": \"Test\",\n    \"sender\": \"+11111111111\",\n    \"selfMessage\": true,\n    \"sentAt\": 1750755023004,\n    \"technology\": \"iMessage\",\n    \"delivered\": true,\n    \"deliveredAt\": 1750755023334,\n    \"readAt\": 1750755049887,\n    \"attachments\": [],\n    \"conversation\": null\n  }\n}\n```"
      },
      "typeVersion": 1
    },
    {
      "id": "9330aeee-82ed-4549-9927-c7802a809cd9",
      "name": "Note adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        380
      ],
      "parameters": {
        "color": 6,
        "width": 780,
        "height": 580,
        "content": "## Message Received Webhook:\n```\n{\n  \"type\": \"new-message\",\n  \"message\": {\n    \"messageId\": \"B525F710-521F-4D39-8C8F-A44BB737A3B6\",\n    \"content\": \"Attached the csv file for you\",\n    \"sender\": \"+11111111111\",\n    \"selfMessage\": false,\n    \"sentAt\": 1750757604774,\n    \"technology\": \"iMessage\",\n    \"delivered\": true,\n    \"deliveredAt\": null,\n    \"readAt\": null,\n    \"attachments\": [\n      {\n        \"id\": \"F933522B-8DC1-47DB-9274-7508B16D15BF\",\n        \"filename\": \"high_volume_b2b_laser_cnc_products.csv\",\n        \"mimeType\": \"text/csv\",\n        \"url\": \"https://bucket.blooio.com/custom-webhook-attachments/-xxxx.csv\",\n        \"size\": 1962,\n        \"expiresAt\": \"2025-07-24T09:33:26.934Z\",\n        \"expiresAtUnix\": 1753349606934\n      }\n    ],\n    \"conversation\": {\n      \"id\": \"iMessage;-;+11111111111\",\n      \"recipient\": \"+11111111111\",\n      \"name\": null\n    }\n  }\n}\n```"
      },
      "typeVersion": 1
    },
    {
      "id": "b7a92947-9617-4639-8c1a-b80242bb3571",
      "name": "Agent IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -160,
        780
      ],
      "parameters": {
        "text": "=User message: {{ $('Receive Message (From Blooio)').item.json.body.message.content }}",
        "options": {
          "systemMessage": "<identity>\nYou are a world-class AI Nutrition Analyst trained to estimate nutrition from food photos using visual analysis, expert knowledge, and common food portion assumptions.\n</identity>\n\n<mission>\nYour task is to analyze a single food photo and provide a complete nutritional summary, without asking the user for any additional information. You must visually identify all items, estimate portion sizes, and calculate total calories and nutrients. Your response should be accurate, clear, and formatted as a friendly iMessage-style explanation — no JSON, no technical markup.\n\n</mission>\n\n<analysis_protocol>\n1. **Identify** all foods and beverages in the image.\n2. **Estimate** portion sizes using visual cues and standard serving sizes.\n3. **Calculate** total:\n   - Calories\n   - Protein\n   - Carbs\n   - Fat\n   - Fiber\n   - Sugar\n   - Sodium\n4. **Score**:\n   - Confidence Score (0.0 to 1.0): How sure you are based on image clarity, food visibility, and assumptions.\n   - Health Score (0 to 10): Nutritional quality based on processing, balance, and content.\n\n</analysis_protocol>\n\n<response_format>\nRespond in a conversational tone. Start by describing the identified meal. Then list the estimated nutrition facts in simple bullet points. Finally, include:\n- A health rating from 0–10.\n- A confidence rating from 0.0–1.0.\n- A short, friendly rationale for your estimate and assumptions.\n\n⚠️ Do NOT ask the user for input or confirmation.\n⚠️ Do NOT include JSON, markdown, or structured code output.\n⚠️ Speak as if you're texting back a friend with a nutrition summary.\n\nGive the user a day report so far, a week report so far and a month report so far.</response_format>\n\n<error_handling>\nIf the image is unclear or does not show food, reply kindly to get the user to upload a different image or images.\n</error_handling>",
          "passthroughBinaryImages": true
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "79696185-e706-4c36-83c1-8f7294f5ec8b",
      "name": "OpenAI Modèle de Chat",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -160,
        960
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "JrqIdyKAvwxNgaEM",
          "name": "Tay - SLUG"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cc4c91c1-aacc-4a43-a530-5f902cb4274f",
      "name": "Mémoire de Chat Postgres",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "position": [
        -160,
        1120
      ],
      "parameters": {
        "tableName": "n8n_calorie_tracker",
        "sessionKey": "={{ $('Receive Message (From Blooio)').item.json.body.message.conversation.id }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 200
      },
      "credentials": {
        "postgres": {
          "id": "asiZOOtRYUAuWsWd",
          "name": "Neon"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "3860f4f4-1af7-4951-a52c-3d7c7f07cb9a",
      "name": "Recevoir un message (Depuis Blooio)",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1440,
        760
      ],
      "webhookId": "00dbce9f-70b6-4e2d-9da4-ba8747f95e5b",
      "parameters": {
        "path": "receive-event",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "40a29005-81ce-4fea-9572-230d27a79894",
      "name": "HTTP Requête",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        400,
        400
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "7b06c8a8-c330-45bc-a3a1-5dd1353b8603",
      "name": "Si images, les télécharger",
      "type": "n8n-nodes-base.if",
      "position": [
        -700,
        760
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "551f9536-48c3-4757-a58b-35ee1ef81a80",
              "operator": {
                "type": "array",
                "operation": "lengthGt",
                "rightType": "number"
              },
              "leftValue": "={{ $('Receive Message (From Blooio)').item.json.body.message.attachments }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e3bb4c52-b673-4d97-b9b5-e980349366ec",
      "name": "Boucle sur les éléments",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        40,
        380
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "f14e056e-2756-4ed9-8233-61fb4a86ee62",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        -280,
        380
      ],
      "parameters": {
        "jsCode": "let output = [];\n\nfor (const item of $input.first().json.body.message.attachments) {\n  output.push({\n    json: {\n      url: item.url\n    }\n  });\n}\n\nreturn output;"
      },
      "typeVersion": 2
    },
    {
      "id": "4bd4284d-fafe-4aca-976e-c822a8170823",
      "name": "Agent IA1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        600,
        780
      ],
      "parameters": {
        "text": "={{ $json.data.toJsonString() }}",
        "options": {
          "systemMessage": "Summarize these messages and give the user a report that will be send in an iMessage. Do not say \"here's the summary\" or anything like that. Just respond with the summary by itself."
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "274b2815-92bf-4a8a-bcd6-98fdb977dfa0",
      "name": "Agréger",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        260,
        780
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "ddc20f94-42a0-4227-ad11-afb0feb34db5",
      "name": "OpenAI Modèle de Chat1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        620,
        940
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "JrqIdyKAvwxNgaEM",
          "name": "Tay - SLUG"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "21264d57-60f5-4594-b450-07662078b23e",
      "name": "Ne pas répondre à soi-même",
      "type": "n8n-nodes-base.if",
      "position": [
        -960,
        760
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cecd3adf-a9e5-41d3-87ae-4a9699bd641b",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.message.selfMessage }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a098d03a-a4af-4b9a-aac2-5f5b57fd30e0",
      "name": "Note adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -360,
        260
      ],
      "parameters": {
        "color": 4,
        "width": 980,
        "height": 400,
        "content": "## Image downloader \n"
      },
      "typeVersion": 1
    },
    {
      "id": "4a009bbd-4457-4bc9-8a03-9de40736f931",
      "name": "Note adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        -700
      ],
      "parameters": {
        "width": 760,
        "height": 1040,
        "content": "## 🚀 Start Here: Blooio Nutrition Tracker Setup\n\nWelcome! Before this n8n workflow can analyze meal photos and send nutrition summaries via SMS or iMessage, follow these steps to get set up:\n\n---\n\n### ✅ Step 1: Get Your Blooio API Token\n1. Visit [https://blooio.com](https://blooio.com)\n2. Sign up for a dedicated instance\n3. Navigate to **Settings → API Keys**\n4. Generate a new token and **copy** it.\n\n> 🔐 Keep it safe! You’ll paste it in the HTTP Request node where it says `YOUR_API_TOKEN`.\n\n---\n\n### ✅ Step 2: Connect Blooio to This Workflow\nIn the **Send Message** node:\n- Replace the value of the `Authorization` header with:\n\n\n### ✅ Step 3: Test the Webhook\nSend an iMessage with a meal photo or description to your Blooio-connected number.\n\nThis will:\n- Trigger the `Receive Message (From Blooio)` webhook\n- Analyze the meal using AI\n- Return a nutrition breakdown with daily/weekly/monthly stats\n\n---\n\n### 📷 What You Can Send\n- Meal photos (ideal!)\n- Text descriptions of meals\n- Multiple items in one image\n\nEnjoy tracking your nutrition effortlessly! 🥦📊📩"
      },
      "typeVersion": 1
    },
    {
      "id": "eb88206b-19c3-41cb-a409-2b924c780852",
      "name": "Note adhésive5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1220,
        -700
      ],
      "parameters": {
        "width": 680,
        "height": 1040,
        "content": "![Description](https://i.imgur.com/bOPrv4H.png)\n"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {
    "Receive Message (From Blooio)": [
      {
        "body": {
          "type": "new-message",
          "message": {
            "readAt": null,
            "sender": "+11111111111",
            "sentAt": 1751234680604,
            "content": "And a Diet Coke",
            "delivered": true,
            "messageId": "6409C11D-9C0B-404B-B2E3-052DA7C14D07",
            "technology": "iMessage",
            "attachments": [
              {
                "id": "E843680B-8F00-460C-A0AA-34B1B1DD9624",
                "url": "https://bucket.blooio.com/custom-webhook-attachments/R3ZJISuC-t9CssQNM3i2J.jpeg",
                "size": 979912,
                "filename": "Pasta.jpeg",
                "mimeType": "image/jpeg",
                "expiresAt": "2025-07-29T22:04:42.432Z",
                "expiresAtUnix": 1753826682432
              }
            ],
            "deliveredAt": null,
            "selfMessage": false,
            "conversation": {
              "id": "iMessage;-;+11111111111",
              "name": null,
              "recipient": "+11111111111"
            }
          }
        },
        "query": {},
        "params": {},
        "headers": {
          "host": "workflows.xx.com",
          "cf-ray": "9578b8a804fa2f17-LAX",
          "cdn-loop": "cloudflare; loops=1; subreqs=1",
          "cf-ew-via": "15",
          "cf-worker": "blooio.com",
          "cf-visitor": "{\"scheme\":\"https\"}",
          "cf-ipcountry": "US",
          "content-type": "application/json",
          "content-length": "622",
          "accept-encoding": "gzip, br",
          "x-forwarded-for": "162.158.91.171",
          "cf-connecting-ip": "2a06:98c0:3600::103",
          "x-forwarded-host": "workflows.xx.com",
          "x-forwarded-proto": "https"
        },
        "webhookUrl": "https://workflows.xx.com/webhook/receive-event",
        "executionMode": "production"
      }
    ]
  },
  "connections": {
    "f14e056e-2756-4ed9-8233-61fb4a86ee62": {
      "main": [
        [
          {
            "node": "e3bb4c52-b673-4d97-b9b5-e980349366ec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b7a92947-9617-4639-8c1a-b80242bb3571": {
      "main": [
        [
          {
            "node": "274b2815-92bf-4a8a-bcd6-98fdb977dfa0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4bd4284d-fafe-4aca-976e-c822a8170823": {
      "main": [
        [
          {
            "node": "334e086c-872b-4a75-8a33-aaec66ec3f02",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "274b2815-92bf-4a8a-bcd6-98fdb977dfa0": {
      "main": [
        [
          {
            "node": "4bd4284d-fafe-4aca-976e-c822a8170823",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "40a29005-81ce-4fea-9572-230d27a79894": {
      "main": [
        [
          {
            "node": "e3bb4c52-b673-4d97-b9b5-e980349366ec",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e3bb4c52-b673-4d97-b9b5-e980349366ec": {
      "main": [
        [
          {
            "node": "b7a92947-9617-4639-8c1a-b80242bb3571",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "40a29005-81ce-4fea-9572-230d27a79894",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "79696185-e706-4c36-83c1-8f7294f5ec8b": {
      "ai_languageModel": [
        [
          {
            "node": "b7a92947-9617-4639-8c1a-b80242bb3571",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "ddc20f94-42a0-4227-ad11-afb0feb34db5": {
      "ai_languageModel": [
        [
          {
            "node": "4bd4284d-fafe-4aca-976e-c822a8170823",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "cc4c91c1-aacc-4a43-a530-5f902cb4274f": {
      "ai_memory": [
        [
          {
            "node": "b7a92947-9617-4639-8c1a-b80242bb3571",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "21264d57-60f5-4594-b450-07662078b23e": {
      "main": [
        [
          {
            "node": "7b06c8a8-c330-45bc-a3a1-5dd1353b8603",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7b06c8a8-c330-45bc-a3a1-5dd1353b8603": {
      "main": [
        [
          {
            "node": "f14e056e-2756-4ed9-8233-61fb4a86ee62",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "b7a92947-9617-4639-8c1a-b80242bb3571",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3860f4f4-1af7-4951-a52c-3d7c7f07cb9a": {
      "main": [
        [
          {
            "node": "21264d57-60f5-4594-b450-07662078b23e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

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é ?

Avancé - Productivité personnelle, Chatbot IA

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.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds19
Catégorie2
Types de nœuds10
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34