Skip to content

Recipe: score new leads with AI and get the hot ones on Telegram

Your website form sends each new lead (name, company, message, budget) to n8n. Claude gives it a score from 1 to 5 with a one-line reason. Leads with a score of 4 or more reach you on Telegram straight away; the others are saved in a data table to look at later.

Time needed 40 minutes
You need An n8n agent with your Claude key (Sign in and build your first AI agent), your Telegram bot saved in n8n (step 1 of the contact form recipe) and your numeric Telegram ID (from @userinfobot)
Result A Telegram message such as Hot lead (5/5): Marta Silva, Hotel Mar Azul with the budget, the message and Claude's reason; the other leads in an other leads table with their score and reason

This is the finished workflow, after a test with a hot lead:

The finished workflow

Webhook receives the lead → Score lead (Basic LLM Chain with Anthropic Chat Model and Structured Output Parser) gives a score and a reason → Score 4 or more? (If) → true: Hot lead alert (Telegram) / false: Save for later (Data table).

Send /start to your bot first

A Telegram bot can only write to people who have opened it. Open your bot in Telegram and tap Start once before you test.

A score is a hint, not a decision

Claude only sees what the lead wrote. Read the reason, and look at the low-score leads in the table from time to time.

Decide what a good lead is

Claude scores better when you tell it what each score means for your business. Our example is a small web agency, Lisboa Web Studio, whose websites start at 1,500 EUR:

Score Meaning
5 clear website project, budget of 5,000 EUR or more, wants to start soon
4 clear website project and a budget of 1,500 EUR or more
3 real interest, but the project is vague or the budget is unknown
2 budget under 1,500 EUR, or only asking for prices for later
1 spam, someone selling something to us, or not about a website

Before testing, we wrote 3 test leads and decided ourselves which score each one deserved: 5 for a hotel with an 8,000 EUR booking website, 2 for a café asking the price of a 300 EUR page for next year, 1 for an SEO company trying to sell us something.

1. Create the table for the other leads

Create a data table named other leads with these columns (how to create a data table):

Column Type
name String
company String
message String
budget String
score Number
reason String

budget is text, because people write it in many ways (8000 EUR, about 2k, or nothing).

2. Receive the lead (Webhook)

  1. Click the + at the top of the menu on the left, choose New workflow and name it, for example Lead scoring.
  2. Click Add first step and choose On webhook call. Set it:

    The Webhook step

    1. HTTP Method: POST.
    2. Path: new-lead.
    3. The Test URL, which you use in step 7. More about the two addresses: Receive data with a webhook.

Your form must send the lead as JSON with the fields name, company, message and budget.

3. Let Claude score the lead

  1. Close the panel. Click the + at the right of Webhook, search for Basic LLM Chain and click it. Rename it Score lead.
  2. Set it:

    The Score lead step after a test

    1. Source for Prompt (User Message): Define below.
    2. Prompt (User Message): click Expression and paste (put your business and your own scale):

      You score sales leads for Lisboa Web Studio, a small agency that builds websites for local businesses (prices start at 1,500 EUR).
      Give the lead a score from 1 to 5:
      5 = clear website project, budget of 5,000 EUR or more, wants to start soon
      4 = clear website project and a budget of 1,500 EUR or more
      3 = real interest, but the project is vague or the budget is unknown
      2 = budget under 1,500 EUR, or only asking for prices for later
      1 = spam, someone selling something to us, or not about a website
      Give a one-line reason in English.
      
      Name: {{ $json.body.name }}
      Company: {{ $json.body.company }}
      Message: {{ $json.body.message }}
      Budget: {{ $json.body.budget }}
      
    3. Require Specific Output Format: switch it on, so Claude answers in a fixed shape (step 4) that the If step can read.

    4. After a test, the OUTPUT shows output with a score (a number) and a reason.
    5. Click the + under Model and choose Anthropic Chat Model (n8n picks your Anthropic account credential). The + under Output Parser is for step 4.

4. Tell Claude the answer shape (Structured Output Parser)

  1. Click the + under Output Parser and choose Structured Output Parser.
  2. Set it:

    The Structured Output Parser step

    1. Schema Type: Generate From JSON Example.
    2. JSON Example: replace the example with:

      {
        "score": 4,
        "reason": "Clear website project for a hotel with a budget of 3,000 EUR."
      }
      

      Write the score without quotes (4, not "4"): n8n then knows it is a number, which the If step compares in step 5.

    3. After a test, the OUTPUT shows the score and reason Claude gave.

5. Split hot leads from the rest (If)

  1. Add an If step after Score lead (the +, search If). Rename it Score 4 or more?.
  2. Set the condition:

    The If step after a test

    1. First box: click Expression and type {{ $json.output.score }}. Operator: Number → is greater than or equal to. Second box: 4.
    2. After a test, the OUTPUT shows which exit the lead took: True Branch or False Branch, with (1 item) on the one it used. Here, the SEO company (score 1) went to False Branch.

6. Hot leads to Telegram, the rest to the table

True exit: Telegram.

  1. Click the + on the true exit of the If step, search Telegram and choose Send a text message. Rename it Hot lead alert.
  2. Set it:

    The Telegram step after a test

    1. Chat ID: your numeric Telegram ID. (Credential: your Telegram bot.)
    2. Text: click Expression and paste:

      Hot lead ({{ $json.output.score }}/5): {{ $('Webhook').item.json.body.name }}, {{ $('Webhook').item.json.body.company }}
      Budget: {{ $('Webhook').item.json.body.budget }}
      Message: {{ $('Webhook').item.json.body.message }}
      Why: {{ $json.output.reason }}
      

      The score and reason come from Claude ($json.output); the lead's details come from the Webhook step.

    3. Additional Fields → Add Field → Append n8n Attribution, switch off.

    4. After a test, the OUTPUT shows ok true: Telegram accepted the message.

False exit: the table.

  1. Click the + on the false exit of the If step, type data table and choose Insert row:

    Insert row in the Data table actions

  2. Rename it Save for later and set it:

    The Save for later step after a test

    1. Data table: From list → other leads.
    2. Under Values to insert, click Expression in each box and type:

      Column Value
      name {{ $('Webhook').item.json.body.name }}
      company {{ $('Webhook').item.json.body.company }}
      message {{ $('Webhook').item.json.body.message }}
      budget {{ $('Webhook').item.json.body.budget }}
      score {{ $json.output.score }}
      reason {{ $json.output.reason }}
    3. After a test, the OUTPUT shows the new row (1 item).

7. Test it with 3 leads

Do this once per test lead:

  1. Click Execute at the bottom of the canvas. n8n waits for a call to the Test URL.
  2. Send a lead. Normally your form does this; to try it yourself, run in a terminal (with your own address):

    curl -X POST https://yourname-n8n.agents.lsvps.net/webhook-test/new-lead \
      -H 'Content-Type: application/json' \
      -d '{"name":"Marta Silva","company":"Hotel Mar Azul","message":"We are a 40-room hotel in Cascais and need a new website with online booking, in Portuguese and English. We would like to launch before March. Can you send us a quote?","budget":"8000 EUR"}'
    

    n8n answers {"message":"Workflow was started"}.

Our other two test leads were:

{"name":"Joao Costa","company":"Cafe Central","message":"Hi, just curious how much a simple one-page website costs. Maybe next year.","budget":"300 EUR"}
{"name":"Rank Masters","company":"Rank Masters SEO","message":"We can put your agency on page 1 of Google in 30 days! Reply now for our special offer.","budget":""}

Each run took between 1 and 2 seconds. These are the scores Claude gave:

Lead Our score Claude's score Claude's reason Went to
Marta Silva, Hotel Mar Azul 5 5 Clear website project with bilingual booking system, 8000 EUR budget, and a defined launch timeline before March. Telegram
Joao Costa, Cafe Central 2 2 Budget is under 1,500 EUR and inquiry is for a future, not immediate, project. table
Rank Masters 1 1 This is an unsolicited SEO sales pitch, not a website project inquiry. table

Claude agreed with us on all 3 leads. The Telegram message for Marta was:

Hot lead (5/5): Marta Silva, Hotel Mar Azul
Budget: 8000 EUR
Message: We are a 40-room hotel in Cascais and need a new website with online booking, in Portuguese and English. We would like to launch before March. Can you send us a quote?
Why: Clear website project with bilingual booking system, 8000 EUR budget, and a defined launch timeline before March.

The two other leads are in the table (menu on the left → Overview → Data tables → other leads):

The other leads table

  1. The score column: 2 and 1.
  2. Total 2.

8. Publish it and connect your form

Click Publish at the top right, then Publish in the window. Then change the address in your form from /webhook-test/ to /webhook/ (the Production URL in the Webhook step). Details: Receive data with a webhook.

Note

We tested with the Test URL only and did not leave the workflow published.

Check that it worked

  • Before testing, write down the score you would give each test lead. Compare it with Claude's score in the If step or the table.
  • A lead with 4 or 5 must reach Telegram (ok true in Hot lead alert), and must not appear in the table.
  • A lead with 1 to 3 must appear in other leads, and no Telegram message is sent.

Make it yours

  • Your own scale: change the 5 lines of the scale in the prompt. Concrete rules (amounts, deadlines, the kind of work you do) give steadier scores than words like good or serious.
  • Alert only for 5: change the 4 in the If step to 5.
  • Keep every lead: add a second Insert row after Hot lead alert, so the table holds all leads.

Common problems

Problem in node 'Score 4 or more?': Wrong type: '5' is a string but was expecting a number

The JSON Example in the parser has the score in quotes ("score": "4"), so Claude's score arrives as text. We tried it: the run stopped at the If step with exactly this message. Remove the quotes ("score": 4) and test again.

A hot lead went to the table, with an empty score and reason

The Structured Output Parser is not connected to Score lead (there is a + under Output Parser instead of a dashed line to the parser). We tried it: n8n gave no error, Claude answered in plain text (Score: 5 ...), the If step found no score and sent the lead to false, and the table got a row with an empty score and reason. Connect the parser (step 4).

Telegram says: Bad Request: chat not found

The Chat ID is wrong, or you never pressed Start in your bot. See the contact form recipe.

Next steps