Skip to content

ADR-010: Send the link only after the pack is verified; never reuse a pack name

Developers and operators — read this before touching delivery, pack naming or the “pack is ready” message.

  • The link is sent only when the Bot API reports 12 stickers and the public t.me/addstickers/<name> page confirms the pack twice in a row.
  • Pack names are pack<N>_<telegram_user_id>_by_<bot_username>; a name is never deleted, recreated or reused.
  • Status: accepted.

Right after a sticker set is created, the link can open to “Sticker set not found” for some seconds. A guest who taps a dead link at an event walks away without a pack. Telegram clients also cache pack names, so a pack deleted and recreated under the same name stays “not found” on devices that saw the old one.

A second trap: the public page always answers HTTP 200, whether the pack exists or not. Only the page’s title differs. One test request also returned an empty body because of a network glitch.

  • After createNewStickerSet the job moves to delivering and the worker slot is released.
  • A background check polls every 2 seconds for the first 90 seconds, then every 10 seconds (bot/delivery.py).
  • “Ready” means: getStickerSet returns 12 stickers, and the public page shows the “pack exists” title on two consecutive requests with a short pause. Anything else — missing title, network error, non-200 — counts as “not ready” (bot/services/telegram_stickers.py). Real captured pages are test fixtures.
  • The link is sent exactly once (jobs.link_sent_at).
  • Names are numbered per account. The next number follows every pack the account ever had, including packs from reset accounts and interrupted attempts. If a name is taken, the next number is used.
  • Telegram’s naming rules (length, first character, no double underscore, the _by_<bot> suffix) are checked in code. The actual name is stored in jobs.pack_name and users.pack_name; links are built only from it.
Alternative Why not
Send the link immediately with a “wait 10–15 seconds” hint Guests tap at once; a dead first impression. The hint text still exists in the code, unused.
Trust the HTTP status of the public page It is always 200.
Delete a broken pack and recreate it with the same name Client-side caches keep it “not found”.
  • Delivery adds a couple of seconds: the load test measured about 2 seconds for the link check (LOAD_TEST_REPORT.md).
  • The check depends on the wording of a public Telegram page. If Telegram changes it, every pack will look “not ready” and fail at the 15-minute deadline — the first thing to suspect when all deliveries stall.
  • Orphan packs from interrupted attempts stay in Telegram forever; this is accepted.
  • tools/check_pack.py runs the same two checks by hand.
  • HANDOFF.md, “Pack names” and “The ‘pack exists’ signal on t.me”; fixtures tests/fixtures/tme_pack_*.html.
  • Commits 914f47f, 9fca59c, ac2a366.

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