{
  "id": "LIlKipVzEu7mwctU",
  "name": "LEDGERS - Add Contact Using AI Prompt",
  "tags": [],
  "nodes": [
    {
      "id": "70f04b98-e2a8-42f3-bd4c-ac9c3ea7c016",
      "name": "Google Sheets Trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        -1984,
        128
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1920008147,
          "cachedResultUrl": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1m4lbSUudsxNI-thsPBZ1sjMU2yWLSQf0MrURDjBwIlg",
          "cachedResultUrl": "",
          "cachedResultName": ""
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4eb10391-8622-49ee-ba8f-27af4fd66a61",
      "name": "Create a contact",
      "type": "@ledgers/n8n-nodes-ledgers-cloud.ledgers",
      "position": [
        -1104,
        112
      ],
      "parameters": {
        "contactName": "={{ $json['output']['name'] }}",
        "additionalFields": {
          "pan": "={{ $json['output']['pan'] }}",
          "email": "={{ $json['output']['email'] }}",
          "gstin": "={{ $json['output']['gstin'] }}",
          "mobile": "={{ $json['output']['mobile'] }}",
          "business_name": "={{ $json['output']['business_name'] }}",
          "billing_address": {
            "billing_city": "={{ $json['output']['billing_city'] }}",
            "billing_email": "={{ $json['output']['billing_addr_email'] }}",
            "billing_gstin": "={{ $json['output']['billing_addr_gstin'] }}",
            "billing_state": "={{ $json['output']['billing_state'] }}",
            "billing_mobile": "={{ $json['output']['billing_addr_mobile'] }}",
            "billing_country": "={{ $json['output']['billing_country'] }}",
            "billing_pincode": "={{ $json['output']['billing_pincode'] }}",
            "billing_address1": "={{ $json['output']['billing_address1'] }}",
            "billing_address2": "={{ $json['output']['billing_address2'] }}"
          },
          "shipping_address": {
            "shipping_city": "={{ $json['output']['shipping_city'] }}",
            "shipping_email": "={{ $json['output']['shipping_addr_email'] }}",
            "shipping_gstin": "={{ $json['output']['shipping_addr_gstin'] }}",
            "shipping_state": "={{ $json['output']['shipping_state'] }}",
            "shipping_mobile": "={{ $json['output']['shipping_addr_mobile'] }}",
            "shipping_country": "={{ $json['output']['shipping_country'] }}",
            "shipping_pincode": "={{ $json['output']['shipping_pincode'] }}",
            "shipping_address1": "={{ $json['output']['shipping_address1'] }}",
            "shipping_address2": "={{ $json['output']['shipping_address2'] }}"
          },
          "mobile_country_code": "={{$json['output']['mobile_country_code']}}"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "98ed1623-d987-42e2-bcf4-b978d9ec17be",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2016,
        -304
      ],
      "parameters": {
        "width": 944,
        "height": 304,
        "content": "### This n8n workflow automatically creates contacts in LEDGERS using AI, based on data updates in a Google Sheet.\n\n\ud83d\udd01 Flow:\n1. **Google Sheets Trigger** \u2013 Watches for any row update.\n2. **OpenAI Chat Model** \u2013 Converts sheet row into contact creation format using a prompt.\n3. **Structured Output Parser** \u2013 Parses AI response into JSON.\n4. **Form Loop & Iteration** \u2013 Loops through fields to structure contact data.\n5. **Create a Contact** \u2013 Sends the structured contact to LEDGERS.\n6. **LEDGERS Loop & Iteration** \u2013 Handles multiple contact creations if needed.\n7. **Success/Failure** \u2013 Sends Gmail notification on contact creation success or failure.\n\n\ud83e\udd16 Use case:\nPerfect for teams that maintain contact info in Google Sheets and want AI to auto-parse and sync it to LEDGERS without manual entry."
      },
      "typeVersion": 1
    },
    {
      "id": "12a98d73-d906-47c9-94fd-83253e965a8f",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -1520,
        336
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"name\": \"\",\n  \"mobile_country_code\": \"\",\n  \"mobile\": \"\",\n  \"email\": \"\",\n  \"gstin\": \"\",\n  \"business_name\": \"\",\n  \"billing_address1\": \"\",\n  \"billing_address2\": \"\",\n  \"billing_city\": \"\",\n  \"billing_state\": \"\",\n  \"billing_country\": \"\",\n  \"shipping_address1\": \"\",\n  \"shipping_address2\": \"\",\n  \"shipping_city\": \"\",\n  \"shipping_state\": \"\",\n  \"shipping_country\": \"\",\n  \"billing_addr_email\": \"\",\n  \"billing_addr_mobile\": \"\",\n  \"billing_addr_gstin\": \"\",\n  \"shipping_addr_email\": \"\",\n  \"shipping_addr_mobile\": \"\",\n  \"shipping_addr_gstin\": \"\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "cb8c047e-8216-417e-a869-904e54ef8582",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1856,
        336
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "1617af28-52aa-4715-a44c-f32d1922754b",
      "name": "Contact Failed",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -416,
        192
      ],
      "parameters": {
        "message": "=### Sample EMAIL Template\n\n<h3>Your Contact Creation is Failed.</h3>\n\n<h6>Check the error message:</h6>\n<h2> {{ JSON.stringify($json, null, 2) }} </h2>",
        "options": {},
        "subject": "Regarding Create Contact via LEDGERS"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e375dc71-3347-4b1d-bc4a-99f2b0024eb4",
      "name": "Contact Success",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -416,
        0
      ],
      "parameters": {
        "message": "=### Sample EMAIL Template\n\n<h3>Your Contact Creation is Success.</h3>\n\n<h6>Check the Response</h6>\n<h2> {{ $json }} </h2>",
        "options": {
          "appendAttribution": true
        },
        "subject": "Regarding Create Contact via LEDGERS N8N"
      },
      "typeVersion": 2.1
    },
    {
      "id": "b4ff0a41-8ef1-4d36-aa97-9592a97b1aa5",
      "name": "Contact Create Smart AI",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1760,
        128
      ],
      "parameters": {
        "text": "=The following is a user-submitted JSON form. Your task is to clean and normalize it according to the specified rules and return it as a structured JSON object.\n\n### INPUT JSON:\n{{ JSON.stringify($json, null, 2) }}\n\n---\n\n### RULES:\n1. `name` is **required**. It may appear under keys like `\"Name\"`, `\"Customer Name\"`, `\"Contact Name\"`, `\"Consumer Name\"`, etc.\n2. If `mobile` is present:\n   - Extract the country code to `mobile_country_code`\n   - Extract the 10-digit number to `mobile`\n   - If no country code, default `mobile_country_code` to `+91`\n3. IF `\"email\"` is Present:\n     Validate `email` format. If invalid, include it in the `\"errors\"` object under `\"email\"` and don't include the value in `\"email\"`\n4. If GST or Tax Number or GSTIN is present, map it to `\"gstin\"` and if PAN or Permanent Account Number is present, map it to `\"pan\"`.\n5. Address:\n   - Normalize from fields like `\"Address Line 1\"`, `\"Address Line 2\"`, `\"City\"`, `\"State\"`, `\"Country\"`,`\"Pincode\"`\n   - Move any email, phone, GSTIN inside address fields to `billing_addr_email`, `billing_addr_mobile`, `billing_addr_gstin` and `shipping_addr_email`, `shipping_addr_mobile`, `shipping_addr_gstin`\n   - if 2 different address is present then move the address to `billing_address1`, `billing_address2`, `billing_city`, `billing_state`, `billing_country`, `billing_pincode` and `shipping_address1`, `shipping_address2`, `shipping_city`, `shipping_state`, `shipping_country`, `shipping_pincode`\n6. Ensure `\"state\"` and `\"country\"` are valid \u2014 if `\"state\"` is given in abbreviations give full form and return `\"state\"` and `\"country\"` in **UPPERCASE**\n7. `business_name` may appear as `\"Business Name\"` or similar \u2014 normalize it\n8. Log any invalid or missing required data inside `\"errors\"` as key-value pairs\n9. \u2757 **Do NOT generate or assume values. Only use data from the given input. Do NOT output placeholders like 'string', 'John Doe', or '123 Main St'. If data is missing, leave the field blank.**\n10. **Remember to store errors in `\"errors\"` object if any key gives `\"errors\"` then mention that key and value in error**\n\n---\n\n### REQUIRED OUTPUT FORMAT:\n```json\n{\n  \"name\": \"\",\n  \"mobile_country_code\": \"\",\n  \"mobile\": \"\",\n  \"email\": \"\",\n  \"gstin\": \"\",\n  \"pan\": \"\",\n  \"business_name\": \"\",\n  \"billing_address1\": \"\",\n  \"billing_address2\": \"\",\n  \"billing_city\": \"\",\n  \"billing_state\": \"\",\n  \"billing_country\": \"\",\n  \"billing_pincode\": \"\",\n  \"shipping_address1\": \"\",\n  \"shipping_address2\": \"\",\n  \"shipping_city\": \"\",\n  \"shipping_state\": \"\",\n  \"shipping_country\": \"\",\n  \"shipping_pincode\": \"\",\n  \"billing_addr_email\": \"\",\n  \"billing_addr_mobile\": \"\",\n  \"billing_addr_gstin\": \"\",\n  \"shipping_addr_email\": \"\",\n  \"shipping_addr_mobile\": \"\",\n  \"shipping_addr_gstin\": \"\",\n  \"errors\": {}\n}\n",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "095aceef-30c1-4cf1-b82a-b7723383c85a",
      "name": "Form Loop",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -1344,
        128
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "f4936bcb-04c3-4878-899f-b461cccc134f",
      "name": "LEDGERS Loop",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -864,
        112
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "4385d084-c2d1-4ac4-ae83-aacc238acad9",
      "name": "Form Iteration",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1328,
        352
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "44a6f11c-478f-434a-a094-e5785558d9aa",
      "name": "LEDGERS Iteration",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -848,
        336
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "565df44d-a75a-4099-8c4f-e8ec4477eee3",
      "name": "Success/Failure",
      "type": "n8n-nodes-base.if",
      "position": [
        -640,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "64f97f1d-a1d8-4eac-8c43-058ee2c81c35",
              "operator": {
                "type": "string",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json['errorMessage'] }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c1e545ea-bf2d-4e80-b4a3-1d12ed40c929",
  "connections": {
    "Form Loop": {
      "main": [
        [
          {
            "node": "Create a contact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Form Iteration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LEDGERS Loop": {
      "main": [
        [
          {
            "node": "Success/Failure",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "LEDGERS Iteration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form Iteration": {
      "main": [
        [
          {
            "node": "Form Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Success/Failure": {
      "main": [
        [
          {
            "node": "Contact Success",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Contact Failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create a contact": {
      "main": [
        [
          {
            "node": "LEDGERS Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LEDGERS Iteration": {
      "main": [
        [
          {
            "node": "LEDGERS Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Contact Create Smart AI",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Trigger": {
      "main": [
        [
          {
            "node": "Contact Create Smart AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Contact Create Smart AI": {
      "main": [
        [
          {
            "node": "Form Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Contact Create Smart AI",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}