NOIR
Reference

ChannelAdapter

Exact interface and invariants for implementing a message transport.

type ChannelAdapter = {
  capabilities: ChannelCapabilities
  defaultPath?: string
  receive(request: Request): Promise<ChannelReceiveResult>
  send(event: OutboundEvent, options?: { signal?: AbortSignal }): Promise<DeliveryResult>
  resolveAttachment?(attachment, options): Promise<ResolvedAttachment>
  health?(): Promise<{ ok: boolean; detail?: string }>
  start?(emit): Promise<{ close(): Promise<void> }>
}

receive

Verify the raw request before normalization. Return the provider-facing response and zero or more events. Event IDs must be stable across provider retries. Installation, actor, conversation, and thread IDs must come from provider-stable fields.

send

Translate one normalized output. Respect cancellation, classify transient errors with NoirError, preserve provider retry timing, and return the external ID when known. For split deliveries, use deterministic part IDs and surface partial failure rather than reporting total success.

Capabilities

Declare approval mode, cards, edits, files, groups, media groups, reactions, read receipts, streaming mode, threads, and typing. false means unsupported. Streaming can be native or emulated through edits.

Attachment resolver

The resolver receives the attachment metadata, channel location, maximum bytes, and abort signal. Authenticate the provider request and reject unapproved hosts or stale references. Return an ID, bytes, and normalized optional name/MIME type.

Push channels

start(emit) supports socket, queue, or long-polling providers. It should reconnect with bounded backoff, emit normalized events through the supplied callback, and return an idempotent close function. Never start a connection at module import time.

Health

Health checks should identify missing credentials and perform at most a lightweight provider operation. They are called by noir doctor and should not create user-visible effects.

On this page