AutomationFlows β€Ί AI & RAG β€Ί Enrich Hubspot Contacts with Linkedin Profiles Using Serpapi, Google Docs and AI

Enrich Hubspot Contacts with Linkedin Profiles Using Serpapi, Google Docs and AI

ByAxiomlab.dev @axiomlabβœ“ on n8n.io

πŸš€ How it works

Event triggerβ˜…β˜…β˜…β˜…β˜† complexityAI-powered16 nodesAgentHubSpotTool Serp ApiHubSpot TriggerGoogle Docs ToolOpenRouter Chat
AI & RAG Trigger: Event Nodes: 16 Complexity: β˜…β˜…β˜…β˜…β˜† AI nodes: yes Added:

This workflow corresponds to n8n.io template #8434 β€” we link there as the canonical source.

This workflow follows the Agent β†’ Googledocstool 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": "2I9c1wem2bFGuXzz",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "HubSpot Contact Refinement",
  "tags": [],
  "nodes": [
    {
      "id": "28164fc1-96bb-44ea-8e1e-2652e94e7679",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1920,
        -640
      ],
      "parameters": {
        "text": "=First Use Read Google Docs tool to understand how to do the research on a specific contact and the expected output format\n\nThen do the research with Google search on this \ncontact-\nFirst Name: {{ $json['First Name'] }}\nLast Name: {{ $json['Last Name'] }}\nEmail: {{ $json.Email }}\n\n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "0505748a-f6da-4ebb-981f-a189891ba38a",
      "name": "HubSpot",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        2704,
        -640
      ],
      "parameters": {
        "email": "={{ $('Edit Fields').item.json.Email }}",
        "options": {},
        "authentication": "appToken",
        "additionalFields": {
          "linkedinUrl": "={{ $json.cleanText }}"
        }
      },
      "credentials": {
        "hubspotAppToken": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "eee601f3-e202-402b-890b-daab67ea3a32",
      "name": "SerpAPI",
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "position": [
        2208,
        -432
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "serpApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "64e12389-996c-4682-9c2e-16abe6cef7fb",
      "name": "Get recently created/updated contacts",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1312,
        -640
      ],
      "parameters": {
        "operation": "getRecentlyCreatedUpdated",
        "authentication": "appToken",
        "additionalFields": {}
      },
      "credentials": {
        "hubspotAppToken": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "51e2c470-d682-4d33-b240-595f41fae02b",
      "name": "HubSpot Trigger",
      "type": "n8n-nodes-base.hubspotTrigger",
      "position": [
        1088,
        -432
      ],
      "parameters": {
        "eventsUi": {
          "eventValues": [
            {}
          ]
        },
        "additionalFields": {}
      },
      "credentials": {
        "hubspotDeveloperApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "563816de-2bff-4952-ad73-402d56f34e3d",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        1104,
        -640
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "643250fa-48b9-4e7e-8c40-b9614e56354d",
      "name": "Code - Remove Think part",
      "type": "n8n-nodes-base.code",
      "position": [
        2432,
        -640
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Remove <think>...</think> (and optional ```json fences) from this item's text\nlet text = $json.text ?? $json.output ?? $json.result ?? \"\";\n\ntext = String(text)\n  .replace(/<think>[\\s\\S]*?<\\/think>/gi, \"\")\n  .replace(/^```(?:json)?\\s*|\\s*```$/g, \"\")\n  .trim();\n\n// Return ONLY the cleaned field\nreturn { json: { cleanText: text } };\n"
      },
      "typeVersion": 2
    },
    {
      "id": "1dbaf3d7-077a-48da-a0dd-fc09aa9cb48e",
      "name": "Read Google Docs",
      "type": "n8n-nodes-base.googleDocsTool",
      "position": [
        2080,
        -432
      ],
      "parameters": {
        "operation": "get",
        "documentURL": "Replace_With_URL",
        "authentication": "serviceAccount",
        "descriptionType": "manual",
        "toolDescription": "Get a document in Google Docs"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "4bcec552-cf09-485d-8584-a9490bd66de4",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1584,
        -640
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d4e105c6-b0a1-43c9-9a28-c6b9a7f92381",
              "name": "First Name",
              "type": "string",
              "value": "={{ $json.properties.firstname.value }}"
            },
            {
              "id": "b04d763a-9e5f-4b65-8eb6-f100ce802395",
              "name": "Last Name",
              "type": "string",
              "value": "={{ $json.properties.lastname.value }}"
            },
            {
              "id": "4cd40bc6-0c25-40d4-98d8-11dbb5b56cc7",
              "name": "Email",
              "type": "string",
              "value": "={{ $json['identity-profiles'][0].identities[0].value }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ab4cf5e3-bcab-470f-9f09-36e3431ed71d",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        1824,
        -432
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "aab92067-a3f9-4a91-855c-1f22602a9930",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1040,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 208,
        "height": 528,
        "content": "## Innitiate the Workflow\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8197ccfd-c289-4ebb-a78c-f46fe9527d07",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 528,
        "content": "## Data Clean Up\n"
      },
      "typeVersion": 1
    },
    {
      "id": "64bfb439-a5c3-46ea-82c8-7d5d92f1fa9d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1776,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 528,
        "content": "## AI Agent Led Contact Research\nAI agent performs Google search to find useful information from LinedIn Profile\n"
      },
      "typeVersion": 1
    },
    {
      "id": "c8ceb524-9b03-4b6e-a01b-04d8fbba2627",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2368,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 528,
        "content": "## Data Clean up\nThink tag portion is common from smaller models and are removed "
      },
      "typeVersion": 1
    },
    {
      "id": "704037d1-f9b8-4df5-8367-8b61483b4c74",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2656,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 528,
        "content": "## Update Hubspot Contact\nThe workflow updates LinkedIn field for the contact"
      },
      "typeVersion": 1
    },
    {
      "id": "93afa981-4a11-4228-b2bc-3072947789df",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        -1248
      ],
      "parameters": {
        "width": 576,
        "height": 1328,
        "content": "## HubSpot Contact Refinement\n\n\ud83d\ude80 **How it works**\n\n**Triggers:**\n* HubSpot Trigger: Fires when contacts are created/updated.\n* Manual Trigger: Run on demand for testing or batch checks.\n* Get Recently Created/Updated Contacts: Pulls fresh contacts from HubSpot.\n* Edit Fields (Set): Maps key fields (First Name, Last Name, Email) for the Agent.\n\n\n**AI Agent:**\n* First reads your Google Doc (via the Google Docs tool) to learn the research steps and output format.\n* Then uses SerpAPI (Google engine) to locate the contact\u2019s likely LinkedIn profile and produce a concise result.\n* Code \u2013 Remove Think Part: Cleans the model output (removes hidden \u201cthink\u201d blocks / formatting) so only the final answer remains.\n* HubSpot Update: Writes the cleaned LinkedIn URL to the contact (via email match).\n\n\n\ud83d\udd11 **Required Credentials:**\n* HubSpot App Token (Private App) \u2014 for Get/Update contact nodes.\n* HubSpot Developer OAuth (optional) \u2014 if you use the HubSpot * Trigger node for event-based runs.\n* Google Service Account \u2014 for the Google Docs tool (share your * playbook doc with this service account).\n* OpenRouter \u2014 for the OpenRouter Chat Model used by the AI Agent.\n* SerpAPI \u2014 for targeted Google searches from within the Agent.\n\n\n\ud83d\udee0\ufe0f **Setup Instructions**\n\n**HubSpot**\n* Create a Private App and copy the Access Token.\n* Add or confirm the contact property linkedinUrl (Text).\n* Plug the token into the HubSpot nodes.\n* If using HubSpot Trigger, connect your Developer OAuth app and subscribe to contact create/update events.\n\n\n**Google Docs (Living Instructions)**\n\n[\u27a1\ufe0f Sample configuration doc file](https://docs.google.com/document/d/1nn69H3wdwXJolDwu0avlFw7sIwnX_Hpr3bmOD6PgdW4/edit?usp=sharing)\n* Copy the sample doc file and modify to your need.\n* Share the doc with your Google Service Account (Viewer is fine).\n* In the Read Google Docs node, paste the Document URL.\n\n**OpenRouter & SerpAPI**\n* Add your OpenRouter key to the OpenRouter Chat Model credential.\n* Add your SerpAPI key to the SerpAPI tool node.\n* (Optional) In your Google Doc or Agent prompt, set sensible defaults for SerpAPI (engine=google, hl=en, gl=us, num=5, max 1\u20132 searches).\n\n\n\u2728 **What you get**\n* Auto-enriched contacts with a LinkedIn URL and profile insights (clean, validated output).\n* A research process you can change anytime by editing the Google Doc\u2014no workflow changes needed.\n* Tight, low-noise searches via SerpAPI to keep costs down.\n\n\nAnd that\u2019s it\u2014publish and let the Agent enrich new leads automatically while you refine the rules in your doc. It allows handing off to a team who wouldn't necessarily tweak the automation nodes."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b1690f40-eaa8-4ee0-9670-9586357288ab",
  "connections": {
    "SerpAPI": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Code - Remove Think part",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HubSpot Trigger": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Google Docs": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Code - Remove Think part": {
      "main": [
        [
          {
            "node": "HubSpot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Get recently created/updated contacts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get recently created/updated contacts": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "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.

Pro

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

About this workflow

πŸš€ How it works

Source: https://n8n.io/workflows/8434/ β€” 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

This workflow is designed for marketers, content creators, agencies, and solo founders who want to publish long‑form posts with visuals on autopilot using n8n and AI agents. ​

Tool Http Request, Agent, HTTP Request +27
AI & RAG

This template enables natural-language-driven automation using Bright Data's MCP tools, triggered directly by new leads in HubSpot. It dynamically extracts and executes the right tool based on lead co

Google Sheets Trigger, Output Parser Structured, Output Parser Autofixing +7
AI & RAG

⚠️ DISCLAIMER: This workflow uses the AnySite LinkedIn community node, which is only available on self-hosted n8n instances. It will not work on n8n.cloud.

OpenAI Chat, Pipedrive Tool, HubSpot Trigger +5
AI & RAG

How it works:

Stop And Error, OpenAI Chat, Output Parser Structured +4
AI & RAG

How it works:

HubSpot Trigger, HubSpot, Stop And Error +6