Bezplatný leadový bot v Telegramu na Pythonu s Yandex Cloud Functions
Vývojáři jednotlivých projektů a malých týmů mohou implementovat jednoduchou CRM na základě Telegramového bota bez žádných nákladů. Bot kvalifikuje přicházející zájemce prostřednictvím dvou otázek s inline tlačítky, vytváří samostatný téma ve supergrupě pro každého klienta a zajišťuje dvoustranný relay zpráv. Nasazení na Yandex Cloud Functions s bezplatným tierem: 1 milion volání a 1 GB Object Storage měsíčně.
Schéma: uživatel následuje deep link ze stránky → bot požaduje typ podnikání a úkol → vytvoří téma ve formátu «Ivan — E-commerce — AI-agent» → celá komunikace je agregována v grupě s vyhledáváním a oznámeními.
Minimální obálka kolem Telegram Bot API
Pro Cloud Functions jsou vhodná lehká řešení bez frameworků jako je aiogram. Cold start se minimalizuje, používá se čistý httpx. Celý API vrstva má 57 řádků:
"""telegram_api.py — tenká obálka kolem Bot API."""
import os
import httpx
BOT_TOKEN = os.environ.get("BOT_TOKEN", "")
BASE_URL = f"https://api.telegram.org/bot{BOT_TOKEN}"
def _call(method: str, **kwargs) -> dict:
resp = httpx.post(f"{BASE_URL}/{method}", json=kwargs, timeout=10)
return resp.json()
def send_message(chat_id, text, reply_markup=None, message_thread_id=None):
params = {"chat_id": chat_id, "text": text, "parse_mode": "HTML"}
if reply_markup:
params["reply_markup"] = reply_markup
if message_thread_id:
params["message_thread_id"] = message_thread_id
return _call("sendMessage", **params)
def create_forum_topic(chat_id, name):
return _call("createForumTopic", chat_id=chat_id, name=name)
def copy_message(chat_id, from_chat_id, message_id, message_thread_id=None):
params = {"chat_id": chat_id, "from_chat_id": from_chat_id, "message_id": message_id}
if message_thread_id:
params["message_thread_id"] = message_thread_id
return _call("copyMessage", **params)
copy_message je preferované před forward_message: vylučuje značku «Přesměrováno od…», zpráva vypadá čistěji.
Webhook handler s ověřením
Yandex Cloud Function zpracovává HTTPS požadavky přímo od Telegramu (allow-unauthenticated-invoke). Ověření pomocí X-Telegram-Bot-Api-Secret-Token:
def handler(event, context):
"""Vstupní bod pro Yandex Cloud Function."""
headers = event.get("headers", {})
secret = headers.get("X-Telegram-Bot-Api-Secret-Token") or \
headers.get("x-telegram-bot-api-secret-token", "")
if secret != WEBHOOK_SECRET:
return {"statusCode": 403, "body": "Forbidden"}
body = event.get("body", "{}")
update = json.loads(body) if isinstance(body, str) else body
if "callback_query" in update:
_handle_callback(update["callback_query"])
elif "message" in update:
_handle_message(update["message"])
return {"statusCode": 200, "body": "ok"}
Rozdělení na _handle_callback a _handle_message zjednodušuje logiku.
Bezstavová kvalifikace zájemců
Příkaz /start spustí průzkum: první otázka – typ podnikání, druhá – úkol. Callback data kóduje oba odpovědi: q2:sales:ecommerce. Limit 64 bajtů je dodržen pro přednastavení.
Příklad první otázky:
def _handle_start(chat_id, from_user):
if storage.get_topic_id_by_user(chat_id):
tg.send_message(chat_id,
"Už jste zanechal přihlášku. Kontaktujeme vás co nejdříve.
" "Pokud chcete něco přidat – stačí napsat zde.")
return
keyboard = {"inline_keyboard": [
[{"text": "E-commerce / Tržnice", "callback_data": "q1:ecommerce"}],
[{"text": "Služby / Servis", "callback_data": "q1:services"}],
[{"text": "Výroba", "callback_data": "q1:production"}],
[{"text": "IT / Startup", "callback_data": "q1:it"}],
[{"text": "Jiné", "callback_data": "q1:other"}],
]}
tg.send_message(chat_id, f"Ahoj, {from_user.get('first_name', '')}! Jsem bot VexAI.
" "Odpovězte na 2 krátké otázky, a spojíme se s vámi.")
tg.send_message(chat_id, "<b>Co dělá váš podnik?</b>", reply_markup=keyboard)
Ochrana proti duplikátům: kontrola mapování v Object Storage. Pro „Jiné“ – dočasný state-soubor.
Druhá otázka je stejná, s předáním q1_key v datovém poli.
Vytvoření tématu a relay
Po průzkumu se generuje téma s limitem 128 znaků:
def _finalize(chat_id, from_user, q1_answer, q2_answer):
tg.send_message(chat_id, "Děkuji! Kontaktujeme vás co nejdříve.")
full_name = f"{from_user.get('first_name', '')} {from_user.get('last_name', '')}".strip()
topic_title = f"{full_name} — {q1_answer} — {q2_answer}"
if len(topic_title) > 128:
topic_title = topic_title[:125] + "..."
result = tg.create_forum_topic(ADMIN_GROUP_ID, topic_title)
topic_id = result["result"]["message_thread_id"]
summary = (f"<b>Nový zájemce</b>\n\n"
f"<b>Jméno:</b> {full_name}\n"
f"<b>Podnikání:</b> {q1_answer}\n"
f"<b>Úkol:</b> {q2_answer}\n"
f"<b>Zdroj:</b> website")
tg.send_message(ADMIN_GROUP_ID, summary, message_thread_id=topic_id)
storage.save_topic_mapping(topic_id, chat_id)
storage.save_user_mapping(chat_id, topic_id)
Relay v _handle_message:
- Admin píše do tématu → kopíruje se klientovi.
- Klient píše botovi → kopíruje se do tématu.
Podpora deep linků: /start website pro sledování zdroje.
Nastavení a omezení
- Vytvořte supergrupu, povolte témata.
- Přidejte bota-admina: správa témat, odesílání zpráv.
- Nakonfigurujte Yandex Cloud: službový účet
storage.editor, bucket, přístupové klíče. - Nastavte webhook s tajným tokenem.
Získáte:
- Hledání podle zájemců.
- Oznámení.
- Upevněné karty.
Omezení: žádné funnely, analýzy, spolupráce týmu. Ideální pro 20 zájemců/měsíc.
Co je důležité
- Bezplatné nasazení: Yandex Cloud Functions + Object Storage v free tier.
- Bezstavový design: callback data uchovává stav, minimální úložiště.
- Funkce relay: plná komunikace v tématech bez externích aplikací.
- Ochrana: tajný token + antikopie.
- Škálovatelnost: až 20 zájemců/měsíc bez placené CRM.
— Editorial Team
Zatím žádné komentáře.