UNLOCK: Interactive Greeting Cards and Advent Calendars
our own studio service: a card behind a password link, managed from Telegram
Our own service for interactive greeting cards and advent calendars: the recipient cracks a locked terminal, and the owner edits everything from a Telegram bot and a web cabinet. Python, aiohttp, PostgreSQL.
The task
An ordinary greeting card is a picture or a template landing page that the recipient scrolls past in a second. Nobody will deploy and pay for a separate backend-driven site for every personal occasion. We needed a way to turn a link into a small story without launching a new project for each client.
Additional requirements:
- the service owner creates and edits cards alone, from a phone, without a developer;
- one card is sent to many guests, and each sees their own name;
- clients can be connected and limited by a plan;
- a card opens on a weak phone and does not go down with the server.
The solution
An interactive card is a page where the recipient does something themselves: solves, chooses, opens. We built it as a locked terminal and added an admin panel in Telegram.
What was implemented:
- A card behind a link with a password screen, the Recovery Protocol, three screens and a finale; the recipient's choice goes to the owner's Telegram.
- A card-creation wizard in the bot with five questions: occasion, to whom, from whom, when, key.
- Seven themes: Romance, Marksman, Bunker, Birthday, Wedding, Neon and Noir.
- A web cabinet with a live preview: fields on the left, the card on the right, and a «How it went» report showing how far the recipient got.
- One card for many guests: the name in the link, bulk link generation, and export of guests and replies to CSV.
- An advent calendar: windows by day, four styles, and the password and date checked by the server.
- Plans, owner, operator and client roles, invitation codes, private cards and closed drafts.
- Delayed publishing, a QR code for the link, a webhook for submissions, and a showcase landing page for the service with demo cards.
How it works
A card made of one HTML file
The card page is a single static HTML file: no build step, no dependencies, no backend. The font sits next to it, the fireworks are drawn by its own code, and sound effects are synthesised with Web Audio. It gets its theme and texts from the service but keeps its own copy of the values, so when the service is unavailable it opens on those and on the cache of the last visit. The copy is not written by hand: a sync_site_defaults command generates it from the service schema, and the smoke tests fail if the file drifts from the schema.
A web cabinet as a Telegram Mini App
A Mini App is a web page that opens inside Telegram. Sign-in needs no passwords: Telegram passes signed data about the user, and the service verifies the signature with the bot token on every request. Permissions are the same as in the chat: a client sees only their own cards. On a computer the cabinet opens through a one-time link from the bot: it lives for 10 minutes and is spent only by pressing a button, so messenger link previews do not burn it. The database stores only token hashes, and a session lasts 30 days.
One card for many guests: the name in the link
A birthday, a wedding, a company event: many recipients, one card. A link like «/c/address?to=Name» puts the name into the terminal, the greeting, the ticket and the preview. Without the parameter, the name from the card itself is used, so links sent earlier keep working. The report shows who opened, how far they got and who replied, including those who stayed silent.
The advent calendar: the server checks the password and the date
In a card the key is part of the game; in a calendar it guards the gift. A window's contents and files reach the browser only after two server checks: the password is right and the day has come. A window opens at midnight in the recipient's time zone, and missed days are not lost. Letter case, the letter «ё» and extra spaces in the password are ignored.
A link preview for every card in messengers
A messenger's robot does not run scripts and reads only what is baked into the file. So the service serves the page at «/c/address» and inserts the title, description and image of that very card. Without this, every client would show the same link card in a chat.
Plans and client roles
Each plan has three numbers: how many cards, how many megabytes per card and how many days it lives. The plan arrives with the invitation code: the owner presses «Code for a client», the person sends the code to the bot and immediately works under their plan. Three days before expiry the card owner gets a warning in the chat.
Results
- A new client is connected with an invitation code: no deploy, no separate site and no code changes.
- A card turns from a picture into a short scenario, and the recipient's reply arrives in Telegram.
- A card stays working when the service is unavailable.
- The database publishes no port and is visible only to the service.
- Plans offer five options: from a trial card for 14 days to a Studio plan with an unlimited number of cards.
- Smoke tests run in CI on every push; the README notes 2,305 checks.
Technologies and why
- Python 3.13 and aiohttp — the API that serves card settings and receives the recipient's choice.
- aiogram 3 — the admin bot on long polling: the creation wizard, edit panels, invitation codes.
- PostgreSQL 17 — cards, replies, plans and sessions; timestamps are stored as TIMESTAMPTZ.
- One HTML file — the card itself, with no build step or dependencies.
- Docker Compose and nginx — two containers, the service and the database; exactly one port is published.
- GitHub Actions — smoke tests with Postgres on every push.
Status
Version 3.16.1 of 29 September 2026, in production, an in-house product of the studio. The latest releases are the service's showcase landing page and a cabinet that works well on phone and desktop. What is not there yet: payment acceptance, so plans are assigned manually with an invitation code or an owner command. A live run with a real Telegram token has not been done, and the tests run on a stub. The task list is kept in the repository's ROADMAP.
Questions about this project
What is an interactive greeting card behind a password link?
How do you make one card for many guests?
How do you build an online gift quest with an advent calendar?
How does the owner edit texts and design without touching code?
What happens if the service is down?
How are client access and card lifetimes limited?
More in this area
Online Shirt Store on Nuxt 4 with an Owner Admin Panel
a shirt shop in Cheboksary: the owner manages products, prices and orders alone
DevUnit Lab: A Bilingual Studio Website on Nuxt 4
our own studio site, in production since 29 September 2026
WordPress Showcase Site with Ordering via VKontakte
for the essential-oils brand «Дыхание Поволжья», built for billboard mobile traffic
Need something similar?
Tell us about the task — we'll show how we solved it and estimate the scope.