Leads missing or fallback
Who is this for
Section titled “Who is this for”The engineer on call and the person who processes sales requests in the leads group.
- Normal path: landing form →
POST /leadson the API (stores the lead) → the bot publishes a card with status buttons in the leads group. - A message that starts with
⚠️ Запасной каналcame straight from the landing because the server did not accept it. It is not in the database: handle it by hand. - No card at all: check the API log for
LEAD_NEW. If the lead is stored, the bot will publish it when it can; nothing is lost. LEAD_REJECTEDin the API log means the secret on Vercel and on the server differ.- Buttons answering
Заявки сейчас не ведутся этим ботом…mean the bot runs without the leads module or the card belongs to another chat.
Symptom
Section titled “Symptom”One of:
-
A. A request was sent from the landing and nothing appears in the group.
-
B. A message appears with this first line and no buttons:
⚠️ Запасной канал: сервер заявок не ответил — заявки нет в базе (request_id <uuid>)Gloss: “Fallback channel: the leads server did not answer — the request is not in the database.”
-
C. A message appears without that line and without buttons (plain
AI Sticker Pack — заявка с лендинга). -
D. Pressing a status button shows a pop-up:
Заявки сейчас не ведутся этим ботом: модуль выключен или карточка из другого чата. Когда модуль включён — /stickers_lead <номер> пришлёт карточку заново.(“Leads are not handled by this bot right now: the module is off or the card is from another chat.”) -
E. Pressing a button shows
Нет доступа(“no access”), or/stickers_*commands get no answer. -
F. Alert:
Заявка #N не публикуется в группу заявок уже K раз: …(“lead #N has failed to publish K times”) orЗаявки: больше 60 за час — лишние отклоняются (429)(“more than 60 leads per hour — the rest are rejected”). -
G. The visitor sees “too many requests, try later” on the form and nothing arrives.
Likely causes
Section titled “Likely causes”- Secret mismatch between Vercel
LEADS_SECRETand the serverLEADS_SECRET→401→ B. - The leads module is off on the server (
LEADS_ENABLED=0or emptyLEADS_SECRET) →404→ B. - The API or Caddy is down, or answered slower than 5 seconds → B.
LEADS_ENDPOINTorLEADS_SECRETis not set in Vercel (or the deployment predates them) → C.- The lead is stored but the bot cannot publish: the bot is down, was removed from the group, is not an administrator, or
LEADS_CHAT_IDis wrong → A, F. - Rate limits: more than 5 requests from one visitor in 10 minutes, more than 60 per hour in total, or 5 wrong-secret calls from one address →
429→ G. The landing does not fall back on429. - The bot runs without the leads router (
LEADS_ENABLED=0,LEADS_CHAT_IDempty or different, old code) → D. - The person is not in
LEADS_ADMIN_IDS→ E. - Validation disagreement between landing and server →
422, no fallback, visitor sees an error.
Diagnose
Section titled “Diagnose”# did the server receive and store itjournalctl -u sticker-api --since -1h --no-pager -o cat | grep 'LEAD_'
# did the bot publish it; is the bot an administrator of the groupjournalctl -u sticker-bot --since -1h --no-pager -o cat | grep -E 'LEAD_PUBLISH|LEAD_BUTTON_ORPHAN|LEAD_STATUS_DENIED'journalctl -u sticker-bot --no-pager -o cat | grep 'LEADS:' | tail -5
# leads stored but not yet publishedsqlite3 -readonly /opt/ai-sticker-pack/bot/data/app.db \ "SELECT id, publish_attempts, created_at FROM leads WHERE published_at IS NULL;"
# is the module configured (prints names and whether a value is present, never the value)grep -E '^LEADS_(ENABLED|CHAT_ID|ADMIN_IDS|SECRET|IP_SALT)=' /opt/ai-sticker-pack/bot/.env | sed 's/=.\+/=<set>/'On the landing side: Vercel → the project → Logs, search for [request].
| Log line | Where | Meaning |
|---|---|---|
LEAD_NEW #N request_id=… locale=… utm_source=… |
API | Stored. Publishing is the bot’s job. |
LEAD_DUPLICATE #N / LEAD_REPEAT #N |
API | Same request_id again, or the same contact within 24 hours: no new card, the existing one is updated |
LEAD_REJECTED неверный секрет от … (“wrong secret”) |
API | Cause 1 |
LEAD_RATE_LIMITED посетитель … / больше N заявок за час |
API | Cause 6 |
LEAD_INVALID поля [...] (“invalid fields”) |
API | Cause 9; the list names fields, not values |
No LEAD_ line at all for the test request |
API | The request never reached the API: causes 2, 3 or 4 |
LEAD_PUBLISHED #N message_id=… |
Bot | Card posted |
LEAD_PUBLISH_FAILED #N попытка K: …chat not found / Forbidden… |
Bot | Cause 5 |
LEAD_PUBLISH_RETRY #N: Telegram просит подождать … |
Bot | Telegram flood control; it retries by itself |
LEADS: бот в группе … — administrator |
Bot, at start | Good |
LEADS: бот в группе … не админ… / LEADS: бот не в группе … |
Bot, at start | Cause 5 |
LEADS: выключено (LEADS_ENABLED=…, LEADS_CHAT_ID …) (“off”) |
Bot, at start | Cause 7 |
LEAD_BUTTON_ORPHAN user=… chat=… data=… |
Bot | Cause 7 |
LEAD_STATUS_DENIED user=… |
Bot | Cause 8 |
[request] leads server responded 401 … — fallback |
Vercel | Cause 1 |
[request] leads server responded 404 … — fallback |
Vercel | Cause 2 |
[request] leads server unreachable … (TimeoutError) — fallback |
Vercel | Cause 3 |
[request] leads server throttled … |
Vercel | Cause 6 |
[request] leads server rejected … (422) |
Vercel | Cause 9 |
[request] … is lost |
Vercel | Server failed and the fallback bot is not configured or failed: the request exists only in this log |
1 — secret mismatch. Put the same value on both sides, following the order in
Secrets → LEADS_SECRET. A changed Vercel variable needs a Redeploy; a
changed server value needs systemctl restart sticker-api.
2 — module off on the server.
E=/opt/ai-sticker-pack/bot/.envsetenv() { grep -q "^$1=" $E && sed -i "s/^$1=.*/$1=$2/" $E || echo "$1=$2" >> $E; }setenv LEADS_ENABLED 1bash /opt/ai-sticker-pack/deploy/update.sh --yesLEADS_SECRET, LEADS_IP_SALT and LEADS_CHAT_ID must be set too: see
Deploy and rollback.
3 — API or Caddy down. Kiosk 502. While it is down, leads keep arriving through the fallback channel.
4 — Vercel variables missing. Vercel → Settings → Environment Variables → set LEADS_ENDPOINT and LEADS_SECRET
for Production → Redeploy.
5 — bot cannot publish.
- Bot stopped:
systemctl restart sticker-bot. Stored leads are published within seconds of the start. - Bot not in the group or not an administrator: add it to the group and promote it to administrator, then
systemctl restart sticker-botand check forLEADS: бот в группе … — administrator. - Wrong
LEADS_CHAT_ID: correct it (supergroup ids start with-100), restart the bot.
Until it is fixed, stored leads can still be read: /stickers_new in the group, or /stickers_export for a CSV in a
private chat. Publishing is retried after 5 s, 15 s, 60 s, 5 minutes, then every 15 minutes; the alert comes after the
fifth failure.
6 — rate limits. A burst from one visitor clears after LEADS_IP_WINDOW_SEC (10 minutes). If the hourly alert
fired and the leads are real (an advertising spike), raise LEADS_HOURLY_LIMIT and restart the API; if it is spam, do
nothing. Counters live in memory, so systemctl restart sticker-api clears them, including a wrong-secret block.
7 — buttons answer “leads are not handled”. Enable the module (cause 2) and make sure LEADS_CHAT_ID is the id of
the group where the card is. After the restart, old cards work again; /stickers_lead <N> re-posts a card.
8 — no access. Add the person’s numeric Telegram id to LEADS_ADMIN_IDS, systemctl restart sticker-bot. Make them
a group administrator as well so they see the command menu.
9 — 422. The landing and the server disagree on field rules: a bug. Note the field names from the log and hand
it to a developer. The visitor’s request is not delivered; if they contact you another way, enter it by hand (below).
Handling a fallback lead by hand
Section titled “Handling a fallback lead by hand”A ⚠️ Запасной канал message is not in the database. It has no status buttons, no reminder, no place in
/stickers_stats, /stickers_new or the CSV export, and /stickers_forget cannot erase it.
-
Reply to the person using the contacts in the message. Do not wait for the system to fix itself.
-
Track its status yourself (for example, reply to the message in the group with the outcome).
-
Optional — put it into the database. The server deduplicates on
request_id, so re-submitting with the id from the marker line is safe:Terminal window S=$(grep '^LEADS_SECRET=' /opt/ai-sticker-pack/bot/.env | cut -d= -f2-)curl -s -X POST https://stickers.eventtalks.uz/leads \-H "Content-Type: application/json" -H "X-Stickers-Leads-Secret: $S" \-d '{"request_id":"<uuid from the marker line>","name":"Guest Name","telegram":"@example_user","phone":"+<digits>","locale":"ru"}'201with"duplicate":false→ stored now; a normal card follows.200with"duplicate":true→ the server had already stored it (only its answer was lost); a normal card already exists next to the fallback message. Optional fields:date,guests,comment,utm. -
If the person later asks for their data to be deleted, delete the fallback message in the group by hand (a group administrator can do this), in addition to
/stickers_forget <N>for the database copy.
A message of type C (no marker, no buttons) is the same situation: handle it the same way. It has no request_id;
generate one with cat /proc/sys/kernel/random/uuid if you re-submit it.
Verify
Section titled “Verify”Submit a test request from the form with ТЕСТ in the name.
journalctl -u sticker-api --since -2min --no-pager -o cat | grep LEAD_NEWjournalctl -u sticker-bot --since -2min --no-pager -o cat | grep LEAD_PUBLISHEDExpected: both lines, and a card with buttons and without the ⚠️ line in the group. Press a status button: the
card updates. Then remove the test lead: /stickers_forget <N> тест.
Prevent
Section titled “Prevent”- Keep
TELEGRAM_BOT_TOKENandTELEGRAM_CHAT_IDset in Vercel. They are the fallback; without them a server outage loses requests. - After any change to
LEADS_SECRETon either side, send a test request. - Keep the bot an administrator of the leads group; check the
LEADS:start-up lines after every restart. - Maintenance mode and the “out of money” pause do not affect leads. Nothing needs to be done for them during a pause.
- Check the group for
⚠️messages after any API outage.
Where to go next
Section titled “Where to go next”- Secrets — rotating the shared secret without a long window.
- Lead submission flow — the full path with the fallback branch.
- Lead process — what the sales side does with a card.
- Runbooks — back to the symptom table.
Last verified: 2026-11-13 against ai-sticker-pack@b715418 and ai-stickers-landing@e350ff5.