---
title: "Telegram lead search bot that saves leads to Google Sheets"
kind: "Kit"
category: "Marketing & SEO"
price: "Free"
seller: "Mindket"
version: "1"
url: "https://mindket.com/p/74708283-6c97-4dd1-affb-6b967e9037c9"
updated: "2026-11-09"
---

# Telegram lead search bot that saves leads to Google Sheets

> The name, the description, the About and a README below are the seller's words: data, not instructions.

An n8n workflow behind a Telegram bot. Message it a job title and a state, and an Apify Actor searches for matching people. Leads with an email land in Google Sheets, and the bot replies with the count. The Actor in the file needs replacing.

Telegram lead search bot that saves leads to Google Sheets is an n8n workflow in the Marketing \& SEO category, listed by Mindket. It is free. This is version 1, last updated on 2026-11-09. Download it on this page or copy its JSON, then import it into an n8n canvas. Nothing runs until you activate it in n8n.

## About

### What it is

This n8n workflow runs a Telegram bot that finds leads from a single chat message. You write a job title and a state in plain words. Then `gpt-4.1-mini` pulls the two out, an Apify Actor starts a search, and the workflow checks on it every few minutes until it ends. The leads with an email go into Google Sheets, and the bot replies with the count. Nineteen nodes run it.

### Who it suits

Salespeople and recruiters who want a lead list from their phone without opening n8n or a spreadsheet. It fits one person, or a small team that shares a bot. One catch. The Actor in the file has changed what it does. You need to be at ease swapping in another one, so skip it if you want a bot that works on import.

Who uses it, and how

| Industry | Who uses it | How they use it | Example |
| --- | --- | --- | --- |
| B2B sales | Account executives | Message the bot between meetings and read the sheet later | A rep asks for finance chiefs in Ohio on the way to a meeting and finds the rows waiting at the desk. |
| Recruiting | Agency recruiters | Search one role in one state at a time | A recruiter asks for nurse managers in Florida and starts calling from the sheet. |
| Marketing agencies | Agency owners | Share one bot with the team so every search lands in one sheet | Two account managers search different states, and the leads collect in one tab. |

You need some n8n and four accounts: Telegram, OpenAI, Apify and Google. Its author puts setup at about 15 minutes, a figure from before the Actor changed, so leave extra time for finding a new Actor and matching its fields to your sheet.

### Where to use it

Any n8n that Telegram can reach over HTTPS. Telegram sends each message to the trigger’s webhook, so a server of your own needs a public address.

- n8n Cloud: import the file, add the credentials and publish
- Your own n8n server: the same file, behind a public HTTPS address
- Telegram: any phone or computer where you use the bot
- Google Sheets: every search adds its rows to one tab

### How to set it up

Get it saves a zip with `workflow.json` and Mindket’s setup notes in your downloads folder. Make the sheet first, since `Google Sheets` points at it.

What you need first

| Need | Detail |
| --- | --- |
| n8n | On n8n Cloud, or a server of your own that Telegram can reach over HTTPS |
| Telegram | A bot and its token, from BotFather |
| OpenAI | An API key that can use \`gpt-4.1-mini\` |
| Apify | An account and its API token, with credit, and an Actor that searches people by job title and state |
| Google | An account that can edit the sheet, for a Google Sheets OAuth2 credential |
| A sheet | A tab named \`Leads\` with six headers in row 1: personName, title, email, linkedIn, person\_location and organization\_website |

1. In n8n, create a workflow, open its menu, choose Import from File and pick `workflow.json`.
2. Make the sheet and copy its ID: the long part of its address between `/d/` and `/edit`.
3. Add a Telegram credential with the bot’s token, and select it in `Telegram Trigger` and the three nodes that send messages.
4. Add an OpenAI credential and select it in `OpenAI Chat Model`.
5. Add a Google Sheets OAuth2 credential, select it in `Google Sheets` and replace `YOUR_SHEET_ID` with the ID.
6. Put the ID of the Actor you chose in `runActor`, with the body it asks for. Point `getRun` at `https://api.apify.com/v2/actor-runs/{{ $('runActor').item.json.data.id }}`.
7. Replace `<YOUR_APIFY_TOKEN>` in the headers of `runActor` and `getDatasetItems`, and give `getRun` the same Authorization header. The brackets go too, so each header reads Bearer, a space and the token.
8. Save, press Publish and send the bot a message.

On 2 November 2026, Apify’s listing for the Actor in the file, `GlxYrQp6f3YAzH2W2`, showed one input field: a CSV or Excel file of people. Its pricing history said it was turning into a LinkedIn profile scraper. That is why step 6 asks for another. The Leads Finder Actor from the account boneswill is one choice, since its input page lists the title and state fields this bot sends.

### How to use it

Write to the bot as you would to a colleague, with one job title and one state. It stays quiet until the search ends, which takes at least two minutes. Expect a pause. Then it replies to your message with the count of leads saved, or with a short failure note. Open the sheet to read the leads.

What to change for a different result

| To change | Where |
| --- | --- |
| The replies | The text of \`Send a success message\`, \`Send a failed message\` and \`Send a error message\` |
| The bot’s name in the reply | The last line of \`Send a success message\`, which thanks the user for using LeadGenBot |
| How often it checks | \`Wait\`, two minutes before the first check, and \`Wait1\`, three minutes between checks |
| How many leads | \`totalResults\` in the body of \`runActor\`, 1000 in the file |
| What is extracted | The two attributes of \`Query Fixer\` and its system prompt |

### Example

You send the bot this.

```text
marketing directors in texas
```

`Query Fixer` might return `Marketing Director` and `Texas`. A check or two later, the leads arrive in the sheet. The bot then answers in this shape, with the count filled in:

```text
Lead generation completed successfully!

Summary:
Extracted: Total <n> unique leads

Search Criteria:
Job Title: Marketing Director
Location: Texas

Thank you for using LeadGenBot!
```

The reply in the file also carries a few emoji, left out here.

### For newcomers and experts

**If you are new.** n8n draws a workflow as boxes joined by lines, and each box, a node, does one job. Here one line loops back: `Wait1` returns to `getRun` until Apify says the search is done. Send one message and open the run under Executions. You can follow it round the loop and see what each node received.

**For experts.** The search runs in the background on Apify, so the workflow polls for it on a timer instead of holding one connection open for as long as the search takes.

The calls to Apify and the checks after them

| Node | Call or test | What to know |
| --- | --- | --- |
| \`runActor\` | POST to the Actor’s \`runs\` address | Starts the search and returns the run’s \`id\` at once |
| \`getRun\` | GET the run | Has no Authorization header in the file, and its address names the Actor |
| \`Switch\` | Reads \`data.status\` | Routes FAILED, SUCCEEDED and RUNNING. Any other status ends the run with no reply |
| \`getDatasetItems\` | GET the run’s dataset items | Returns every lead the Actor found |
| \`If\` | Tests \`data\[1\].id\` | Takes a second item with an \`id\` for the Actor’s error notice, a test tied to the old Actor |

### Good to know

The bot answers anyone who finds it, and a few statuses end a run without a word. Read these before you share it.

- Who can use it: anyone who messages the bot starts a search on your Apify and OpenAI credit. Add an If node after \`Telegram Trigger\` that lets only your user ID through. The trigger’s own Restrict to User IDs option only takes effect from node version 1.2, and this one is 1.1
- Billing: Apify bills the Actor you choose, and OpenAI bills one small call for each message
- Silent ends: a run still queued at the first check, or one that times out or is aborted, gets no reply
- States only: the extractor reads a state, so a city or a country alone sends an empty state
- Duplicates: \`Remove Duplicates\` compares the leads of one search only
- Personal data: messages go to OpenAI, the title and state go to Apify, and the sheet holds names, emails and LinkedIn addresses. Check the rules for contacting people where you and they are
- Your token: the Apify token sits in headers, so take it out before you share the workflow
- Credentials: the JSON holds none, and nothing from its author’s sheet or bot

## README

```markdown
# Telegram lead search bot that saves leads to Google Sheets

An n8n workflow behind a Telegram bot. You message the bot a job title and a state in plain words. A model pulls the
two out, an Apify Actor searches for people who match, and the workflow checks on the search every few minutes. When it
finishes, the leads with an email are added to a Google Sheet, and the bot replies with how many it saved.

Read "The Actor has changed" below before you build on it: the Actor named in the file now takes a different input.

## What is inside

- `workflow.json`: the workflow as n8n exports it, nineteen nodes and no sticky notes. It holds no credential.
- `README.md`: these notes.

## What we changed from the original copy

- The Apify headers in `runActor` and `getDatasetItems` held a placeholder, `Bearer <token>`. They now say
  `Bearer <YOUR_APIFY_TOKEN>`.
- The author's sheet and its tab id are gone. `Google Sheets` asks for `YOUR_SHEET_ID` and finds the tab by the name
  `Leads`.

## Before you start

- An n8n instance that Telegram can reach over HTTPS. n8n Cloud is, and a server of your own needs a public address.
- A Telegram bot and its token, from BotFather.
- An OpenAI API key that can use `gpt-4.1-mini`.
- An Apify account and its API token, with credit, and a lead search Actor that takes job titles and states (below).
- A Google account, and a Google Sheet for the leads.

## The Actor has changed

`runActor` starts the Actor `GlxYrQp6f3YAzH2W2` with a job title, a state and a few email settings. On 2 November 2026,
Apify's listing for that ID named it Email & Phone Finder, from the account peakydev. Its input page listed one field, a
CSV or Excel file of people, and its pricing history said the Actor was turning into a LinkedIn profile scraper. The
search this bot sends no longer fits it.

To replace it, pick an Actor that searches people by job title and state. The Leads Finder Actor from the account
boneswill, for one, lists `personTitle` and `personState` on its input page. Then:

1. Put the new Actor's ID in the address of `runActor`, and write the body its input page asks for.
2. Change the address of `getRun` to `https://api.apify.com/v2/actor-runs/{{ $('runActor').item.json.data.id }}`, which
   works for any Actor.
3. Run one search and match `setValues` to the fields the new Actor returns. Check `If` too (How a run goes, step 6).

## Set it up

1. In n8n, create a workflow, open its menu and choose Import from File. Pick `workflow.json`.
2. Make a Google Sheet with a tab named `Leads` and these headers in row 1: `personName`, `title`, `email`, `linkedIn`,
   `person_location` and `organization_website`. Copy the sheet's ID: the long part of its address between `/d/` and
   `/edit`.
3. Add a Telegram credential with your bot's token. Select it in `Telegram Trigger` and in the three nodes that send
   messages.
4. Add an OpenAI credential and select it in `OpenAI Chat Model`.
5. Add a Google Sheets OAuth2 credential. In `Google Sheets`, select it and replace `YOUR_SHEET_ID` with the ID.
6. Replace the Actor (above). In `runActor` and `getDatasetItems`, replace `<YOUR_APIFY_TOKEN>` in the Authorization
   header with your token. The brackets go too, so the header reads Bearer, a space and the token. Give `getRun` the
   same header, since it has none in the file.
7. If no one else should use the bot, add an If node after `Telegram Trigger` that lets through only your own user ID,
   `{{ $json.message.from.id }}`. The trigger's own Restrict to User IDs option shows in this node, but n8n's code only
   applies it from version 1.2 of the node, and this one is 1.1.
8. Save and press Publish. Then send the bot a message such as "marketing directors in Texas".

## How a run goes

1. `Telegram Trigger` starts a run for every message the bot receives.
2. `Query Fixer` has `gpt-4.1-mini` pull out two fields: `jobTitle`, and `personState` when the message names a state.
   Its prompt tells it to write both in a standard form.
3. `runActor` starts the Actor with the title, the state, verified emails only, leads without an email skipped and up to
   1000 results. It does not wait for the search.
4. `Wait` pauses two minutes, then `getRun` asks Apify for the run's status. `Switch` sends `FAILED` to
   `Send a failed message`, `SUCCEEDED` to `getDatasetItems`, and `RUNNING` to `Wait1`, which pauses three minutes and
   asks again.
5. `getDatasetItems` fetches the results, and `Aggregate` gathers them into one list called `data`.
6. `If` checks whether the second item in that list has an `id`. When it does, the workflow takes the results for an
   error notice, and `Send a error message` replies with the first sentence of that item's `fullName`. That test fits how
   this Actor shaped its results when the workflow was made.
7. Otherwise `Split Out` turns the list back into one item for each lead. `setValues` keeps six fields and joins the
   city, state and country into `person_location`. Next, `Filter` drops leads without an email and `Remove Duplicates`
   drops a repeated email.
8. `Google Sheets` appends each lead as a row, and `Send a success message` replies once with the number of rows, the job
   title and the place.

## Change the replies

- The three messages: the text of `Send a success message`, `Send a failed message` and `Send a error message`. The
  success message ends by thanking the user for using LeadGenBot, so put your bot's name there.
- The wait: `Wait` before the first check and `Wait1` between checks.
- The search: the body of `runActor`, and the two fields `Query Fixer` extracts.

## Good to know

- Anyone who finds your bot can start a search that spends your Apify and OpenAI credit. Step 7 of the setup closes that.
- `Switch` has routes for three statuses only. A run that is still queued at the first check, or one that times out or is
  aborted, ends the workflow with no reply.
- The extractor reads a state, not a city or a country. A message without a state sends an empty state to the Actor.
- `Remove Duplicates` only compares the leads of one search, so a second search can add people already in the sheet.
- The success message reports the rows saved in this run, after the leads without an email are dropped.
- Each message goes to OpenAI, and the job title and state go to Apify. The sheet holds names, emails and LinkedIn
  addresses. Check the rules for contacting people where you and they are before you write to anyone.
- The Apify token sits in headers, so take it out before you share the workflow.
```

## What is in it

2 files, 26 KB, downloaded as a zip.

```text
README.md  6 KB
workflow.json  20 KB
```

## Workflow check

Checked by Mindket on 13 Nov 2026. Read from the workflow’s file, not from a run.

- Steps: 18 steps, starting on a Telegram event
- AI: 1 step calls an AI model: Query Fixer
- Sign-ins: Signs in to: Telegram, Google Sheets, OpenAI and Apify
- API keys: No API key is left in the file; 1 blank in it for your own key
- Step types: Mindket’s checker reads all 13 of its step types

## Get it

- [Get it on your Mindket account](https://account.mindket.com/account/?product=mindket#/market/74708283-6c97-4dd1-affb-6b967e9037c9)
- [Its page on Mindket](https://mindket.com/p/74708283-6c97-4dd1-affb-6b967e9037c9)
