Skip to content
/ wildpost Public

Telegram-based advertising and influencer marketplace platform.

License

Notifications You must be signed in to change notification settings

zytfo/wildpost

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wildpost

Telegram-based advertising and influencer marketplace platform. Advertisers create campaigns with budgets and targeting, while channel owners (influencers) monetize their Telegram channels by publishing sponsored content.

This project is a submission for the Ad Marketplace Contest by Builders.

Try it out: @wild_post_bot

For influencers: add @wildpost_employer as an admin to your Telegram channel with all permissions to enable stats fetching and auto-posting.

App Modes

The platform has two modes that users can switch between:

  • Influencer mode — Manage your Telegram channels, view stats, submit creatives, and withdraw earnings
  • Advertiser mode — Create and manage advertisers, set up campaigns with budgets and targeting, review creatives, and track deal progress

To switch between modes, long-press the Influencer or Advertiser button in the bottom navigation menu. The selected mode is persisted in local storage.

Architecture

Wildpost is a monorepo with 5 services connected via a shared Docker network (ad_net):

Service Description README
/api FastAPI backend (REST API, JWT auth) api/README.md
/bot Telegram bot (aiogram 3.x) bot/README.md
/workers Celery background task workers workers/README.md
/client Next.js frontend (Telegram Mini App) client/README.md
/db PostgreSQL + PgBouncer + HAProxy db/README.md

Data Flow

  1. Users interact via the Telegram bot or the Mini App (Next.js frontend)
  2. The FastAPI backend handles REST endpoints with JWT authentication
  3. PostgreSQL stores all data, accessed via SQLAlchemy 2.0 (async) through PgBouncer
  4. Celery workers process background jobs (posting, payments, verification) via RabbitMQ
  5. Telethon (Telegram client library) handles posting to channels and fetching stats
  6. TON blockchain handles payments and withdrawals

Tech Stack

Layer Technology
API FastAPI, Uvicorn, Gunicorn
Bot aiogram 3.x, Python 3.13
Workers Celery, RabbitMQ
Frontend Next.js 16, React 19, TypeScript, Tailwind CSS
Database PostgreSQL 16, SQLAlchemy 2.0, Alembic, PgBouncer
Caching Redis 7
Blockchain TON (tonutils, pytoniq_core)
Telegram Client Telethon (session-based)
Monitoring Prometheus, Loki, Tempo, Grafana, cAdvisor
Reverse Proxy Nginx with Cloudflare

Architecture Decisions

Decision Why
Telethon user bot The Telegram Bot API cannot fetch broadcast channel statistics (GetBroadcastStatsRequest) or publish posts to channels on behalf of a user account. A Telethon MTProto client (@wildpost_employer) is required for stats fetching, auto-publishing, and post verification.
Model duplication across services Each service (/api, /bot, /workers) maintains its own SQLAlchemy models. This enables independent deployment without shared package dependencies and avoids import chain issues across different runtimes (uvicorn vs aiogram vs celery).
Per-queue Celery workers Each task type runs in its own worker with a dedicated queue. This provides isolation (a slow stats fetch won't block payment checking), independent scaling, and prevents Telethon session conflicts (one session per worker).
PgBouncer + HAProxy Connection pooling is essential for async workers that open/close connections frequently. PgBouncer pools PostgreSQL connections in transaction mode, HAProxy adds health checking and load balancing.
TON blockchain Aligns with the Telegram ecosystem. TON provides fast, low-fee transactions suitable for micropayments in an ad marketplace.
JWT from Telegram initData Telegram Mini Apps provide initData with a cryptographic signature. The API validates this signature using the bot token, checks auth_date to prevent replay attacks, and issues a short-lived JWT — secure authentication without passwords.
Per-deal deposit addresses Each deal gets a unique TON deposit address. This isolates funds per deal for clean escrow tracking, automated on-chain payment verification, and auditable refund paths.
Admin re-verification on financial ops Bot admin status is re-checked via the Bot API (getChatMember) before processing withdrawals, ensuring the bot still has permissions in the channel before releasing funds.
Deal auto-expiration Deals that stall at any stage are automatically expired/cancelled by a cron task. Pre-payment deals expire after 24h, post-payment deals are cancelled after 48-72h and feed into the refund pipeline.

Influencer Flow

  1. Add a channel — Send your channel link to the bot. The bot resolves the channel and stores its Telegram ID. You must add @wildpost_employer as an admin with all permissions for stats fetching and auto-posting to work.
  2. Channel verification — The bot verifies it has admin access. Channels with 500+ subscribers automatically get detailed statistics fetched every hour by the fetch_channels_stats_cron worker.
  3. Browse campaigns — In influencer mode, browse active campaigns from advertisers. Filter by category, language, budget, and subscriber requirements.
  4. Apply to a campaign — Submit an application with your channel and proposed price. The advertiser reviews your channel stats and decides.
  5. Application approved → Deal created — Once approved, a deal is created. Wait for the advertiser to pay.
  6. Submit a creative — After the advertiser pays, you submit a creative matching the campaign requirements (text, media, inline buttons). If a creative template exists, the rules are enforced (max text length, allowed media types, etc.).
  7. Creative review — The advertiser reviews your submission:
    • Approved — your creative is scheduled for auto-publishing
    • Changes requested — revise and resubmit
    • Rejected — submit a new creative version
  8. Auto-publishing — The approved creative is automatically published to your channel at the scheduled time via Telethon. No manual action needed.
  9. Keep the post live — The post must remain published for the agreed minimum duration (default 24h). The verify_posts_cron worker will check that it still exists and the bot is still an admin.
  10. Get paid — After successful verification, your channel balance is credited with the deal amount.
  11. Withdraw earnings — Request a withdrawal to your TON wallet via the bot. A 5% platform fee is deducted. The bot shows a full breakdown (amount, fee, net payout) at every step. The process_channel_withdrawals_cron worker sends the net amount to your wallet.

Advertiser Flow

  1. Create an advertiser — Register your advertiser profile via Mini App. You become the owner with full permissions. Optionally invite managers with granular permissions.
  2. Create a campaign — Define targeting (channel categories, languages, subscriber range, avg views), set a budget in TON, choose preferred creative types (POST, STORY, REPOST), and optionally attach a creative template with content requirements.
  3. Activate the campaign — Campaign status: DRAFT → ACTIVE. Active campaigns become visible to channel owners.
  4. Receive applications — Channel owners browse active campaigns and apply. You see each applicant's channel stats and can approve or reject applications.
  5. Approve an application — An approved application creates a deal between you and the channel. The deal enters PENDING_PAYMENT status with an agreed price.
  6. Pay for the deal — You pay the deal amount in TON to a unique deposit address. The check_deal_payments_cron worker verifies the transaction on-chain. Once confirmed, the deal moves to CREATIVE_PENDING.
  7. Review the creative — The channel owner submits a creative (text, media, buttons). You can:
    • Approve — the creative moves to CREATIVE_APPROVED and gets scheduled for auto-publishing
    • Request changes — the channel owner revises and resubmits
    • Reject — the creative is rejected and the channel owner can submit a new version
  8. Post is published — The Celery worker auto-publishes the approved creative to the channel via Telethon at the scheduled time.
  9. Verification — After the minimum duration (default 24h), the verify_posts_cron worker checks that the post still exists and the bot is still a channel admin.
  10. Deal completion — If verification passes, the deal is marked COMPLETED and the channel owner's balance is credited. If verification fails and funds have been swept to the hot wallet, a refund is processed back to your wallet.

Deal Lifecycle

DRAFT → PENDING_APPROVAL → APPROVED → PENDING_PAYMENT → PAID →
CREATIVE_PENDING → CREATIVE_SUBMITTED → CREATIVE_APPROVED →
SCHEDULED → PUBLISHED → (verification) → COMPLETED / REFUNDED / CANCELLED
Status Description
DRAFT Deal created, not yet submitted for approval
PENDING_APPROVAL Awaiting advertiser approval
APPROVED Advertiser approved the deal
PENDING_PAYMENT Waiting for TON payment from advertiser
PAID Payment confirmed on-chain
CREATIVE_PENDING Awaiting creative submission from channel owner
CREATIVE_SUBMITTED Creative submitted, awaiting advertiser review
CREATIVE_APPROVED Advertiser approved the creative
CREATIVE_REJECTED Advertiser rejected the creative
SCHEDULED Creative scheduled for auto-publishing
PUBLISHED Post published to the channel
VERIFICATION_PENDING Awaiting post verification after min duration
COMPLETED Post verified, channel owner credited
DISPUTED Deal is under dispute
REFUNDED Funds refunded to advertiser (failed verification, funds were swept)
CANCELLED Deal cancelled (failed verification, funds not yet swept)
EXPIRED Deal expired without completion

Managers & Permissions

Both advertisers and channels support a multi-user management system. Owners can invite other Telegram users as managers with granular permissions.

Advertiser Managers

Permission Description
can_manage_campaigns Create, edit, and manage campaigns
can_manage_managers Invite or remove other managers
can_edit_advertiser Edit advertiser profile details

Channel Managers

Permission Description
can_manage_deals Accept/reject deals, submit creatives, manage scheduling
can_manage_pricing Set and update channel pricing
can_withdraw Initiate balance withdrawals to a TON wallet
can_manage_managers Invite or remove other managers

The user who creates an advertiser or adds a channel becomes the owner with all permissions. Managers are soft-deleted (removed_at) when removed, preserving audit history.

Creatives

When a deal is approved and paid, the channel owner submits a creative — the actual content to be published. Creatives go through a review workflow (DRAFT → SUBMITTED → APPROVED / CHANGES_REQUESTED / REJECTED).

Creative Types

Type Description
POST Standard channel post with text, media, and inline buttons
STORY Telegram channel story with configurable duration
REPOST Forward/repost of an existing message

Creative Templates

Advertisers can attach creative templates to campaigns to define content requirements for channel owners:

  • Max text length — character limit for the creative text
  • Allowed media types — which media formats are accepted (photo, video, etc.)
  • Max media count — how many media files can be attached
  • Buttons — whether inline buttons are allowed and how many
  • Link preview — whether URL previews are enabled
  • Story duration — duration in seconds for story-type creatives
  • Prohibited content and additional notes — guidelines for the channel owner

Each creative is linked to a template (if one exists for the campaign), and the template rules are enforced during submission.

Demos

Adding channel and fetching stats (as influencer) | Creating an advertiser and campaign (as advertiser)

Applying for a campaign (as influencer) | Accepting (rejection) a request (as advertiser)

Creating a creative and its submission (as influencer) | Payment (as advertiser)

Check result here (the post time might not be correct for testing purposes)

Prerequisites

  • Docker and Docker Compose
  • Node.js 18+ (for client development)
  • Python 3.11+ (for API/workers) or Python 3.13+ (for bot)
  • uv (bot dependency management)
  • Poetry (API/workers dependency management)
  • Telegram Bot Token (from @BotFather)
  • Telegram API credentials (API_ID, API_HASH from https://my.telegram.org)
  • TON API key (from TON API)

Deployment

All services share the ad_net Docker bridge network. Deploy in this order: dbapibotworkersclient.

See each service's README for detailed deployment instructions.

Known Limitations & Future Work

  • Channel stats require 500+ subscribers — Telegram's API only exposes detailed channel statistics for channels with at least 500 subscribers.

  • TON payments only — All payments and withdrawals are processed exclusively via the TON blockchain.

  • Single pending withdrawal per channel — A channel can only have one pending withdrawal at a time; the previous one must complete or fail first.

  • Telethon session limits — Each Telethon session can only be used by one worker at a time; concurrent access will cause session conflicts.

  • Adjustable 5% platform fee on withdrawals — A flat 5% fee is deducted from all channel owner withdrawals. Future: tiered fee structure based on volume (lower fees for high-volume channels).

  • Minimum withdrawal amount — Channel owners must have at least 0.5 TON balance to initiate a withdrawal.

  • User bot must be channel admin — The user bot (@wildpost_employer) must be added as an admin with all permissions to each channel for stats fetching and auto-posting. Admin status is re-verified before financial operations.

  • User bot (Telethon) is central to the flow — The Telegram Bot API does not support fetching channel statistics or publishing posts on behalf of a channel. A Telethon-based user bot is used for stats fetching, auto-publishing, and post verification.

  • Post verification timing — Posts are verified only after the agreed minimum duration (default 24 hours) has elapsed.

  • Model duplication — SQLAlchemy models are duplicated across /api, /bot, and /workers services. Future: shared model package published as an internal dependency.

  • Seed phrases stored in plain text — Currently, seed phrases are stored in environment variables in plain text. Future: implement encryption at rest using a key management service.

About

Telegram-based advertising and influencer marketplace platform.

Resources

License

Stars

Watchers

Forks