Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.authforge.cc/llms.txt

Use this file to discover all available pages before exploring further.

This pattern lets anyone message your bot, but only licensed users get full responses.

Architecture

  1. User sends a message to your bot.
  2. If not licensed, bot asks for a license key.
  3. User submits key in DM/private chat.
  4. Bot validates key with AuthForge and sets hwidOverride = tg:<telegram_user_id>.
  5. If valid, store “licensed” status for that Telegram user.

Why this works

  • AuthForge treats HWID as an identity string.
  • tg:<user_id> is stable per Telegram account.
  • Seat controls (maxHwidSlots) and reset flows still work.
Use user_id, not username (usernames can change). Use heartbeatMode: "LOCAL" (or heartbeat_mode="LOCAL" in Python) for the bot process. Server heartbeat mode targets software running on the licensee’s device; a Telegram bot only performs validation on your infrastructure, so local session checks after login are enough. For every scheduled run or every message, use validateLicense / validate_license (same /auth/validate + Ed25519 verification as login) so you avoid heartbeat timers and never need logout() just to stop background intervals. Keep login for processes that intentionally hold one long-lived session.

Node example (Telegraf-style pseudocode)

import { AuthForgeClient } from "@authforgecc/sdk";

async function validateTelegramKey(telegramUserId, licenseKey) {
  const client = new AuthForgeClient({
    appId: process.env.AUTHFORGE_APP_ID,
    appSecret: process.env.AUTHFORGE_APP_SECRET,
    publicKey: process.env.AUTHFORGE_PUBLIC_KEY,
    heartbeatMode: "LOCAL",
    hwidOverride: `tg:${telegramUserId}`,
  });

  const result = await client.validateLicense(licenseKey);
  return result.valid ? result : { valid: false, code: result.code };
}

Python example

from authforge import AuthForgeClient

def validate_telegram_key(user_id: int, license_key: str) -> dict:
    client = AuthForgeClient(
        app_id=APP_ID,
        app_secret=APP_SECRET,
        public_key=PUBLIC_KEY,
        heartbeat_mode="LOCAL",
        hwid_override=f"tg:{user_id}",
    )
    return client.validate_license(license_key)
  • Keep key entry in private chat.
  • Rate limit invalid attempts per user and per IP.
  • Return clear error text for invalid_key, expired, revoked, hwid_mismatch.
  • Provide a support command to request reset help when users switch accounts.