/**
 * Telegram adapter — long-polling via the official Bot API (v0.7a).
 *
 * SDK: `grammy` (modern, TS-first, actively maintained — recommended
 * over `telegraf` which is frozen at v4.16 from Feb 2024 and over
 * `node-telegram-bot-api` which is untyped).
 *
 * Connection: long-polling via `bot.start()` — no public webhook URL
 * required. The bot opens an outbound HTTPS connection to
 * `api.telegram.org` and polls for updates. Works behind any NAT.
 *
 * Why `grammy` is loaded via dynamic import: opensquid declares all
 * three chat SDKs as optionalDependencies. Users with no Telegram
 * config (and possibly `npm --omit=optional`) shouldn't pay the install
 * cost. The dynamic import only runs in `start()` when this adapter
 * is actually being activated — and produces a clear "install grammy"
 * error if the dep is missing.
 *
 * Gotcha: only ONE polling consumer per token at a time. A second
 * opensquid process with the same token will collide with 409 Conflict.
 * Surface that error clearly on start.
 */
import { type ChatAdapter, type MessageHandler, type OutboundMessage, type SendResult } from "../gateway.js";
import type { TelegramConfig } from "../config.js";
export declare class TelegramAdapter implements ChatAdapter {
    private readonly config;
    readonly platform: "telegram";
    private bot;
    private handlers;
    private botUsername;
    private botId;
    private startPromise;
    /**
     * 0.7.4 (#147): true when the long-poll lost to a 409 Conflict
     * (another consumer holds the token — typically the Claude Code
     * `plugin:telegram` bun bot). Outbound sendMessage still works via
     * HTTPS, only inbound is dead. A periodic retry attempts to reclaim.
     */
    private outboundOnly;
    /** 0.7.4 (#147): handle for the periodic long-poll retry timer. */
    private retryTimer;
    /** Retry cadence — long enough that flapping doesn't burn API quota. */
    private static readonly RETRY_INTERVAL_MS;
    /**
     * 0.5.90 (TG.3): chat_ids for which we've already logged an allowlist
     * drop this process. The adapter silently drops messages from non-
     * allowlisted chats (correct policy — never echo policy decisions back
     * to the sender), but operators need a one-time-per-chat log line so
     * they can diagnose "why isn't my message routing?" without reading
     * source. Tracked as a Set keyed by chatIdStr; resets on restart.
     */
    private allowlistDropLogged;
    constructor(config: TelegramConfig);
    start(): Promise<void>;
    /**
     * 0.7.4 (#147): handle a rejection from `bot.start()`. Extracted
     * from inline catch handler so tests can simulate 409 without
     * needing a live grammy + colliding bot. EXPORTED VIA PROTECTED for
     * test-only direct invocation; not part of the public adapter API.
     */
    handleStartRejection(err: unknown): void;
    /**
     * 0.7.4 (#147): test-only seed — install a fake bot reference + mark
     * outbound-only so tests can verify isOutboundOnly() + retry timer
     * without spinning up grammy. Must be called before any
     * handleStartRejection in test context.
     */
    _testSeed(fakeBot: any): void;
    /**
     * 0.7.4 (#147): test-only — clear the retry timer so tests don't
     * leak intervals after a 409 simulation.
     */
    _testClearRetryTimer(): void;
    /**
     * 0.7.4 (#147): periodically retry the long-poll while in outbound-
     * only mode. If the competing consumer disconnects, we reclaim
     * inbound transparently.
     */
    private scheduleRetry;
    private tryReclaim;
    shutdown(): Promise<void>;
    /**
     * 0.7.4 (#147): introspection accessor for tests + the
     * `chat_daemon_status` MCP tool to surface "outbound-only" state to
     * operators trying to diagnose "where did my message go?"
     */
    isOutboundOnly(): boolean;
    onMessage(handler: MessageHandler): void;
    send(message: OutboundMessage): Promise<SendResult>;
    /**
     * v0.7.2 — Create a forum topic in a supergroup. Requires the bot
     * to be admin with "Manage Topics" permission and the supergroup to
     * have Topics enabled in settings. Returns the topic's
     * `message_thread_id` for storage in chat-routing.json.
     */
    createTopic(chatId: string, name: string, options?: {
        iconColor?: number;
        iconCustomEmojiId?: string;
    }): Promise<{
        message_thread_id: number;
        name: string;
    }>;
    identity(): Promise<{
        username: string;
        nativeId: string;
    }>;
}
/**
 * Parse a Telegram channel id (with optional embedded forum-topic
 * thread id) into its native chat_id + message_thread_id parts.
 *
 * Wire format (canonical, mirrors `chat_poll_inbox` output):
 * - `telegram:<chat_id>`              → general topic, no thread
 * - `telegram:<chat_id>:<thread_id>`  → forum topic (supergroup with
 *                                       Topics enabled)
 *
 * Examples:
 * - `telegram:-1001234567890`      → `{ chatId: "-1001234567890" }`
 * - `telegram:-1001234567890:15`   → `{ chatId: "-1001234567890",
 *                                       threadId: "15" }`
 * - `telegram:8075471258`          → `{ chatId: "8075471258" }` (DM)
 *
 * Why the parser lives in the adapter (not in `gateway.ts`): Slack uses
 * a different colon-in-native-id convention (`slack:C012345:1234.5678`
 * where the trailing segment is `thread_ts`, an opaque part of the
 * native id). Telegram's `<chat_id>:<thread_id>` semantic is
 * platform-specific and shouldn't leak into the cross-platform
 * `nativeIdFromChannel` helper.
 *
 * Exported for unit testing.
 */
export declare function parseTelegramChannel(channel: string): {
    chatId: string;
    threadId?: string;
};
/**
 * Detect whether a message text contains an @-mention of this bot, or
 * uses one of telegram's bot_command entities pointing at the bot
 * (`/cmd@my_bot`).
 *
 * Exported for unit testing.
 */
export declare function detectBotMention(text: string, entities: Array<{
    type: string;
    offset: number;
    length: number;
}> | undefined, botUsername: string): boolean;
//# sourceMappingURL=telegram.d.ts.map