Developers
How Telegram and Discord access works
The mechanics behind Soca’s paid Telegram and Discord access: the one shared platform bot, the wallet-link handshake, idempotent grant and revoke driven by subscription events, and the self-hosting switch — all with no code and no per-merchant bot token.
This is the under-the-hood companion to the click-by-click setup guides — Sell access to your Discord server and Sell access to your Telegram channel. Here we describe *how* it works: how one shared Soca bot serves every merchant, how a chat member is bound to the wallet that pays, and how access is granted and revoked automatically. There is still no code to write — this is for understanding the moving parts and for self-hosting the worker.
One shared bot, not one per merchant
Soca runs a single Telegram bot and a single Discord application for the whole platform. Merchants add that shared bot to their own community — they never create an app, register a bot, or paste a token. Each merchant is told apart by which server/channel the bot is in and by a per-merchant connect token, not by a bot of their own.
Configuration is per mode, like everything else. Set it up in test mode first for a dry run. Each platform connection is tied to exactly one plan: the subscription that grants the access.
Telegram
- 1
Add the shared bot as a channel admin
The merchant adds Soca’s Telegram bot to their channel or group and promotes it to admin with Invite Users via Link (to add members) and Ban Users (to remove them). No token changes hands — it is the same platform bot everywhere.
- 2
Map the channel to a plan (verified on save)
In Dashboard → Settings → Integrations → Telegram the merchant enters the channel id and the granting plan. On save, Soca calls
getChatandgetChatMemberto confirm its bot is actually an admin there, echoes back the channel’s title, and warns if either required permission is missing — so a wrong id or an un-promoted bot fails immediately, not at grant time. - 3
Members link through a deep link
The member opens
t.me/<soca-bot>?start=<connectToken>(surfaced as Connect Telegram in their Soca account). The bot’s single webhook reads the connect token, resolves the merchant, and returns a personal link into Soca to bind the wallet.
How the grant works on Telegram: when a subscriber’s wallet is linked and the subscription is active, the bot creates a fresh single-use invite link and DMs it to them. On lapse it kicks the member (ban then immediate unban), never a permanent ban, so they can rejoin the instant they resubscribe. There is one webhook for the whole platform, secured by a secret token Telegram echoes on every call.
Discord
- 1
Add Soca to the server
In Dashboard → Settings → Integrations → Discord the merchant clicks Add Soca to Discord, picks their server on Discord’s screen, and authorizes. This invites the shared Soca application with the Manage Roles permission; the callback records the server (guild) id against the merchant. No application or bot token is created.
- 2
Pick the role and plan
Soca reads the server’s roles and offers them as a dropdown; the merchant chooses the role to grant and the plan that grants it. Keep the granted role below Soca’s role — Discord only lets a bot manage roles beneath its own.
- 3
Members link with one tap
The member clicks Connect Discord from their subscription and authorizes with the
identifyscope only — Soca reads their Discord user id and nothing else, then binds it to their paying wallet.
How the grant works on Discord: granting adds the configured role to the member; revoking removes it. Both calls go through Discord’s REST API, so there is no always-on gateway bot sitting in the server.
The wallet-link handshake
Soca has to know which Telegram/Discord user is which paying wallet, and it never asks anyone to paste an ID. The two platforms start the link differently — a Telegram deep link versus a Discord identify authorize — then converge on the same secure step: the member connects the same wallet the subscription is paid from on a hosted Soca page, and Soca records the platform-user-to-wallet binding server-side. Because access is anchored to that wallet, the person let into the community is provably the person who paid.
Grant and revoke lifecycle
A background sync continuously compares each linked member’s entitlement against their current access and closes any gap: subscription active but no access → grant; subscription lapsed (canceled, dunning exhausted, revoked, or expired) but still inside → revoke. Every operation is idempotent — granting an already-granted member or revoking an already-absent one succeeds cleanly — so the sync can run as often as it likes and a missed run just means the next one catches up. It reconciles about every minute, and Sync now in the dashboard forces an immediate pass.
Self-hosting: INTEGRATIONS_LIVE
If you run the Soca worker yourself, the access sync is safe by default. Without INTEGRATIONS_LIVE=true in the worker’s environment it uses a recording adapter that logs what it *would* grant or revoke without touching Telegram or Discord. Set INTEGRATIONS_LIVE=true, with the shared bot credentials configured, to go live.
The subscription lifecycle events driving all of this (subscription.active, subscription.dunning_exhausted, subscription.revoked, and subscription.expired) are documented in Webhooks and events, and the plans themselves can be created over the API or in the dashboard.
Was this page helpful?
A quick signal helps us improve the right pages.