{
  "id": "snAYVkGIb3bDTk2C",
  "name": "My workflow 4",
  "tags": [],
  "nodes": [
    {
      "id": "8973e5ac-fe72-4a8f-a293-a1bf673cefb9",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -912,
        64
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "14665c0e-7229-4145-a323-fe08472b8db9",
      "name": "Workflow Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -704,
        64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "searchQuery",
              "type": "string",
              "value": "\u6e0b\u8c37 \u30ab\u30d5\u30a7"
            },
            {
              "id": "id-2",
              "name": "maxPlaces",
              "type": "number",
              "value": 5
            },
            {
              "id": "id-3",
              "name": "apifyActorId",
              "type": "string",
              "value": "compass/google-maps-scraper"
            },
            {
              "id": "id-4",
              "name": "serviceName",
              "type": "string",
              "value": "\u98f2\u98df\u5e97\u5411\u3051\u4e88\u7d04\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u300cyoyaku-kun\u300d"
            },
            {
              "id": "id-5",
              "name": "serviceStrength",
              "type": "string",
              "value": "\u5fd9\u3057\u3044\u30e9\u30f3\u30c1\u30bf\u30a4\u30e0\u3067\u3082\u96fb\u8a71\u3092\u53d6\u3089\u305a\u306b\u4e88\u7d04\u5b8c\u7d50\u3002\u30aa\u30fc\u30ac\u30cb\u30c3\u30af\u98df\u6750\u306a\u3069\u3053\u3060\u308f\u308a\u3092\u30a2\u30d4\u30fc\u30eb\u3059\u308b\u30da\u30fc\u30b8\u4f5c\u6210\u6a5f\u80fd\u3042\u308a\u3002"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "644f99ed-f731-43a3-b108-f42d6b025650",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -240,
        64
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "db5a7927-9b40-49a1-9356-68cda2575e93",
      "name": "Check Website URL Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        -32,
        80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.website }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "fac6fc69-635f-43bb-8d7f-d07b14eede3a",
      "name": "Fetch Website HTML",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        224,
        64
      ],
      "parameters": {
        "url": "={{ $json.website }}",
        "options": {}
      },
      "typeVersion": 4.3
    },
    {
      "id": "fa8d0479-4c34-4c53-b240-de0cb65267ff",
      "name": "Extract Text from HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        432,
        64
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const html = $input.item.json.data || '';\nconst text = html.replace(/<script[^>]*>.*?<\\/script>/gi, '').replace(/<style[^>]*>.*?<\\/style>/gi, '').replace(/<[^>]+>/g, ' ').replace(/\\s+/g, ' ').trim().substring(0, 2000);\n\nreturn {\n  json: {\n    site_text: text,\n    title: $('Loop Over Items').item.json.title,\n    categoryName: $('Loop Over Items').item.json.categoryName,\n    website: $('Loop Over Items').item.json.website,\n    address: $('Loop Over Items').item.json.address,\n    phone: $('Loop Over Items').item.json.phone\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "864e927b-98e1-4f64-936b-b4b6534f2bda",
      "name": "Generate Personalized Email",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        656,
        64
      ],
      "parameters": {
        "operation": "message"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "f87d5128-c0a5-44df-892a-0cbe99e06d32",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1008,
        208
      ],
      "parameters": {
        "columns": {
          "value": {
            "\u4f4f\u6240": "={{ $('Loop Over Items').item.json.address }}",
            "\u5e97\u8217\u540d": "={{ $('Loop Over Items').item.json.title }}",
            "Web\u30b5\u30a4\u30c8": "={{ $('Loop Over Items').item.json.website }}",
            "\u96fb\u8a71\u756a\u53f7": "={{ $('Loop Over Items').item.json.phone }}",
            "\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u4ef6\u540d": "={{ $json.message.content }}",
            "\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u672c\u6587": "={{ $json.message.content }}",
            "\u30b5\u30a4\u30c8\u304b\u3089\u53d6\u5f97\u3057\u305f\u60c5\u5831": "={{ $('Extract Text from HTML').item.json.site_text }}"
          },
          "schema": [
            {
              "id": "\u5e97\u8217\u540d",
              "required": false,
              "displayName": "\u5e97\u8217\u540d",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u4f4f\u6240",
              "required": false,
              "displayName": "\u4f4f\u6240",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Web\u30b5\u30a4\u30c8",
              "required": false,
              "displayName": "Web\u30b5\u30a4\u30c8",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u96fb\u8a71\u756a\u53f7",
              "required": false,
              "displayName": "\u96fb\u8a71\u756a\u53f7",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u30b5\u30a4\u30c8\u304b\u3089\u53d6\u5f97\u3057\u305f\u60c5\u5831",
              "required": false,
              "displayName": "\u30b5\u30a4\u30c8\u304b\u3089\u53d6\u5f97\u3057\u305f\u60c5\u5831",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u4ef6\u540d",
              "required": false,
              "displayName": "\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u4ef6\u540d",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u672c\u6587",
              "required": false,
              "displayName": "\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u672c\u6587",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "\u5e97\u8217\u540d"
          ]
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "<__PLACEHOLDER_VALUE__Sheet Name (e.g., Sheet1)__>"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Google Sheets Document ID__>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "08d04338-0f49-450d-9115-b47090cf95c2",
      "name": "Get user runs list",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        -480,
        64
      ],
      "parameters": {
        "resource": "Actor runs"
      },
      "typeVersion": 1
    },
    {
      "id": "419d3380-9887-42c3-a7f8-351381030862",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2320,
        -560
      ],
      "parameters": {
        "width": 1248,
        "height": 1248,
        "content": "\n\n# Generate personalized sales emails from Google Maps results to Google Sheets\n\nThis workflow automates the entire process of lead generation and personalized outreach drafting for local businesses. It utilizes **Apify** to scrape business data from Google Maps based on your search criteria (e.g., \"Cafes in Shibuya\"), visits each business's website to extract content, and uses **OpenAI** to generate a highly personalized sales email that connects the business's unique characteristics with your service's value proposition. Finally, it saves the business details, scraped data, and the generated email draft into **Google Sheets**.\n\nThis template is perfect for reducing the manual effort required to research leads and write initial cold outreach emails.\n\n## Who is this for\n- **Sales Representatives** looking to automate lead sourcing and initial drafting.\n- **Marketing Agencies** doing outreach for local businesses.\n- **Freelancers** offering web design, SEO, or reservation system services to brick-and-mortar stores.\n\n## What it does\n1. **Configuration**: You define your search query (e.g., \"Gyms in London\"), the number of leads to fetch, and details about the service you are selling.\n2. **Lead Scraping**: The workflow triggers an Apify actor (Google Maps Scraper) to find businesses matching your criteria.\n3. **Website Analysis**: It checks if the business has a website, fetches the HTML, and extracts relevant text to understand the business's vibe and offerings.\n4. **AI Email Generation**: OpenAI analyzes the scraped website text and generates a specific, personalized email subject and body promoting your service.\n5. **Data Storage**: All data (Business Name, Phone, Address, Website, Scraped Info, and Email Draft) is appended to a Google Sheet.\n\n## Requirements\n- **n8n** (v1.0 or later)\n- **Apify Account**: You need an Apify account and the `compass/google-maps-scraper` actor.\n- **OpenAI Account**: An API key for generating the email content.\n- **Google Cloud Platform**: A project with the Google Sheets API enabled.\n\n## How to set up\n1. **Credentials**: Set up your credentials for Apify, OpenAI, and Google Sheets in n8n.\n2. **Google Sheet**: Create a new Google Sheet and add the following headers in the first row:\n   - `\u5e97\u8217\u540d` (Store Name)\n   - `\u4f4f\u6240` (Address)\n   - `Web\u30b5\u30a4\u30c8` (Website)\n   - `\u96fb\u8a71\u756a\u53f7` (Phone Number)\n   - `\u30b5\u30a4\u30c8\u304b\u3089\u53d6\u5f97\u3057\u305f\u60c5\u5831` (Info from Website)\n   - `\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u4ef6\u540d` (Generated Subject)\n   - `\u751f\u6210\u3055\u308c\u305f\u30e1\u30fc\u30eb\u672c\u6587` (Generated Body)\n3. **Workflow Configuration Node**: Open the first \"Workflow Configuration\" node and update the following values:\n   - `searchQuery`: The location and keyword you want to target.\n   - `serviceName`: The name of the product you are selling.\n   - `serviceStrength`: The USP (Unique Selling Proposition) of your product.\n4. **Google Sheets Node**: Open the \"Save to Google Sheets\" node and select the file you created in step 2.\n\n## How to customize\n- **Change the Prompt**: Open the \"Generate Personalized Email\" (OpenAI) node to modify the system prompt. You can change the tone, language (currently set to Japanese context in your example), or structure of the sales email.\n- **Filter Results**: You can add logic to the \"Check Website URL Exists\" node to filter out specific types of businesses or domains.\n- **Limit Scraping**: Adjust the `maxPlaces` value in the Configuration node to control how many leads you process per run to save on API credits.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "05843f95-cc8e-4f24-93b0-2335a400755f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -752,
        -112
      ],
      "parameters": {
        "color": 2,
        "width": 192,
        "height": 336,
        "content": "1. **Configuration**: You define your search query (e.g., \"Gyms in London\"), the number of leads to fetch, and details about the service you are selling."
      },
      "typeVersion": 1
    },
    {
      "id": "6684bb6a-0214-4305-8381-485d2df0d22d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -528,
        -112
      ],
      "parameters": {
        "color": 3,
        "width": 192,
        "height": 336,
        "content": "2. **Lead Scraping**: The workflow triggers an Apify actor (Google Maps Scraper) to find businesses matching your criteria."
      },
      "typeVersion": 1
    },
    {
      "id": "d49f1bc8-8ba0-436c-8b89-286f11cc5a05",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -96
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 336,
        "content": "3. **Website Analysis**: It checks if the business has a website, fetches the HTML, and extracts relevant text to understand the business's vibe and offerings."
      },
      "typeVersion": 1
    },
    {
      "id": "2c312123-c050-45f2-afee-441e9d0e8cee",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        -96
      ],
      "parameters": {
        "color": 5,
        "width": 288,
        "height": 336,
        "content": "4. **AI Email Generation**: OpenAI analyzes the scraped website text and generates a specific, personalized email subject and body promoting your service."
      },
      "typeVersion": 1
    },
    {
      "id": "dbf1484c-73f6-465d-aa1b-185732ae78d8",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        944,
        48
      ],
      "parameters": {
        "color": 6,
        "width": 256,
        "height": 384,
        "content": "5. **Data Storage**: All data (Business Name, Phone, Address, Website, Scraped Info, and Email Draft) is appended to a Google Sheet."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "1125f1d6-fc85-4612-a340-d9422fffb618",
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Check Website URL Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Website HTML": {
      "main": [
        [
          {
            "node": "Extract Text from HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get user runs list": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Google Sheets": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Text from HTML": {
      "main": [
        [
          {
            "node": "Generate Personalized Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Get user runs list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Website URL Exists": {
      "main": [
        [
          {
            "node": "Fetch Website HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Personalized Email": {
      "main": [
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}