AutomationFlowsAI & RAG › Automate Business Card Management with Line, Ai, and Google Sheets

Automate Business Card Management with Line, Ai, and Google Sheets

ByOka Hironobu @okp29 on n8n.io

This workflow is designed for business professionals and sales teams who receive business card images via LINE and want to quickly digitize contact information with minimal manual work.

Webhook trigger★★★★☆ complexityAI-powered19 nodesGoogle Gemini ChatHTTP RequestChain LlmGoogle SheetsGoogle DriveGmail
AI & RAG Trigger: Webhook Nodes: 19 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #12058 — we link there as the canonical source.

This workflow follows the Chainllm → Gmail recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "5zAPU5L5WdkEkB4N",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Extract business card info to Google Sheets with LINE and AI",
  "tags": [],
  "nodes": [
    {
      "id": "2fad63fd-4433-407e-b759-6bb893930171",
      "name": "Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -272,
        96
      ],
      "parameters": {
        "width": 508,
        "height": 409,
        "content": "## How it works\n1. Receive business card image via LINE webhook\n2. Extract text using Google Gemini AI\n3. Parse structured data (company, name, email, phone, etc.)\n4. Save to Google Sheets and upload image to Drive\n5. Send thank-you email and LINE confirmation\n\n## Setup steps\n1. Create LINE Messaging API channel and get Channel Access Token\n2. Set up Google Sheets with columns: Company Name, Contact Person, Department, Address, Email, Phone Number\n3. Create Google Drive folder for image storage\n4. Add your credentials in the Config node\n5. Set webhook URL in LINE Developer Console\n\n\u26a0\ufe0f Note: Processes one image per execution. Multiple images in one message are not supported."
      },
      "typeVersion": 1
    },
    {
      "id": "afc3a258-2988-4b82-b837-6c1bd6ae9750",
      "name": "Step 1 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 588,
        "height": 320,
        "content": "## Trigger & Config\nReceives LINE webhook events and loads configuration settings."
      },
      "typeVersion": 1
    },
    {
      "id": "3800f883-4e1e-40b9-bbff-0124f24d1b27",
      "name": "Step 2 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 704,
        "content": "## AI Processing\nDownloads image from LINE and extracts business card info using Gemini."
      },
      "typeVersion": 1
    },
    {
      "id": "1ca79a58-e64b-44f4-8dac-41e612048337",
      "name": "Step 3 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1264,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 1100,
        "height": 704,
        "content": "## Data Storage\nParses extracted text, uploads image to Drive, and saves data to Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "bca6ea4d-6e54-40c3-93cc-5eff08010505",
      "name": "Step 4 Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2384,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 396,
        "height": 704,
        "content": "## Notification\nSends thank-you email and replies to LINE with extracted info."
      },
      "typeVersion": 1
    },
    {
      "id": "12bcda0e-bf0e-4620-b9fa-762fd6bce1e9",
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "line_token",
              "name": "LINE_CHANNEL_ACCESS_TOKEN",
              "type": "string",
              "value": "YOUR_LINE_CHANNEL_ACCESS_TOKEN_HEREK8T2FaPR+xpbJyhxHV0TkWjTijbq6IUcJNmcVfUqZMY3og/eZ1Lw1sb9786bGzeiUA2zj/9GraOfpQdB04t89/1O/w1cDnyilFU="
            },
            {
              "id": "sheets_id",
              "name": "GOOGLE_SHEETS_ID",
              "type": "string",
              "value": "YOUR_GOOGLE_SHEETS_ID_HERE"
            },
            {
              "id": "drive_folder",
              "name": "GOOGLE_DRIVE_FOLDER_ID",
              "type": "string",
              "value": "YOUR_GOOGLE_DRIVE_FOLDER_ID_HERE"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "fef3f682-efa0-4690-977b-3e5ff2554af3",
      "name": "LINE Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        272,
        256
      ],
      "parameters": {
        "path": "/BusinessCard",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "d990bacc-ff90-4885-9397-b5e194277ea1",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        928,
        656
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d21403d1-5ea8-4708-9b30-edac6904f1f0",
      "name": "Check If Image",
      "type": "n8n-nodes-base.switch",
      "position": [
        736,
        256
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "1d9fe3c1-bebe-4a3a-9645-720c91e9ebbf",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('LINE Webhook').item.json.body.events[0].message.type }}",
                    "rightValue": "image"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.3
    },
    {
      "id": "dc37f2b3-7e59-4517-a6f0-aabf30fa2992",
      "name": "Download Image from LINE",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1008,
        256
      ],
      "parameters": {
        "url": "=https://api-data.line.me/v2/bot/message/{{ $('LINE Webhook').item.json.body.events[0].message.id }}/content",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Config').item.json.LINE_CHANNEL_ACCESS_TOKEN }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "9b07ef81-28e6-4217-8939-12bb259695bf",
      "name": "Extract Card Info",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        928,
        480
      ],
      "parameters": {
        "text": "Extract the following information from this business card image.\n\n\u3010IMPORTANT RULES\u3011\n- Use the exact key names listed below without any modification\n- Output each item in one line using the format \"Key: Value\"\n- Do not add bullets or numbers at the beginning of lines\n- If information cannot be extracted, output \"\u30fc\" (dash)\n- Do not add explanations or supplementary text\n- If no information can be extracted at all, only output \"Extraction Failed\"\n\n\u3010OUTPUT FORMAT\u3011\nCompany Name: \nContact Person: \nDepartment: \nAddress: \nEmail: \nPhone:",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "type": "HumanMessagePromptTemplate",
              "messageType": "imageBinary"
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "9be197a9-8832-4550-8bce-dac50c87d59f",
      "name": "Parse Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1552,
        304
      ],
      "parameters": {
        "jsCode": "// Input\nconst text =\n  $json?.text ??\n  $json?.data?.text ??\n  $input.first().json?.text ??\n  \"\";\n\n// 1) Normalize text\nconst normalize = (s) =>\n  String(s ?? \"\")\n    .trim()\n    .replace(/[\u30fb\u25cf\u25a0\u25c6\u25c7\u25b6\ufe0e]/g, \"\")        \n    .replace(/[\u3000\\t]+/g, \" \")           \n    .replace(/[\uff1a]/g, \":\")              \n    .replace(/[\uff08(].*?[\uff09)]/g, \"\")       \n    .trim();\n\nconst normKey = (k) =>\n  normalize(k)\n    .toLowerCase()\n    .replace(/\\s+/g, \"\");\n\n// 2) Key aliases mapping\nconst KEY_ALIASES = {\n  company: new Set([\n    \"company name\", \"company\", \"organization\", \"corporation\",\n    \"\u4f1a\u793e\u540d\",\"\u6cd5\u4eba\u540d\",\"\u4f01\u696d\u540d\",\"\u793e\u540d\",\"\u4f1a\u793e\",\"\u6cd5\u4eba\",\"\u4f01\u696d\"\n  ]),\n  name: new Set([\n    \"contact person\", \"name\", \"person\", \"full name\",\n    \"\u62c5\u5f53\u8005\u540d\",\"\u6c0f\u540d\",\"\u540d\u524d\",\"\u62c5\u5f53\u8005\"\n  ]),\n  department: new Set([\n    \"department\", \"division\", \"section\",\n    \"\u62c5\u5f53\u8005\u540d\u306e\u6240\u5c5e\u90e8\u7f72\u540d\",\"\u6240\u5c5e\u90e8\u7f72\",\"\u90e8\u7f72\",\"\u90e8\u9580\",\"\u6240\u5c5e\"\n  ]),\n  address: new Set([\n    \"address\", \"location\",\n    \"\u4f4f\u6240\",\"\u6240\u5728\u5730\"\n  ]),\n  email: new Set([\n    \"email\", \"e-mail\", \"mail\",\n    \"\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\",\"e\u30e1\u30fc\u30eb\",\"\u9023\u7d61\u5148\u30e1\u30fc\u30eb\"\n  ]),\n  phone: new Set([\n    \"phone\", \"telephone\", \"tel\", \"mobile\", \"cell\",\n    \"\u96fb\u8a71\u756a\u53f7\",\"\u643a\u5e2f\",\"\u9023\u7d61\u5148\",\"\u96fb\u8a71\"\n  ]),\n};\n\n// 3) Parse lines\nconst toLines = (t) =>\n  String(t)\n    .replace(/\\\\n/g, \"\\n\")\n    .split(/\\r?\\n/)\n    .map((l) => normalize(l))\n    .filter(Boolean);\n\nconst lines = toLines(text);\n\n// 4) Resolve key\nfunction resolveKey(rawKey) {\n  const nk = normKey(rawKey);\n\n  for (const [fixed, set] of Object.entries(KEY_ALIASES)) {\n    for (const alias of set) {\n      if (nk === normKey(alias)) return fixed;\n    }\n  }\n\n  if (nk.includes(\"tel\") || nk.includes(\"phone\") || nk.includes(\"mobile\") || nk.includes(\"\u643a\u5e2f\")) return \"phone\";\n  if (nk.includes(\"mail\")) return \"email\";\n  if (nk.includes(\"\u4f4f\u6240\") || nk.includes(\"\u6240\u5728\u5730\") || nk.includes(\"address\")) return \"address\";\n  if (nk.includes(\"\u4f1a\u793e\") || nk.includes(\"\u793e\u540d\") || nk.includes(\"company\")) return \"company\";\n  if (nk.includes(\"\u90e8\u7f72\") || nk.includes(\"department\") || nk.includes(\"division\")) return \"department\";\n  if (nk.includes(\"\u62c5\u5f53\") || nk.includes(\"\u6c0f\u540d\") || nk.includes(\"name\")) return \"name\";\n\n  return null;\n}\n\n// 5) Extract phone numbers\nfunction extractPhones(s) {\n  const str = String(s ?? \"\");\n  const matches = str.match(/\\b0\\d{1,4}[-\\s]?\\d{1,4}[-\\s]?\\d{3,4}\\b/g) ?? [];\n  const cleaned = matches\n    .map((p) => p.replace(/\\s+/g, \"-\"))\n    .map((p) => p.replace(/-+/g, \"-\"))\n    .map((p) => p.trim())\n    .filter(Boolean);\n\n  return Array.from(new Set(cleaned));\n}\n\nconst out = {\n  company: \"\",\n  name: \"\",\n  department: \"\",\n  address: \"\",\n  email: \"\",\n  phone: \"\",\n  phoneList: [],\n};\n\nfor (const line of lines) {\n  const m = line.match(/^(.+?):\\s*(.+)$/);\n  if (!m) continue;\n\n  const rawKey = m[1];\n  const value = m[2];\n\n  const fixed = resolveKey(rawKey);\n  if (!fixed) continue;\n\n  if (out[fixed]) continue;\n\n  out[fixed] = value;\n}\n\nconst phones = extractPhones(out.phone);\nout.phoneList = phones;\n\nif (phones.length) out.phone = phones.join(\" / \");\n\nif (out.email) out.email = String(out.email).trim().toLowerCase();\n\nfor (const k of Object.keys(out)) {\n  if (typeof out[k] === \"string\" && out[k].trim() === \"\") delete out[k];\n  if (Array.isArray(out[k]) && out[k].length === 0) delete out[k];\n}\n\nreturn [{ \n  json: out,\n  binary: $input.first().binary\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "1ef2af98-caef-4fe3-bc9b-15c271a6152f",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2224,
        208
      ],
      "parameters": {
        "columns": {
          "value": {
            "\u4f4f\u6240": "={{ $('Parse Data').item.json.address }}",
            "\u4f1a\u793e\u540d": "={{ $('Parse Data').item.json.company }}",
            "\u62c5\u5f53\u8005\u540d": "={{ $('Parse Data').item.json.name }}",
            "\u96fb\u8a71\u756a\u53f7": "={{ $('Parse Data').item.json.phoneList.join(\"/\") }}",
            "\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9": "={{ $('Parse Data').item.json.email }}",
            "\u62c5\u5f53\u8005\u306e\u6240\u5c5e\u90e8\u7f72\u540d": "={{ $('Parse Data').item.json.department }}"
          },
          "schema": [
            {
              "id": "\u4f1a\u793e\u540d",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u4f1a\u793e\u540d",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u62c5\u5f53\u8005\u540d",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u62c5\u5f53\u8005\u540d",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u62c5\u5f53\u8005\u306e\u6240\u5c5e\u90e8\u7f72\u540d",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u62c5\u5f53\u8005\u306e\u6240\u5c5e\u90e8\u7f72\u540d",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u4f4f\u6240",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u4f4f\u6240",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u96fb\u8a71\u756a\u53f7",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u96fb\u8a71\u756a\u53f7",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Config').item.json.GOOGLE_SHEETS_ID }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "df3c9ba2-ea61-4025-bb93-4594f8deab42",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1776,
        208
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3
    },
    {
      "id": "85f0b504-a3c0-44dd-9aca-aaedf07205b6",
      "name": "Notify Analysis Failed",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1552,
        576
      ],
      "parameters": {
        "url": "https://api.line.me/v2/bot/message/push",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"to\": \"{{ $('LINE Webhook').item.json.body.events[0].source.userId }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"Sorry, we were unable to read any information from your business card image. \\n\\nCould you please send us another image?\"\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Config').item.json.LINE_CHANNEL_ACCESS_TOKEN }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "8df1769e-bd52-4250-beec-d0d08d268b0d",
      "name": "Upload to Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2000,
        208
      ],
      "parameters": {
        "name": "={{ 'BusinessCard_' + $now.format('yyyyMMdd_HHmmss') }}.jpg",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "={{ $('Config').item.json.GOOGLE_DRIVE_FOLDER_ID }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "8056dc52-6da6-40c8-badb-654798bb1b2f",
      "name": "Reply to LINE",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2656,
        208
      ],
      "parameters": {
        "url": "https://api.line.me/v2/bot/message/push",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"to\": \"{{ $('LINE Webhook').item.json.body.events[0].source.userId }}\",\n  \"messages\": [\n    {\n      \"type\": \"text\",\n      \"text\": \"The following information has been extracted.\\nCompany: {{ $('Parse Data').item.json.company }}\\nContact Name: {{ $('Parse Data').item.json.name }}\\nDepartment: {{ $('Parse Data').item.json.department }}\\nAddress: {{ $('Parse Data').item.json.address }}\\nEmail: {{ $('Parse Data').item.json.email }}\\nPhone: {{ $('Parse Data').item.json.phoneList.join('/') }}\"\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Config').item.json.LINE_CHANNEL_ACCESS_TOKEN }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "cd7514ad-f719-46b5-8927-3cd315d1fac2",
      "name": "Send Thank You Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2432,
        208
      ],
      "parameters": {
        "sendTo": "={{ $json['\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9'] }}",
        "message": "=Dear {{ $json['\u62c5\u5f53\u8005\u540d'] }},\n\nIt was a pleasure meeting you today. Thank you very much for taking the time to exchange business cards with me.\n\nI truly appreciated learning more about your work and your insights. I hope we will have the opportunity to stay in touch and explore possible collaboration in the future.\n\nPlease feel free to contact me if you need any further information.\n\nBest regards,\n[Your Name]",
        "options": {},
        "subject": "Thank You for the Opportunity to Meet",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "8d532d8b-d4f9-4a21-a5f9-2862432c8a79",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        1280,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "412a45c2-b07c-45ed-a629-a5734cc6ca1a",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.text }}",
              "rightValue": "Extraction Failed"
            }
          ]
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "bfdf8229-ab5d-4cd7-bac0-5a2ffaf09d9f",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Parse Data",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Analysis Failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Upload to Google Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config": {
      "main": [
        [
          {
            "node": "Check If Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Data": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "LINE Webhook": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Image": {
      "main": [
        [
          {
            "node": "Download Image from LINE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Card Info": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Thank You Email": {
      "main": [
        [
          {
            "node": "Reply to LINE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Google Sheets": {
      "main": [
        [
          {
            "node": "Send Thank You Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Google Drive": {
      "main": [
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Image from LINE": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          },
          {
            "node": "Extract Card Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Extract Card Info",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow is designed for business professionals and sales teams who receive business card images via LINE and want to quickly digitize contact information with minimal manual work.

Source: https://n8n.io/workflows/12058/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

ANIS_HUB 1. Uses gmail, googleDrive, googleSheets, httpRequest. Webhook trigger; 89 nodes.

Gmail, Google Drive, Google Sheets +3
AI & RAG

Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses outputParserStructured, chainLlm, googleDrive, stickyNote. Webhook trigger; 67 nodes.

Output Parser Structured, Chain Llm, Google Drive +9
AI & RAG

Candidate Engagement | Resume Screening | AI Voice Interviews | Applicant Insights

Output Parser Structured, Chain Llm, Google Drive +9
AI & RAG

This workflow automates document processing using LlamaParse to extract and analyze text from various file formats. It intelligently processes documents, extracts structured data, and delivers actiona

Gmail, Gmail Trigger, HTTP Request +6
AI & RAG

Categories Content Creation AI Automation Publishing Social Media

Google Docs, HTTP Request, Slack +7