System context
Who is this for
Section titled “Who is this for”A newcomer who needs the big picture before any detail: who touches the system, what it talks to, and where its responsibility ends.
- Five kinds of people use the system: the guest, the event operator, the lead admin in a Telegram group, the site visitor (an event organiser) and the developer/owner.
- The system depends on Telegram (Bot API and public
t.mepages), two AI providers (Gemini primary, OpenAI fallback), Vercel (landing hosting) and one DigitalOcean droplet (API, bot, database, files). - The guest never installs anything and never creates an account: a QR code and their own Telegram are enough.
- The result is a real Telegram sticker set owned by the guest’s Telegram account, delivered as a link in the bot.
- The system does not take payments, does not keep photos (files are deleted within
PHOTO_TTL_HOURS, at most 72 hours) and does not expose any webhook to Telegram.
Context diagram
Section titled “Context diagram”flowchart TB
guest["Guest at an event"]
operator["Event operator or staff"]
leadadmin["Lead admin in the Telegram group"]
visitor["Site visitor - event organiser"]
dev["Developer and owner"]
system["AI Sticker Pack - kiosk page, API, bot with worker, landing page"]
telegram["Telegram - Bot API, t.me pages, client apps"]
ai["AI providers - Gemini primary, OpenAI fallback"]
vercel["Vercel - hosts the landing page"]
droplet["DigitalOcean droplet - hosts API, bot, database, files"]
tls["DNS and Let's Encrypt certificates via Caddy"]
guest -- "taps Start, picks an outfit, is photographed" --> system
guest -- "scans QR, gives consent, receives the pack link" --> telegram
operator -- "sets up the tablet, watches the admin panel and alerts" --> system
leadadmin -- "presses status buttons, runs group commands" --> telegram
visitor -- "reads the landing, submits a request" --> system
dev -- "deploys over SSH, edits configuration" --> system
system -- "long polling, messages, sticker set creation" --> telegram
system -- "selfie and prompt in, sticker sheets and JSON out" --> ai
system -. "landing runs on" .-> vercel
system -. "server parts run on" .-> droplet
system -. "HTTPS certificates" .-> tls
Solid arrows are interactions. Dotted arrows mean “is hosted on” or “depends on for infrastructure”.
People
Section titled “People”| Person | What they do | How they reach the system |
|---|---|---|
| Guest | Taps Start on the tablet, scans the QR code with their phone, presses the consent button in the bot, picks an outfit on the tablet, looks at the camera, later opens the sticker set link | The kiosk page on the tablet, and a private chat with the Telegram bot on their own phone |
| Event operator / staff | Opens the kiosk page on the tablet, grants camera permission once, resets a stuck station (long press on a hidden zone), watches the admin panel, reacts to alerts, grants an extra pack or retries a failed job | The kiosk page; the web admin panel at https://stickers.eventtalks.uz/admin (HTTP Basic); bot commands /stats, /admin_stats, /pause, /resume for the Telegram users listed in ADMIN_USER_IDS; alert messages in the chat set by ADMIN_CHAT_ID |
| Lead admin | Works with requests from organisers: presses a status button on a request card, lists open requests, exports CSV, erases a person’s data on request | The Telegram group set by LEADS_CHAT_ID. Only the Telegram users listed in LEADS_ADMIN_IDS may press buttons or run /stickers_* commands |
| Site visitor / organiser | Reads the landing page in Russian, Uzbek or English and submits the request form | https://pack.eventtalks.uz in a browser |
| Developer / owner | Changes code, deploys, edits bot/.env, tops up the AI provider balance |
SSH to the droplet (deploy scripts in deploy/), the Vercel project, the AI provider consoles |
One person may hold several roles. The roles are separated by configuration, not by accounts in the system:
ADMIN_USER_IDS, LEADS_ADMIN_IDS, the admin panel login and SSH access are four independent lists.
External systems
Section titled “External systems”| System | What it is used for | Direction |
|---|---|---|
| Telegram Bot API | Receiving updates by long polling (getUpdates), sending messages, createNewStickerSet, getStickerSet, getChat, getChatMember, setMyCommands |
The server always opens the connection. There is no webhook, so Telegram never connects to the server |
t.me public pages |
The deep link in the QR code (https://t.me/<bot_username>?start=<session_token>), the pack link (https://t.me/addstickers/<pack_name>) and the readiness check: the bot fetches the pack page and reads its og:title |
Guest’s phone opens the links; the bot fetches the pack page over HTTPS |
| Gemini (Google) — primary AI provider | Image generation (sticker sheets, anchor portrait, single-figure regeneration) and cheap vision calls that return JSON (appearance description, quality checks) | The bot process calls the provider SDK over HTTPS |
| OpenAI — fallback AI provider | The same two roles when the primary provider fails for a call. Which provider is primary is configuration (PRIMARY_AI_PROVIDER, FALLBACK_AI_PROVIDER), not code |
The bot process calls the provider SDK over HTTPS |
| Vercel | Hosts the Next.js landing page and runs its server action. The landing domain is set there through NEXT_PUBLIC_SITE_URL; it is not stored in the repository |
The server action calls the leads endpoint, and Telegram directly as a fallback |
| DigitalOcean | One droplet runs Caddy, sticker-api, sticker-bot, the SQLite file and the photo files. The droplet is shared with a second, unrelated project |
— |
| DNS and Let’s Encrypt | Caddy obtains and renews the certificate for stickers.eventtalks.uz automatically. HTTPS is mandatory: the browser camera API (getUserMedia) works only on HTTPS or localhost. Where the DNS zone is hosted is not recorded in either repository |
Caddy contacts Let’s Encrypt |
What the system does
Section titled “What the system does”- Links a tablet session to a Telegram user through a one-time QR token.
- Records explicit consent before anything else happens; without it the outfit screen never opens.
- Accepts one photo per session, strips EXIF by re-encoding, and queues a generation job.
- Generates 12 stickers of the guest with an image model, checks them, and repairs single stickers when a check fails.
- Creates a Telegram sticker set in the guest’s name and sends the link only after the set is confirmed to open.
- Enforces a pack limit per Telegram account: one pack, plus extra packs granted by an operator.
- Records every AI call with an estimated cost, stops a job that exceeds
JOB_MAX_COST_USD, and pauses new jobs when the provider reports that the balance is exhausted. - Deletes photos and derived images by TTL and clears the textual appearance description when a job ends.
- Accepts organiser requests from the landing page, stores them, posts them to a Telegram group, reminds about unhandled ones, sends a daily digest and anonymises old ones.
What the system does not do
Section titled “What the system does not do”| Not done | What happens instead / why it matters |
|---|---|
| No payments, invoices or pricing logic | Sales happen outside the system; the landing form only collects a request |
| No guest accounts, passwords or e-mail | Identity is the guest’s Telegram user id |
| No Telegram webhook | The bot long-polls. The only inbound HTTP on the server is the kiosk, the admin panel and POST /leads |
| No photo in the database | The database stores a file path only; the file lives on disk until the pack is created or the TTL passes |
| No result on the tablet | The kiosk never waits for generation. The pack arrives in Telegram |
| No outfit choice in the bot | Outfits are chosen on the tablet, after consent |
| No deletion or re-creation of a sticker set on Telegram | A created set is never deleted or recreated under the same name, because Telegram clients cache the state of a name. Resetting a guest in the admin panel removes database rows, not the set |
| No multi-tenancy | One bot token, one database, one kiosk domain. See Multi-tenant |
| No CRM, mailing or lead scoring | A lead has six statuses and a history of who changed them; everything else is manual |
| No Docker | Processes run directly under systemd from a Python virtual environment |
Where to go next
Section titled “Where to go next”- Containers — the same picture one level down: processes, ports, protocols.
- Flow: guest session — the guest’s path step by step.
- Privacy — what personal data each actor leaves behind.
- What is AI Sticker Pack — the product description without architecture terms.
Last verified: 2026-11-13 against ai-sticker-pack@b715418 and ai-stickers-landing@e350ff5.