Marketing-Ops Platform: desktop → Telegram → web
Ad campaign management platform for an own performance stack. Started in 2024 as a Tkinter desktop for personal use — grew into a fully fledged product with 80+ features, a Telegram bot, and a production web app on Next.js + FastAPI with multi-user RBAC and encrypted token vault.
Launching one campaign = 2 hours of manual work
In media buying, launching one ad campaign is 9 connected steps: build the naming (Store/Product/GEO/Buyer/Vertical), pick landing+offers in Keitaro, create a short URL via Cutt.ly, set OG tags, attach Facebook Pixel and Access Token, create a post on the FB page, add seed comments.
Every step is easy to mess up: the alias repeats from a previous campaign, wrong pixel ID, missing UTM tag — and attribution breaks, budget burns. With 5-10 launches a day, the whole team spends more time on copy-paste than on creatives.
No ready-made solutions exist: commercial SaaS is tied to a single CPA network, custom internal tools are locked to rigid processes. Needed a tool that understands our naming structure, our integrations and evolves with team needs.
Three iterations, three interfaces
Tkinter native macOS app — for personal use
Python + Tkinter + native macOS Edit menu (Undo/Cut/Copy/Paste). A personal productivity tool: one full form with auto-pick of landings/offers, validation, template saving, local history in SQLite. ~2000 lines of Python, packaged into a .app bundle.
Telegram bot for the team — chat-based UX
aiogram 3 + FSM state machine: step-by-step field collection via inline buttons. The same business logic code is reused from the desktop via shared modules. Creating a campaign doesn't require opening a laptop — the buyer works straight from chat on the phone.
Production web app with multi-user RBAC
Fully rewritten from scratch as production-grade SaaS: Next.js 14 (App Router, TypeScript, Tailwind, shadcn/ui) + FastAPI (async SQLAlchemy 2 + Pydantic v2) + PostgreSQL 16 + Celery + Redis 7.
Encrypted token vault on Fernet (AES-128-CBC + HMAC-SHA256) — the frontend never sees raw API tokens. JWT auth with bcrypt passwords. Audit log of every action in the DB. Deployed via Docker compose on Vultr VPS, origin IP hidden behind Cloudflare.
What's inside — top 10 functions from 80+
Editable table, post auto-numbering, side-by-side progress bar, results table with success/error per row.
Fernet (AES-128-CBC + HMAC-SHA256), master key from ENV, separate vault-admin role. Tokens never leave the backend.
"You usually use Hershey's with Kisses", time-based hints ("14:00 — your typical posting time").
Form auto-saves to DB. On browser/app crash — recovery from the latest save, "clear draft" button.
Red/green field border, button disabled on collision. Auto-fix in batch (appending -2, -3, or a random word).
Grouping by GEO/Store, quick-apply, preview before applying, JSON import/export, ability to share templates across the team.
Action logger with timestamp per change, search/filter (Campaign/Post/Ads/Error), date-range filter, CSV/JSON export, click-to-jump to campaign.
Backup manager keeps the last 10 copies locally, manual-backup button in menu, last-save time indicator in the status bar.
Warning when trying to create a campaign with the same Store+Product+GEO as an existing one, side-by-side compare with the previous version.
Cmd+1/2/3 tab switch, Cmd+N new campaign, Cmd+H history, Cmd+Q quick-actions panel. Full keyboard navigation.
This is my personal build — an internal tool, not a product for sale. Shown here not to sell this software, but as a reference for what I can build solo: full-stack product with three interfaces, production deploy, multi-user RBAC, ~80 polished features. In client projects I bring the same level of attention to detail to your use case — choosing the stack to fit the task.
Production-grade technologies
- Next.js 14 (App Router)
- React 18 + TypeScript
- Tailwind CSS + shadcn/ui
- Radix UI primitives
- react-hook-form + Zod validation
- Sonner for toast notifications
- FastAPI 0.115 (async)
- SQLAlchemy 2 async + Alembic migrations
- Pydantic v2 for all schemas
- JWT (jose, HS256, 24h TTL)
- bcrypt for passwords
- Fernet (AES + HMAC) for vault
- PostgreSQL 16 (pgcrypto, uuid-ossp)
- Celery 5 for async tasks
- Redis 7 for broker + cache
- SQLite (desktop / Telegram versions)
- Docker compose, multi-service
- Nginx (TLS, security headers, source-map blocking)
- Cloudflare DNS/CDN, origin IP hidden
- Vultr VPS, Ubuntu 22.04
- Let's Encrypt SSL automation
- Python 3 + Tkinter
- Native macOS Edit menu
- SQLite for local DB
- py2app for .app bundle
- aiogram 3 (async)
- FSM state machine
- inline buttons + callback handlers
- Keitaro API (campaigns, landings, offers)
- Facebook Graph API (posts, comments, pages)
- Cutt.ly API (short URLs)
- Webhook handlers for statuses
- Pytest for backend
- Audit-log table in DB
- Centralized ErrorHandler
- Structured logging
What changed in the workflow
8× faster, with no-duplicate guarantee and full field validation
campaigns per run with editable table and individual configuration
through 10 phases of iterative development from MVP to production SaaS
Systemic effect: the platform became a single source of truth for all team ad launches. Telegram bot for buyers on the road, web app for office work and team collaboration, desktop for those who prefer native macOS. All three use the same code for business logic and one shared database of campaigns/templates/tokens.
Lesson for client projects: the right architecture (separation of concerns, shared business logic, multi-frontend) lets you add a new interface — mobile app, Slack integration, voice assistant — in a week, without rewriting the backend.
Аудит за 5 000 ₽ — с конкретным отчётом и сметой
Расскажу что внедрить в вашем бизнесе в первую очередь, какая будет окупаемость, и нужен ли вообще AI для вашей задачи (иногда — нет).
Или просто напишите свой вопрос — отвечу в течение 2 часов