We built a service that watches open Telegram chats and surfaces people who are actively looking
to buy something. After processing 542,795 keyword-matched messages in production, here is the
number that defines the whole problem:
97.3% of them were junk. Only 14,774 were real purchase requests.
That is roughly 36 useless messages per 1 real lead. Last 30 days alone: 7,945 real requests
against 363,508 rejected.
If you are thinking about building keyword monitoring for lead generation, this post is the thing
I wish someone had told me before we started.
Why keyword matching fails so badly
The naive approach is obvious: pick keywords, match messages, get leads. It works for about a week.
The noise is not random garbage. It is specifically the stuff that looks exactly like a lead:
- Competitor ads. They use the same words a buyer would. "Ищу клининг" (looking for cleaning) and a cleaning company's ad both contain "клининг".
- Job postings. "Требуется мастер" (master needed) matches every keyword a repair service has.
- Reposts and cross-promotion. Same text, many chats, multiplied by the number of chats you watch.
- Discussion without intent. People talk about renovation constantly. Almost none of them are hiring a contractor right now.
A keyword is a subject signal. It carries no intent signal at all. "ищу риелтора"
(looking for a realtor) and "ищу приключений" (looking for adventure) share a token and mean
nothing alike.
The architecture that actually works
Telegram open chats
│
▼
[1] keyword / stop-word prefilter ← cheap, high recall, ~97% false positives
│
▼
[2] LLM intent classifier ← "is this a real request to buy?"
│
├─ rejected → log
└─ passed → lead (hot / warm / cold) + draft reply
Stage 1 must stay broad. Every attempt we made to encode intent into the keyword list itself
made recall collapse: you start losing real requests because people phrase them in ways you did
not predict. Keep it dumb and permissive, let stage 2 do the thinking.
Stage 2 is where the product lives. Our classifier returns three classes:
- hot — explicit, ready now: "ищу клининг после ремонта, когда можете подъехать?"
- warm — asking for advice, no deadline or budget yet
- cold — topic-adjacent, low intent
Noise rate varies wildly by niche
This surprised us. Real data from client accounts, 60-day window, anonymised to niche + region:
| Niche | Region | Chats | Leads | Days | Hot | Noise |
|---|---|---|---|---|---|---|
| Price monitoring SaaS | Russia | 448 | 402 | 40 | 65 | 67.3% |
| White imports from China | Russia | 482 | 1,174 | 34 | 525 | 80.0% |
| Product certification | Russia | 165 | 751 | 57 | 262 | 87.3% |
| Apartment renovation | Moscow reg. | 49 | 161 | 11 | 44 | 88.5% |
| Debt relief lawyers | Moscow reg. | 811 | 174 | 24 | 56 | 92.0% |
| Marketplace fulfilment | Russia | 190 | 415 | 39 | 98 | 93.1% |
| Realtor | Blagoveshchensk | 189 | 166 | 46 | 33 | 95.4% |
| Cleaning company | Moscow | 272 | 201 | 19 | 159 | 97.3% |
The pattern: the more common the vocabulary, the worse the noise. "Уборка" (cleaning) appears
in chats constantly and almost never means "I want to order cleaning". Meanwhile a narrow B2B term
like "репрайсер" (repricer) is almost self-filtering.
Practical consequence: niche determines your infrastructure cost. A cleaning client needs ~36x more
classifier calls per delivered lead than a narrow B2B client.
A measurement trap that will fool you
When a new account connects, the system scans chat history. That first day produces a huge
batch of leads at once.
In one account, 417 of 1,174 leads arrived on day one. If you compute "leads per day" naively,
you report 34.5/day when the real steady-state is much lower. Two of our accounts had all their
leads on a single day — pure backfill, zero ongoing flow.
Always exclude the first active day before computing rate, and drop accounts with a single
active day entirely. We nearly published inflated numbers because of this.
Stop-words carry more weight than keywords
Generic set that applies to nearly any niche (Russian, but the categories translate):
# hiring, not buying
вакансия, ищем сотрудника, требуется, резюме, зарплата, оклад, на работу
# someone selling, not buying
предлагаю услуги, оказываю услуги, наша компания, обращайтесь, прайс,
портфолио, скидка, акция, подписывайтесь, реклама, промокод
# channel noise
переслано, репост, кто знает чат, админ, правила группы
Niche-specific additions matter more. For cleaning: уборщица, пылесос купить,
генеральная уборка сама.
Speed beats price
Lead temperature decays fast. In a 500-flat residential chat, a cleaning request collects several
competing replies within the hour. The first clear answer with a price and a time slot wins far
more often than the cheapest one sent next morning.
This changes the product requirement: it is not enough to find the lead, you have to deliver it
while it is still warm, and ideally hand over a draft reply.
Full dataset and per-niche breakdown:
mpleads.ru/kejsy-po-nisham
The service itself is Leadolovets — commercial, Russian market, 5-day free
trial. The documentation and stop-word recipes are public on
GitHub.
Happy to answer questions about the classifier setup in the comments.
Top comments (0)