{
  "id": "DpGGOD1h7fXRgFN8",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI-Powered Make.com to n8n Workflow Migration Engine",
  "tags": [],
  "nodes": [
    {
      "id": "31d6969a-9e52-4fd9-8c90-525820db4fd6",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1600,
        1344
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "cbbf343a-1abf-4d8a-8143-0d8081b8450e",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2336,
        624
      ],
      "parameters": {
        "width": 572,
        "height": 492,
        "content": "## \ud83d\udd04 Make.com to n8n Workflow Converter\n\n### How it works\nThis workflow automates the conversion of Make.com blueprint JSON files into fully importable n8n workflow exports. It scans a Google Drive folder for a specific blueprint file, downloads and parses it, then sends it to an AI agent that intelligently maps Make.com modules to their n8n equivalents. The cleaned output is saved to a Google Sheet for review and reuse.\n\n### Setup steps\n1. **Connect credentials** \u2014 Add your Google Drive OAuth2, Google Sheets OAuth2, and Azure OpenAI API credentials in n8n's credential manager.\n2. **Point to your Drive folder** \u2014 In the *Search Files and Folders* node, configure the folder or drive you want to scan for blueprint files.\n3. **Update the file filter** \u2014 In the *Filter Target Blueprint* node, update the filename string to match your Make.com export file.\n4. **Set your output Sheet** \u2014 In the *Save Converted Workflow* node, update the Google Spreadsheet ID and sheet name to your own.\n5. **Test run** \u2014 Click *Execute Workflow* manually to verify the full pipeline end-to-end before automating."
      },
      "typeVersion": 1
    },
    {
      "id": "9dcb06a2-3568-4d84-8ed9-949a75f6e1f9",
      "name": "Trigger & File Discovery Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1648,
        1136
      ],
      "parameters": {
        "color": 7,
        "width": 636,
        "height": 408,
        "content": "## \ud83d\udcc1 Trigger & File Discovery\nStarts on manual execution, scans Google Drive for available files, and filters down to the specific Make.com blueprint you want to convert. Only matching files proceed to download."
      },
      "typeVersion": 1
    },
    {
      "id": "b3741feb-c80a-4c42-b9e6-be894c1b6544",
      "name": "Download & Parse Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        1104
      ],
      "parameters": {
        "color": 7,
        "width": 412,
        "height": 404,
        "content": "## \ud83d\udce5 Download & Parse Blueprint\nDownloads the matched blueprint file from Google Drive and extracts its JSON content so it can be passed into the AI conversion agent."
      },
      "typeVersion": 1
    },
    {
      "id": "7f887825-a2b6-4c0d-80b2-87fff9529fce",
      "name": "AI Conversion Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        1040
      ],
      "parameters": {
        "color": 7,
        "width": 644,
        "height": 680,
        "content": "## \ud83e\udd16 AI Conversion Agent\nThe Azure OpenAI-powered agent receives the Make.com JSON and converts it into a valid n8n workflow structure \u2014 mapping modules, connections, and node types according to strict n8n schema rules."
      },
      "typeVersion": 1
    },
    {
      "id": "de7b1f47-32b5-48b7-bc4a-c1e28d4cab71",
      "name": "Cleanup & Transform Section",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        1104
      ],
      "parameters": {
        "color": 7,
        "width": 444,
        "height": 456,
        "content": "## \ud83d\udee0\ufe0f Workflow Cleanup & Transform\nTwo code nodes clean up and normalize the AI output \u2014 fixing IF node conditions, resolving ID-to-name mappings in connections, stripping Make-specific fields, and ensuring the JSON is directly importable into n8n without edits."
      },
      "typeVersion": 1
    },
    {
      "id": "b0a757a6-2017-4611-a223-a178a294c48c",
      "name": "Credentials & Security",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        1360
      ],
      "parameters": {
        "color": 3,
        "width": 300,
        "height": 192,
        "content": "## \ud83d\udd10 Credentials & Security\nUse OAuth2 for Google Drive and Google Sheets. Use a scoped Azure OpenAI deployment key. Avoid hardcoding credentials \u2014 always use n8n's built-in credential manager."
      },
      "typeVersion": 1
    },
    {
      "id": "7454bcd7-a743-4d6f-8522-9164e2cb9436",
      "name": "Convert Blueprint with AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueErrorOutput",
      "position": [
        -400,
        1328
      ],
      "parameters": {
        "text": "=={{ JSON.stringify($json.data) }}",
        "options": {
          "systemMessage": "You are a senior n8n core workflow architect and JSON schema expert.\n\nYour task:\nConvert the provided Make.com blueprint JSON into a fully valid, directly importable n8n workflow export JSON.\n\nCRITICAL OUTPUT RULES:\n- Output ONLY raw JSON.\n- No markdown.\n- No explanations.\n- No comments.\n- No surrounding text.\n- Do NOT wrap the JSON inside \"output\".\n- Do NOT stringify the JSON.\n- Return a JSON object, not a string.\n- If anything other than pure JSON is returned, the answer is invalid.\n\nREQUIRED FINAL STRUCTURE:\n{\n  \"name\": \"string\",\n  \"nodes\": [],\n  \"connections\": {},\n  \"active\": false,\n  \"settings\": {},\n  \"versionId\": \"1\"\n}\n\nSTRICT NODE RULES:\nEach node MUST include:\n- id (string)\n- name (string)\n- type (valid n8n node type)\n- typeVersion (number)\n- position ([x, y])\n- parameters (object)\n\nSTRICT CONNECTION RULES:\n- The connections object MUST use NODE NAMES as keys.\n- NEVER use node IDs as connection keys.\n- Each connection MUST include:\n  {\n    \"node\": \"Target Node Name\",\n    \"type\": \"main\",\n    \"index\": 0\n  }\n- The \"type\" field inside connections MUST always be \"main\".\n- NEVER use \"start\", \"then\", \"else\", \"true\", or \"false\".\n- Branching is defined by array position:\n  - main[0] = true branch\n  - main[1] = false branch\n\nIF NODE RULES:\n- When comparing text, use:\n  \"conditions\": {\n    \"string\": [\n      {\n        \"value1\": \"={{$json[\\\"FieldName\\\"]}}\",\n        \"operation\": \"equal\",\n        \"value2\": \"SomeValue\"\n      }\n    ]\n  }\n- NEVER use \"boolean\" for text comparisons.\n- NEVER use \"property\" format.\n\nEXPRESSION RULES:\n- Always use valid n8n expressions:\n  ={{$json[\"FieldName\"]}}\n- Field names must match spreadsheet headers when possible.\n- Do NOT escape expressions incorrectly.\n\nMODULE MAPPING RULES:\n- google-sheets:watchRows \u2192 n8n-nodes-base.googleSheetsTrigger\n- builtin:BasicRouter \u2192 n8n-nodes-base.if\n- microsoft-email:createAndSendAMessage \u2192 n8n-nodes-base.microsoftOutlook\n\nGENERAL RULES:\n- Ensure every node is connected end-to-end.\n- No orphan nodes.\n- Positions should flow left to right (0,0 \u2192 300,0 \u2192 600,0).\n- Make reasonable assumptions if information is missing.\n- The result must import into n8n without modification.\n\nIf the output violates any of these constraints, it is invalid.\nReturn JSON only."
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "50f69122-4944-45ea-9dc0-d717a3ee5957",
      "name": "Normalize Connections and Conditions",
      "type": "n8n-nodes-base.code",
      "position": [
        48,
        1312
      ],
      "parameters": {
        "jsCode": "let workflow = $json;\n\n// If AI wrapped JSON as string inside \"output\"\nif (workflow.output && typeof workflow.output === \"string\") {\n  workflow = JSON.parse(workflow.output);\n}\n\n// Ensure required root fields\nworkflow.active = workflow.active ?? false;\nworkflow.settings = workflow.settings ?? {};\nworkflow.versionId = workflow.versionId ?? \"1\";\n\n// Build ID \u2192 Name map\nconst idToName = {};\nworkflow.nodes.forEach(n => {\n  idToName[n.id] = n.name;\n});\n\n// --- FIX IF CONDITIONS ---\nworkflow.nodes.forEach(node => {\n  if (node.type === \"n8n-nodes-base.if\" && node.parameters?.conditions) {\n    const cond = node.parameters.conditions;\n\n    // Convert boolean \u2192 string automatically\n    if (cond.boolean) {\n      cond.string = cond.boolean;\n      delete cond.boolean;\n    }\n\n    // Force correct structure\n    if (cond.string && Array.isArray(cond.string)) {\n      cond.string = cond.string.map(c => ({\n        value1: c.value1 || c.property || \"\",\n        operation: c.operation || \"equal\",\n        value2: c.value2 || \"\"\n      }));\n    }\n  }\n});\n\n// --- FIX CONNECTIONS ---\nconst newConnections = {};\n\nObject.keys(workflow.connections || {}).forEach(key => {\n  const fromName = idToName[key] || key;\n  const originalMain = workflow.connections[key].main || [];\n\n  newConnections[fromName] = { main: [] };\n\n  // Force 2D structure\n  const branches = Array.isArray(originalMain[0])\n    ? originalMain\n    : originalMain.map(b => [b]);\n\n  branches.forEach((branch, branchIndex) => {\n    newConnections[fromName].main[branchIndex] = [];\n\n    branch.forEach(conn => {\n      newConnections[fromName].main[branchIndex].push({\n        node: idToName[conn.node] || conn.node,\n        type: \"main\",\n        index: 0\n      });\n    });\n  });\n});\n\nworkflow.connections = newConnections;\n\nreturn [{ json: workflow }];"
      },
      "typeVersion": 2
    },
    {
      "id": "0a3ee706-502d-4706-9fba-74bad38d512d",
      "name": "Strip Make Fields and Finalize",
      "type": "n8n-nodes-base.code",
      "position": [
        304,
        1312
      ],
      "parameters": {
        "jsCode": "let workflow = $json;\n\n// If wrapped inside array\nif (Array.isArray(workflow)) {\n  workflow = workflow[0];\n}\n\n// If wrapped inside \"output\" string\nif (workflow.output && typeof workflow.output === \"string\") {\n  workflow = JSON.parse(workflow.output);\n}\n\n// Remove Make-specific fields and unstable fields\nworkflow.nodes.forEach(node => {\n  if (node.parameters && node.parameters.__IMTCONN__) {\n    delete node.parameters.__IMTCONN__;\n  }\n\n  // Remove typeVersion to avoid version mismatch errors\n  if (node.typeVersion) {\n    delete node.typeVersion;\n  }\n});\n\n// Remove optional fields that can cause import mismatch\ndelete workflow.active;\ndelete workflow.settings;\ndelete workflow.versionId;\n\n// Ensure connections exist\nworkflow.connections = workflow.connections || {};\n\n// Return CLEAN object (not array)\nreturn [\n  {\n    json: workflow\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "8cda5546-0a9a-4ce5-8b3b-dd0485c567f1",
      "name": "Azure OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        -416,
        1536
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "85a9abe1-3fc0-4892-ae3d-90722b57aa95",
      "name": "Search Files and Folders",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -1344,
        1344
      ],
      "parameters": {
        "filter": {},
        "options": {},
        "resource": "fileFolder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "4a5f3f6b-feba-4d4a-8dc0-f4b6c25738d8",
      "name": "Download Blueprint File",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -864,
        1328
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "a0ab9b33-f64c-49cd-bb08-d13cd983d42b",
      "name": "Filter Target Blueprint",
      "type": "n8n-nodes-base.if",
      "position": [
        -1136,
        1344
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0f26f1d2-cd56-4e4c-8caa-2282db3346b8",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.name }}",
              "rightValue": "blueprint"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "d7e542c8-78ee-4621-be11-73ae6378473b",
      "name": "Extract JSON from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -656,
        1328
      ],
      "parameters": {
        "options": {},
        "operation": "fromJson"
      },
      "typeVersion": 1.1
    },
    {
      "id": "e99a1898-8f72-4ced-803d-7eb4b04ba94b",
      "name": "Save Converted Workflow to Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        512,
        1312
      ],
      "parameters": {
        "columns": {
          "value": {
            "json": "={{ $('Convert Blueprint with AI Agent').item.json.output }}"
          },
          "schema": [
            {
              "id": "json",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "json",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "json"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "json",
          "cachedResultName": "json"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SPREADSHEET_ID_HERE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID_HERE/edit",
          "cachedResultName": "sample_leads_50"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "261187ba-3882-4808-869c-78fcd1aa2abf",
  "connections": {
    "Extract JSON from File": {
      "main": [
        [
          {
            "node": "Convert Blueprint with AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Convert Blueprint with AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Download Blueprint File": {
      "main": [
        [
          {
            "node": "Extract JSON from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Target Blueprint": {
      "main": [
        [
          {
            "node": "Download Blueprint File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Files and Folders": {
      "main": [
        [
          {
            "node": "Filter Target Blueprint",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Strip Make Fields and Finalize": {
      "main": [
        [
          {
            "node": "Save Converted Workflow to Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Blueprint with AI Agent": {
      "main": [
        [
          {
            "node": "Normalize Connections and Conditions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Connections and Conditions": {
      "main": [
        [
          {
            "node": "Strip Make Fields and Finalize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Search Files and Folders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}