Documentation for agents: an index at /llms.txt, every docs page in one file at /llms-full.txt, and Markdown for any docs page by adding .md to its URL.

Effect KitEmails

Azure Communication Services

Send email through Azure Communication Services Email with the @effect-kit/emails/azure Layer.

The @effect-kit/emails/azure subpath sends messages through Azure Communication Services Email and provides the Email service.

Installation

npm install @effect-kit/emails effect @azure/communication-email@1.1.0

The SDK is a pinned optional peer. It is needed only when you import this subpath.

Setup

Azure.layerConfig() reads these variables:

VariableRequiredValue
AZURE_EMAIL_CONNECTION_STRINGyesCommunication Services connection string

Example (Sending a Message With Azure Communication Services Email)

import { , ,  } from "effect";
import {  } from "@effect-kit/emails";
import * as  from "@effect-kit/emails/azure";

const  = .().(
  .(.(.())),
);

const  = .(function* () {
  const  = yield* ;
  return yield* .({
    : "hello@example.com",
    : "ada@example.com",
    : "Welcome",
    : "Your account is ready.",
  });
});

.(.(.()));

Use a from address your Azure Communication Services Email account is allowed to send from.

Options

Azure.layer takes these options. layerConfig builds the same object from a Config.

Prop

Type

Capabilities

Azure Communication Services Email reports this in email.capabilities:

TextHTMLBothSender nameCcBccReply-toHeadersAttachmentsInline imagesIdempotency
yesyesyesnoyesyesmultipleyesyesyesno

These fail with UnsupportedFeatureError and acceptance: "notSubmitted" before any request:

  • A display name on from (feature senderName).
  • An idempotencyKey (feature idempotency).

Idempotency

Not supported. A key fails with UnsupportedFeatureError before sending.

Provider notes

  • Azure sends are long-running operations. The Layer starts the operation, polls it every pollInterval and resolves when it finishes, so timeout covers the whole operation and defaults to 60 seconds.
  • The send is accepted when the operation status is Succeeded. Failed or Canceled fails with MessageRejectedError and acceptance: "rejected". Any other final status fails with UnexpectedResponseError.
  • The receipt's reference has kind operationId. Failures after the operation started carry that reference in references.
  • Azure takes the sender address only. A display name on from fails before sending with feature senderName. Set the sender display name in Azure.
  • The owned client is created with maxRetries: 0.

Using your own client

layerClient takes any object with beginSend(message, options) that returns a poller with pollUntilDone, stopPolling and getResult, which an EmailClient does. options is optional and accepts timeout and pollInterval.

Example (Borrowing a Azure Communication Services Email Client)

import { EmailClient } from "@azure/communication-email";
import * as Azure from "@effect-kit/emails/azure";

const client = new EmailClient("endpoint=https://example.communication.azure.com/;accesskey=fake");

const EmailLive = Azure.layerClient(client);

You own a borrowed client. The Layer never closes it, and the client keeps its own retry, timeout and logging policy.

Errors

Layer construction fails with AzureConfigurationError, whose field names the bad option. layerClient fails with it for the client options.

fieldRaised when
connectionStringThe SDK client could not be created from the connection string.
timeoutThe timeout is not finite and positive.
pollIntervalThe poll interval is not finite and positive.
Azure failureReason
Operation ends Failed or CanceledMessageRejectedError (acceptance: "rejected")
Operation id changes while polling, or an unknown final statusUnexpectedResponseError
timeout elapsesTimeoutError
TypeError or DOMException from the SDKTransportError

REST errors use the HTTP status with the shared mapping. Once an operation id is known, the acceptance of a failure is unknown so you can reconcile it. Kept providerCode values are ServiceUnavailable and REQUEST_SEND_ERROR.