Skip to content

Leads missing or fallback

The engineer on call and the person who processes sales requests in the leads group.

  • Normal path: landing form → POST /leads on 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_REJECTED in 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.

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.

  1. Secret mismatch between Vercel LEADS_SECRET and the server LEADS_SECRET → 401 → B.
  2. The leads module is off on the server (LEADS_ENABLED=0 or empty LEADS_SECRET) → 404 → B.
  3. The API or Caddy is down, or answered slower than 5 seconds → B.
  4. LEADS_ENDPOINT or LEADS_SECRET is not set in Vercel (or the deployment predates them) → C.
  5. 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_ID is wrong → A, F.
  6. 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 on 429.
  7. The bot runs without the leads router (LEADS_ENABLED=0, LEADS_CHAT_ID empty or different, old code) → D.
  8. The person is not in LEADS_ADMIN_IDS → E.
  9. Validation disagreement between landing and server → 422, no fallback, visitor sees an error.
Terminal window
# did the server receive and store it
journalctl -u sticker-api --since -1h --no-pager -o cat | grep 'LEAD_'
# did the bot publish it; is the bot an administrator of the group
journalctl -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 published
sqlite3 -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.

Terminal window
E=/opt/ai-sticker-pack/bot/.env
setenv() { grep -q "^$1=" $E && sed -i "s/^$1=.*/$1=$2/" $E || echo "$1=$2" >> $E; }
setenv LEADS_ENABLED 1
bash /opt/ai-sticker-pack/deploy/update.sh --yes

LEADS_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-bot and check for LEADS: бот в группе … — 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).

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.

  1. Reply to the person using the contacts in the message. Do not wait for the system to fix itself.

  2. Track its status yourself (for example, reply to the message in the group with the outcome).

  3. 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"}'

    201 with "duplicate":false → stored now; a normal card follows. 200 with "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.

  4. 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.

Submit a test request from the form with ТЕСТ in the name.

Terminal window
journalctl -u sticker-api --since -2min --no-pager -o cat | grep LEAD_NEW
journalctl -u sticker-bot --since -2min --no-pager -o cat | grep LEAD_PUBLISHED

Expected: 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> тест.

  • Keep TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID set in Vercel. They are the fallback; without them a server outage loses requests.
  • After any change to LEADS_SECRET on 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.

Last verified: 2026-11-13 against ai-sticker-pack@b715418 and ai-stickers-landing@e350ff5.