4.9 KiB
4.9 KiB
AI Lead Funnel — Echogate LLM + Telethon
Full runnable pattern for Telegram accounts that auto-respond to DMs using LLM.
When to use
- User wants a Telegram account to auto-respond to incoming messages
- Redirect leads to a target contact (@lordrax, etc.)
- Need a human-like operator that filters and redirects
Key design decisions
- Stage-gated dialog, not free-form LLM — LLM is too eager to share contact immediately or too chatty. Use 3 hardcoded stages with separate system prompts.
- Processing lock per user —
asyncio.Eventorset()to prevent parallel handler invocations. - Typing indicator before every message —
SetTypingRequest(SendMessageTypingAction())+asyncio.sleep(3-10s). - State persistence — JSON file with
stage,history,doneper user. Survives restarts.
LLM config
from openai import AsyncOpenAI
llm = AsyncOpenAI(
base_url="https://api.echogate.one/v1",
api_key="[REDACTED]",
timeout=60,
)
# gpt-5.5: ~3s response — fast enough for real-time
# deepseek-v4-pro: ~21s — too slow, breaks the illusion
Stage prompts
STAGE_PROMPTS = {
0: """Ты — оператор. Строгий, деловой, немногословный.
Это ПЕРВОЕ сообщение в диалоге. Ответь коротко (1 предложение).
Поприветствуй и спроси что интересует / по какому вопросу.
НЕ давай контакты. НЕ упоминай @target. НЕ давай ссылки.
НЕ используй эмодзи. Стиль: спокойный, уверенный, без лишней вежливости.""",
1: """Ты — оператор. Строгий, деловой.
Это ВТОРОЕ сообщение. Ответь на вопрос пользователя коротко (1-2 предложения).
Упомяни что детали, цены и наличие — у партнёра @target.
НЕ давай прямую ссылку пока. НЕ используй эмодзи.
Стиль: уверенный, деловой. Не извиняйся, не будь подобострастным.""",
2: """Ты — оператор. Строгий, деловой.
Это ТРЕТЬЕ (финальное) сообщение. Дай прямую ссылку.
Скажи обратиться туда, это всё. Закругляйся.
1 предложение. НЕ продолжай диалог. НЕ используй эмодзи.""",
}
Processing lock pattern
processing = set() # Track user_ids currently being processed
@client.on(events.NewMessage(incoming=True))
async def handler(event):
uk = str(event.sender_id)
if uk in processing:
log(f"Already processing {uk}, skip")
return
processing.add(uk)
try:
# ... generate and send reply ...
finally:
processing.discard(uk)
Race condition: why it happens
When two messages arrive within 2 seconds (e.g. user sends empty message then "привет"), the Telethon event handler fires twice in parallel. Both invocations see the same state (stage=0, our_count=0), both generate Stage 0 replies, and both send simultaneously. Result: two greeting messages back-to-back, no dialog.
The processing lock prevents this — the second invocation sees uk in processing and skips.
Fallback messages
Always have hardcoded fallbacks per stage in case LLM times out:
FALLBACKS = {
0: "Добрый. По какому вопросу?",
1: "По наличию и ценам — обратись к @target",
2: "Напиши @target: https://t.me/target",
}
Full runnable script
See C:\Users\User\Desktop\_PROJECTS\рассылка\lead_funnel.py for the production version with:
- echogate.one LLM integration
- 3-stage dialog with processing lock
- Typing indicator + random delays
- JSON state persistence
- @Tomitotototo → @lordrax funnel
Pitfalls learned 2026-08-11
- JSON account metadata is stale:
sessions/*.jsonfiles saystatus: "Active",spamblock: "none"but 90%+ of accounts are actually RESTRICTED/BANNED. Always verify by connecting and sending a test message to "me". - SpamBot "RESTRICTED" ≠ can't DM: Account may be RESTRICTED for groups but perfectly fine for private messages. The real test is
client.send_message("me", "test"). - Free-form LLM fails: Without stage-gating, LLM either shares contact immediately (no dialog) or never shares it (endless chat). Hardcode stages.
- No processing lock = duplicate messages: Parallel handler invocations on rapid-fire messages produce duplicate greetings.
- deepseek-v4-pro is 21s: Too slow for real-time. gpt-5.5 is 3s. Pick fast models.
- No skip phrases in lead funnel: Respond to EVERYTHING — "ку", "привет", empty messages. No intent detection needed.