/** * MS Teams {@link ChannelAdapter}: Bot Framework webhook ingress (JWT-verified, * fast-acked) + connector-service egress via {@link MsTeamsClient}. Raw fetch * only — no botbuilder. Identity stays with the engine: the adapter only tags * `isBot` mention entities and never resolves users itself (Decision 16). */ import type { AdapterContext, ChannelAdapter } from "../../src/adapter.js"; import type { ActorQuery, ChannelActor, ConversationHealth, ConversationKey, MessageRef, OutboundMessage, ReplyTarget, SurfaceCapabilities } from "../../src/types.js"; export * from "./activity.js"; export * from "./client.js"; export * from "./jwt.js"; /** Options for {@link MsTeamsAdapter}. */ export type MsTeamsAdapterOptions = { /** Skaile's multi-tenant Entra app id (non-secret; the secret comes via CredentialPort). */ appId: string; /** Default "/channels/msteams/messages". */ ingressPath?: string; openIdMetadataUrl?: string; loginBaseUrl?: string; fetchImpl?: typeof fetch; }; /** * The MS Teams adapter (spec §6, plan Task 10). Webhook-style: `start` only * registers the ingress route — there is no outbound socket. Egress posting * requires the conversation to have been seen on ingress (serviceUrl + tenant * are remembered per conversationKey; Bot Framework provides no directory). */ export declare class MsTeamsAdapter implements ChannelAdapter { readonly platform: "msteams"; readonly capabilities: SurfaceCapabilities; private readonly opts; private ctx?; /** tenantId → lazily-created provider client (promise-cached to collapse races). */ private readonly clients; /** Ingress-observed conversation facts, keyed by conversationKey (thread AND channel level). */ private readonly conversations; /** Ingress-observed actors by externalId — the lookupActor roster. */ private readonly roster; /** post() idempotency: dedupeKey → prior ref, TTL {@link DEDUPE_TTL_MS}. */ private readonly posted; constructor(opts: MsTeamsAdapterOptions); /** Registers the ingress route on the host; no connection is opened. */ start(ctx: AdapterContext): Promise; /** Drops the context and per-tenant clients; the host owns route teardown. */ stop(): Promise; /** * The Bot Framework messaging endpoint. Guarded by a `Promise.race` at * `ackDeadlineMs - 1000`: if processing overruns, Teams still gets its 200 * and at-least-once redelivery covers the rest. */ readonly handleRequest: (req: Request) => Promise; private processRequest; /** Records serviceUrl + tenant under the thread key AND its channel-level key. */ private rememberConversation; /** Grows the lookupActor roster from the sender and mention entities (bot excluded). */ private rememberActors; /** Maps a messageReaction activity onto InboundReaction events (one per emoji). */ private forwardReactions; /** Posts a message; a repeated `dedupeKey` returns the prior ref with no second side effect. */ post(target: ReplyTarget, msg: OutboundMessage, dedupeKey: string): Promise; /** Replaces a previously posted activity's content in place. */ update(ref: MessageRef, msg: OutboundMessage): Promise; /** Native Teams typing indicator — fire-and-forget, never deduped. */ indicateTyping(target: ReplyTarget): Promise; /** Preflight: a typing probe proves the bot can post; 403/404 → actionable problem. */ verifyConversation(key: ConversationKey): Promise; /** Resolves from the ingress-observed roster only (Graph lookup is platform glue, later). */ lookupActor(query: ActorQuery): Promise; /** Decision 11: Adaptive Card for questions with options; markdown text otherwise. */ private buildActivity; /** serviceUrl + native conversation id for a target — threadRef.raw first, ingress memory else. */ private resolveTarget; /** Conversation facts under the exact key, falling back to its channel-level key. */ private infoFor; /** One MsTeamsClient per tenant, built from CredentialPort (kind must be "msteams"). */ private clientForConversation; private clientForTenant; /** Live dedupe hit for `key`, sweeping expired entries opportunistically. */ private dedupeGet; } //# sourceMappingURL=index.d.ts.map