AutomationFlowsSlack & Telegram › Quick Hubspot Contact Lookup in Slack for Sales & Support Teams

Quick Hubspot Contact Lookup in Slack for Sales & Support Teams

ByAvkash Kakdiya @itechnotion on n8n.io

This workflow starts when a user triggers a custom slash command in Slack. The workflow checks if a valid message (email address or HubSpot contact ID) was provided. Based on the input, it searches HubSpot for the contact either by email or by ID. Once the contact is found, the…

Webhook trigger★★★★☆ complexity15 nodesStop And ErrorHubSpotSlack
Slack & Telegram Trigger: Webhook Nodes: 15 Complexity: ★★★★☆ Added:
Quick Hubspot Contact Lookup in Slack for Sales & Support Teams — n8n workflow card showing Stop And Error, HubSpot, Slack integration

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

This workflow follows the HubSpot → Slack 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": "PLACEHOLDER_WORKFLOW_ID",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "20 - HubSpot to Slack Contact Card",
  "tags": [],
  "nodes": [
    {
      "id": "00cc9790-780b-45e8-bb85-1613ef34cd05",
      "name": "\ud83c\udf10 Incoming Slash Command",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -900,
        200
      ],
      "parameters": {
        "path": "hubspot-contact-lookup",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "06f703df-a621-4c3b-a860-83859f8db226",
      "name": "\ud83d\udd0d Check if Message Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        -680,
        200
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ec3773aa-e58f-4743-b2f1-ac508daf3c87",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.text }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2898d6d5-8cd5-4e71-bf09-bc3303dea75b",
      "name": "\ud83d\uded1 Stop \u2013 Missing Message",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        -460,
        300
      ],
      "parameters": {
        "errorMessage": "No message found"
      },
      "typeVersion": 1
    },
    {
      "id": "b1bbfab9-57d8-4d26-9ab7-95e66dffa40d",
      "name": "\u2702\ufe0f Parse Search Input",
      "type": "n8n-nodes-base.code",
      "position": [
        -460,
        100
      ],
      "parameters": {
        "jsCode": "const input = $input.first().json.body.text || '';\nconst trimmedInput = input.trim();\n\nif (!trimmedInput) {\n  throw new Error('Please provide an email address or HubSpot contact ID');\n}\n\nconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst isEmail = emailRegex.test(trimmedInput);\n\nreturn {\n  searchValue: trimmedInput,\n  searchType: isEmail ? 'email' : 'id',\n  channelId: $json.channel_id,\n  userId: $json.user_id,\n  responseUrl: $json.response_url\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "e05b7063-1779-427d-b23f-b0fc9f6a20ad",
      "name": "\ud83d\udd00 Determine Search Type",
      "type": "n8n-nodes-base.if",
      "position": [
        -240,
        100
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.searchType }}",
              "rightValue": "email"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "e19a4c16-c33e-4bb5-8060-12e52e356d71",
      "name": "\ud83d\udce7 Search Contact by Email",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        -20,
        0
      ],
      "parameters": {
        "operation": "search",
        "authentication": "appToken",
        "filterGroupsUi": {
          "filterGroupsValues": [
            {
              "filtersUi": {
                "filterValues": [
                  {
                    "value": "={{ $json.searchValue }}",
                    "propertyName": "email|string"
                  }
                ]
              }
            }
          ]
        },
        "additionalFields": {
          "properties": [
            "firstname",
            "lastname",
            "email",
            "phone"
          ]
        }
      },
      "credentials": {
        "hubspotAppToken": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "47964017-2ed4-4f4a-a180-8f89759a54d0",
      "name": "\ud83c\udd94 Get Contact by ID",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        -20,
        200
      ],
      "parameters": {
        "contactId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.searchValue }}"
        },
        "operation": "get",
        "authentication": "appToken",
        "additionalFields": {}
      },
      "credentials": {
        "hubspotAppToken": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "f6fc8617-197a-42da-9d5b-4d42d428b40d",
      "name": "\ud83d\udcdd Format Contact Info (ID Search)",
      "type": "n8n-nodes-base.code",
      "position": [
        200,
        200
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nlet contact = null;\n\nif (items.length === 0) {\n  return {\n    success: false,\n    message: 'Contact not found',\n    channelId: $('\u2702\ufe0f Parse Search Input').item.json.channelId,\n    responseUrl: $('\u2702\ufe0f Parse Search Input').item.json.responseUrl\n  };\n}\n\nif (items[0].json.results && items[0].json.results.length > 0) {\n  contact = items[0].json.results[0].properties;\n} else if (items[0].json.properties) {\n  contact = items[0].json.properties;\n} else {\n  return {\n    success: false,\n    message: 'Contact not found',\n    channelId: $('\u2702\ufe0f Parse Search Input').item.json.channelId,\n    responseUrl: $('\u2702\ufe0f Parse Search Input').item.json.responseUrl\n  };\n}\n\nconst firstName = $input.first().json.properties.firstname.value || '';\nconst lastName = $input.first().json.properties.lastname.value || '';\nconst fullName = $input.first().json.properties.hs_full_name_or_email.value || 'N/A';\nconst email = $input.first().json.properties.email.value || 'N/A';\nconst phone = $input.first().json.properties.phone.value || 'N/A';\n\nconst message = `\ud83d\udccb *Contact Information*\\n\\n` +\n  `\ud83d\udc64 *Name:* ${fullName}\\n` +\n  `\ud83d\udce7 *Email:* ${email}\\n` +\n  `\ud83d\udcde *Phone:* ${phone}`;\n\nreturn {\n  success: true,\n  message: message,\n  channelId: $('\u2702\ufe0f Parse Search Input').item.json.channelId,\n  responseUrl: $('\u2702\ufe0f Parse Search Input').item.json.responseUrl\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "5cb1767c-6d3d-4f08-b486-2cc1a59d2bd2",
      "name": "\ud83d\udcdd Format Contact Info (Email Search)",
      "type": "n8n-nodes-base.code",
      "position": [
        200,
        0
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nlet contact = null;\n\nif (items.length === 0) {\n  return {\n    success: false,\n    message: 'Contact not found'\n  };\n}\n\n// Your input has `properties` directly inside the first item\nif (items[0].json.properties) {\n  contact = items[0].json.properties;\n} else {\n  return {\n    success: false,\n    message: 'Contact not found'\n  };\n}\n\nconst firstName = contact.firstname || '';\nconst lastName = contact.lastname || '';\nconst fullName = [firstName, lastName].filter(Boolean).join(' ') || 'N/A';\nconst email = contact.email || 'N/A';\nconst phone = contact.phone || 'N/A';\nconst company = contact.company || 'N/A';\nconst dealStage = contact.dealstage || 'N/A';\n\n\nconst message = `\ud83d\udccb *Contact Information*\\n\\n` +\n  `\ud83d\udc64 *Name:* ${fullName}\\n` +\n  `\ud83d\udce7 *Email:* ${email}\\n` +\n  `\ud83d\udcde *Phone:* ${phone}\\n` +\n  `\ud83c\udfe2 *Company:* ${company}\\n` +\n  `\ud83d\udcbc *Deal Stage:* ${dealStage}`;\n\nreturn {\n  success: true,\n  message\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "2df1ebf2-bda8-4112-994d-352a587ba91d",
      "name": "\ud83d\udcac Send Contact Info to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        420,
        100
      ],
      "parameters": {
        "text": "={{ $json.message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_CHANNEL_ID"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "3fadae4a-a629-4c2a-aa3c-ed5d953ff1a4",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -940,
        -60
      ],
      "parameters": {
        "width": 420,
        "height": 520,
        "content": "## Nodes: Incoming Webhook (Webhook) + Check if Message Exists (If)\n\n*This section handles receiving incoming requests (e.g., from Slack) and ensuring they contain a valid message. If the message text is empty, the workflow stops with an error response. This prevents unnecessary API calls when no search term (email or ID) is provided.*"
      },
      "typeVersion": 1
    },
    {
      "id": "220b5b75-09af-4315-9844-d0740dc9d1cf",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -500,
        -160
      ],
      "parameters": {
        "color": 5,
        "width": 420,
        "height": 420,
        "content": "## Nodes: Parse Search Input (Parse Input) + Determine Search Type (Check Search Type)\n\n*Parses the incoming message to extract and clean the search value. Determines if the provided value is a valid email address or a HubSpot contact ID using regex. This decision directs the workflow toward the correct HubSpot search method.*"
      },
      "typeVersion": 1
    },
    {
      "id": "0aad2c24-807f-4065-a905-19f0489d8bf3",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -60,
        -420
      ],
      "parameters": {
        "color": 4,
        "width": 190,
        "height": 780,
        "content": "## Nodes: Search Contact by Email (HubSpot) + Get Contact by ID (Get by ID)\n\n*If the input is an email \u2192 searches HubSpot using the email filter.\n\nIf the input is an ID \u2192 retrieves the contact record directly by ID*"
      },
      "typeVersion": 1
    },
    {
      "id": "9a3e57b1-fc33-411c-8237-5285158a06ad",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -420
      ],
      "parameters": {
        "color": 6,
        "width": 190,
        "height": 780,
        "content": "## Nodes: Format Contact Info\n\n*Formats the retrieved HubSpot contact properties into a Slack-friendly message. Includes name, email, phone number, and other key details like company and deal stage where available. Ensures consistent presentation regardless of the search method used.*"
      },
      "typeVersion": 1
    },
    {
      "id": "2d27ce7f-2d1f-4dbb-8116-225661aa9be4",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        380,
        -240
      ],
      "parameters": {
        "color": 3,
        "width": 190,
        "height": 600,
        "content": "## Node: Send Contact Info to Slack (Send to Slack)\n\n*Sends the formatted contact information to the designated Slack channel, making it immediately accessible to the requesting user or team.*"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "PLACEHOLDER_VERSION_ID",
  "connections": {
    "\ud83c\udd94 Get Contact by ID": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Format Contact Info (ID Search)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2702\ufe0f Parse Search Input": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Determine Search Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd00 Determine Search Type": {
      "main": [
        [
          {
            "node": "\ud83d\udce7 Search Contact by Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83c\udd94 Get Contact by ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83c\udf10 Incoming Slash Command": {
      "main": [
        [
          {
            "node": "\ud83d\udd0d Check if Message Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce7 Search Contact by Email": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Format Contact Info (Email Search)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd0d Check if Message Exists": {
      "main": [
        [
          {
            "node": "\u2702\ufe0f Parse Search Input",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\uded1 Stop \u2013 Missing Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Format Contact Info (ID Search)": {
      "main": [
        [
          {
            "node": "\ud83d\udcac Send Contact Info to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Format Contact Info (Email Search)": {
      "main": [
        [
          {
            "node": "\ud83d\udcac Send Contact Info to Slack",
            "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

This workflow starts when a user triggers a custom slash command in Slack. The workflow checks if a valid message (email address or HubSpot contact ID) was provided. Based on the input, it searches HubSpot for the contact either by email or by ID. Once the contact is found, the…

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

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

This workflow is built for education businesses, course creators, coaching programs, and online academies that use Close CRM for sales and need to automate everything that happens after a deal closes.

Slack, HTTP Request, Airtable
Slack & Telegram

This workflow automates the prioritization and escalation of customer support tickets. It acts as an intelligent triage system that identifies high-value customers and potential churn risks in HubSpot

HTTP Request, HubSpot, Jira +1
Slack & Telegram

How it works This AI Customer Success Risk Prediction workflow revolutionizes customer retention by predicting churn risk 30-90 days before it happens. Here's the high-level flow: Daily Data Collectio

HTTP Request, Zendesk, Stripe +4
Slack & Telegram

Code. Uses zendesk, slack, stickyNote. Webhook trigger; 9 nodes.

Zendesk, Slack
Slack & Telegram

This workflow creates a Slack thread when a new ticket is created in Zendesk. Subsequent comments on the ticket in Zendesk are added as replies to the thread in Slack. Zendesk account and Zendesk cred

Zendesk, Slack