This workflow corresponds to n8n.io template #15701 — we link there as the canonical source.
This workflow follows the Agent → 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 →
{
"id": "lWffHWaTokM7diXl",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Scan business cards with Gemini AI, log contacts to Google Sheets and Calendar",
"tags": [],
"nodes": [
{
"id": "8004dfdd-3aa2-447e-9d99-5209b69fcb05",
"name": "New Card in Drive",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
640,
768
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "id",
"value": "YOUR_FOLDER_ID",
"cachedResultName": "Business Cards"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "e922b8f2-8577-4454-99c9-8b3926b7a88e",
"name": "Download Card Image",
"type": "n8n-nodes-base.googleDrive",
"position": [
864,
768
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}",
"cachedResultName": "Card Image"
},
"options": {},
"operation": "download"
},
"typeVersion": 3
},
{
"id": "fdde13cf-ef72-4c2c-bf2a-58a3c20bd45f",
"name": "Gemini 2.5 Flash",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1104,
992
],
"parameters": {
"options": {
"temperature": 0.1
},
"modelName": "models/gemini-2.5-flash"
},
"typeVersion": 1.1
},
{
"id": "57bc08d4-f78d-4fd9-bde8-3c6015b96855",
"name": "Contact Data Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1232,
992
],
"parameters": {
"jsonSchemaExample": "{\n \"full_name\": \"Taro Yamada\",\n \"full_name_reading\": \"\u30e4\u30de\u30c0 \u30bf\u30ed\u30a6\",\n \"company\": \"Acme Corporation\",\n \"department\": \"Marketing Division\",\n \"job_title\": \"Senior Manager\",\n \"email\": \"user@example.com\",\n \"phone\": \"03-1234-5678\",\n \"mobile\": \"090-1234-5678\",\n \"fax\": \"03-1234-5679\",\n \"postal_code\": \"150-0001\",\n \"address\": \"1-2-3 Shibuya, Shibuya-ku, Tokyo\",\n \"website\": \"https://acme.co.jp\",\n \"notes\": \"\",\n \"confidence\": \"high\"\n}"
},
"typeVersion": 1.2
},
{
"id": "5aaed7bb-83ca-4d3b-9acc-b7dc5e9abae7",
"name": "Extract Contact Info",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1088,
768
],
"parameters": {
"text": "=You are a business card OCR specialist. Analyze the attached business card image and extract all contact information.\n\nExtract the following fields with high accuracy:\n- full_name: Full name as printed on the card\n- full_name_reading: Reading/pronunciation in katakana (for Japanese names) or leave empty\n- company: Company or organization name\n- department: Department or division\n- job_title: Job title or position\n- email: Email address\n- phone: Office phone number (keep original format with hyphens)\n- mobile: Mobile phone number (keep original format)\n- fax: Fax number if present\n- postal_code: Postal/ZIP code\n- address: Full address\n- website: Website URL\n- notes: Any other relevant information (e.g. qualifications, social media)\n- confidence: \"high\", \"medium\", or \"low\" based on image quality and readability\n\nRules:\n- For Japanese business cards, extract both kanji name and reading if available\n- Keep phone numbers in their original format (e.g. 03-1234-5678)\n- If a field is not present on the card, use an empty string\n- Set confidence to \"low\" if the image is blurry or partially unreadable",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.9
},
{
"id": "1f2f99fa-42fa-452a-b404-d1c516a98a4e",
"name": "Valid Extraction?",
"type": "n8n-nodes-base.if",
"position": [
1440,
768
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-name",
"operator": {
"type": "string",
"operation": "notEmpty"
},
"leftValue": "={{ $json.output.full_name }}",
"rightValue": ""
},
{
"id": "cond-confidence",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.output.confidence }}",
"rightValue": "low"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "1530997a-f8aa-4e79-be8f-7a2dd2178511",
"name": "Save to Contact Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
1664,
672
],
"parameters": {
"columns": {
"value": {
"Fax": "={{ $('Extract Contact Info').item.json.output.fax }}",
"Email": "={{ $('Extract Contact Info').item.json.output.email }}",
"Notes": "={{ $('Extract Contact Info').item.json.output.notes }}",
"Phone": "={{ $('Extract Contact Info').item.json.output.phone }}",
"Mobile": "={{ $('Extract Contact Info').item.json.output.mobile }}",
"Address": "={{ $('Extract Contact Info').item.json.output.address }}",
"Company": "={{ $('Extract Contact Info').item.json.output.company }}",
"Reading": "={{ $('Extract Contact Info').item.json.output.full_name_reading }}",
"Website": "={{ $('Extract Contact Info').item.json.output.website }}",
"Full Name": "={{ $('Extract Contact Info').item.json.output.full_name }}",
"Job Title": "={{ $('Extract Contact Info').item.json.output.job_title }}",
"Department": "={{ $('Extract Contact Info').item.json.output.department }}",
"Scanned At": "={{ $now.toISO() }}",
"Postal Code": "={{ $('Extract Contact Info').item.json.output.postal_code }}",
"Source File": "={{ $('New Card in Drive').item.json.name }}"
},
"schema": [
{
"id": "Full Name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Full Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Reading",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Reading",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Company",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Company",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Department",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Department",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Job Title",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Job Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Phone",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Phone",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Mobile",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Mobile",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Fax",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Fax",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Postal Code",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Postal Code",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Address",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Address",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Website",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Website",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Source File",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Source File",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Scanned At",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Scanned At",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Contacts"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SPREADSHEET_ID",
"cachedResultName": "Business Card Contacts"
}
},
"typeVersion": 4.5
},
{
"id": "15b84536-6ed0-48fb-8d47-52e58d347a3b",
"name": "Schedule Follow-up",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1888,
672
],
"parameters": {
"end": "={{ $now.plus({week: 1}).plus({hour: 1}).toISO() }}",
"start": "={{ $now.plus({week: 1}).toISO() }}",
"calendar": {
"__rl": true,
"mode": "id",
"value": "primary",
"cachedResultName": "Primary Calendar"
},
"remindersUi": {
"remindersValues": [
{
"method": "popup",
"minutes": 1440
},
{
"method": "popup",
"minutes": 60
}
]
},
"additionalFields": {
"color": "9",
"summary": "=Follow up: {{ $('Extract Contact Info').item.json.output.full_name }} @ {{ $('Extract Contact Info').item.json.output.company }}",
"description": "=Follow-up reminder for new contact.\n\nName: {{ $('Extract Contact Info').item.json.output.full_name }}\nCompany: {{ $('Extract Contact Info').item.json.output.company }}\nTitle: {{ $('Extract Contact Info').item.json.output.job_title }}\nEmail: {{ $('Extract Contact Info').item.json.output.email }}\nPhone: {{ $('Extract Contact Info').item.json.output.phone }}\nMobile: {{ $('Extract Contact Info').item.json.output.mobile }}\n\nScanned from: {{ $('New Card in Drive').item.json.name }}"
},
"useDefaultReminders": false
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "36e5e31d-4124-4987-ab42-679bfcf1f13a",
"name": "Draft Follow-up Email",
"type": "n8n-nodes-base.gmail",
"position": [
1888,
880
],
"parameters": {
"message": "=<p>Dear {{ $('Extract Contact Info').item.json.output.full_name }},</p>\n<p>It was a pleasure meeting you. I would love to stay in touch and explore potential opportunities to collaborate.</p>\n<p>Please feel free to reach out anytime.</p>\n<p>Best regards</p>\n<hr style='border:none;border-top:1px solid #ddd;margin:20px 0;'>\n<p style='font-size:12px;color:#888;'>This draft was auto-generated from a scanned business card. Please review and personalize before sending.</p>",
"options": {
"sendTo": "={{ $('Extract Contact Info').item.json.output.email }}"
},
"subject": "=Nice meeting you - {{ $('Extract Contact Info').item.json.output.full_name }}",
"resource": "draft",
"emailType": "html"
},
"typeVersion": 2.2
},
{
"id": "df100396-d91e-4611-965f-4a5f2d95d8d6",
"name": "Send Error Alert",
"type": "n8n-nodes-base.gmail",
"position": [
1600,
1104
],
"parameters": {
"sendTo": "=YOUR_EMAIL@gmail.com",
"message": "=<div style='font-family:sans-serif;max-width:500px;'><h3 style='color:#d32f2f;'>Business card scan failed</h3><p>The following file could not be processed:</p><table style='border-collapse:collapse;width:100%;'><tr><td style='padding:8px;border:1px solid #ddd;font-weight:bold;'>File</td><td style='padding:8px;border:1px solid #ddd;'>{{ $('New Card in Drive').item.json.name }}</td></tr><tr><td style='padding:8px;border:1px solid #ddd;font-weight:bold;'>Reason</td><td style='padding:8px;border:1px solid #ddd;'>Extraction returned empty name or low confidence</td></tr><tr><td style='padding:8px;border:1px solid #ddd;font-weight:bold;'>Time</td><td style='padding:8px;border:1px solid #ddd;'>{{ $now.toISO() }}</td></tr></table><p style='margin-top:16px;'>Please check the image quality and try again.</p></div>",
"options": {},
"subject": "=[Card Scan Failed] {{ $('New Card in Drive').item.json.name }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "520f16f3-284b-47b3-8503-cba276c0de78",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
208,
496
],
"parameters": {
"width": 330,
"height": 896,
"content": "### How it works\n\nDrop a business card photo into your Google Drive folder. This workflow picks it up automatically, sends the image to Gemini 2.5 Flash for OCR, and extracts 14 contact fields \u2014 name, company, title, email, phone, address, and more.\n\nIf the extraction looks good (name found, confidence not low), the contact gets logged to Google Sheets. Then two things happen in parallel: a follow-up event lands on your Google Calendar for one week out, and a draft email shows up in Gmail ready for you to personalize and send.\n\nIf the scan fails \u2014 blurry photo, unreadable text \u2014 you get an error alert email so nothing slips through.\n\n### Setup steps\n\n1. Make a **Business Cards** folder in Google Drive \u2014 grab the folder ID from the URL\n2. Create a spreadsheet with 15 headers: Full Name, Reading, Company, Department, Job Title, Email, Phone, Mobile, Fax, Postal Code, Address, Website, Notes, Source File, Scanned At\n3. Wire up credentials: Google Drive, Sheets, Calendar, Gmail (all OAuth2) + Gemini API key\n4. Set your folder ID in **New Card in Drive**, spreadsheet ID in **Save to Contact Sheet**, and notification email in **Send Error Alert**\n\n### Customization\n\n- Change `$now.plus({week: 1})` in **Schedule Follow-up** to adjust timing\n- Edit the draft template in **Draft Follow-up Email**\n- Add or remove Sheets columns to fit your CRM"
},
"typeVersion": 1
},
{
"id": "cb814624-afe2-4245-8a61-addcef6c94af",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
576,
528
],
"parameters": {
"color": "#FDFCFC",
"width": 428,
"height": 416,
"content": "## Trigger & download\nWatches your Drive folder every minute and grabs new card images automatically."
},
"typeVersion": 1
},
{
"id": "bca33d75-4c19-413c-8944-8d35aec68a56",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1024,
528
],
"parameters": {
"color": "#FAFAFA",
"width": 364,
"height": 608,
"content": "## AI contact extraction\nGemini 2.5 Flash reads the card image and pulls out 14 structured fields via the output parser."
},
"typeVersion": 1
},
{
"id": "3d6aeefa-179d-46f7-b32c-9426e19998dd",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1408,
528
],
"parameters": {
"color": "#FEFBFB",
"width": 408,
"height": 388,
"content": "## Validate & save\nChecks extraction quality, then logs the contact to your Sheets tracker with 15 columns."
},
"typeVersion": 1
},
{
"id": "edf74fc0-4abe-4887-a6b9-979385d1599c",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
528
],
"parameters": {
"color": "#FFFFFF",
"width": 248,
"height": 528,
"content": "## Auto follow-up\nCalendar event + Gmail draft created in parallel \u2014 review the draft before sending."
},
"typeVersion": 1
},
{
"id": "d9f92bee-384e-4993-a8a7-fba62fe68cb1",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
928
],
"parameters": {
"color": "#FEFBFB",
"width": 252,
"height": 352,
"content": "## Error alert\nIf the scan fails or confidence is low, you get an email with the filename so you can retake the photo."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "f9c88f44-967e-413e-a8fd-fe1a12d8ca59",
"connections": {
"Gemini 2.5 Flash": {
"ai_languageModel": [
[
{
"node": "Extract Contact Info",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"New Card in Drive": {
"main": [
[
{
"node": "Download Card Image",
"type": "main",
"index": 0
}
]
]
},
"Valid Extraction?": {
"main": [
[
{
"node": "Save to Contact Sheet",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Error Alert",
"type": "main",
"index": 0
}
]
]
},
"Contact Data Parser": {
"ai_outputParser": [
[
{
"node": "Extract Contact Info",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Download Card Image": {
"main": [
[
{
"node": "Extract Contact Info",
"type": "main",
"index": 0
}
]
]
},
"Extract Contact Info": {
"main": [
[
{
"node": "Valid Extraction?",
"type": "main",
"index": 0
}
]
]
},
"Save to Contact Sheet": {
"main": [
[
{
"node": "Schedule Follow-up",
"type": "main",
"index": 0
},
{
"node": "Draft Follow-up Email",
"type": "main",
"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.
gmailOAuth2googleCalendarOAuth2ApigoogleDriveOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Small to medium businesses in Japan using a LINE Official Account for customer support. Ideal for retail shops, restaurants, salons, and service providers who want to reduce response times without hiring additional staff.
Source: https://n8n.io/workflows/15701/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Who is this for? Agencies, consultants, and service providers who conduct discovery calls and need to quickly turn conversations into professional proposals.
This workflow automates the extraction and processing of invoice data from PDFs stored in a Google Drive folder. It leverages Google Drive, Google Sheets, and Gemini AI to streamline invoice managemen
This workflow automatically converts unstructured internal documentation into clear, actionable Standard Operating Procedures (SOPs).
Overview The Automated Invoice-Processing AI Agent in n8n is designed to streamline and optimize invoice management for finance teams and accounts payable (AP) professionals. This solution addresses t
This workflow is designed to evaluate newly added CVs for Diversity, Equity, and Inclusion (DEI) eligibility. It automatically ingests CVs from Google Drive, extracts key fields, analyzes them with Az