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.0The SDK is a pinned optional peer. It is needed only when you import this subpath.
Setup
Azure.layerConfig() reads these variables:
| Variable | Required | Value |
|---|---|---|
AZURE_EMAIL_CONNECTION_STRING | yes | Communication 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:
| Text | HTML | Both | Sender name | Cc | Bcc | Reply-to | Headers | Attachments | Inline images | Idempotency |
|---|---|---|---|---|---|---|---|---|---|---|
| yes | yes | yes | no | yes | yes | multiple | yes | yes | yes | no |
These fail with UnsupportedFeatureError and acceptance: "notSubmitted" before any request:
- A display name on
from(featuresenderName). - An
idempotencyKey(featureidempotency).
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
pollIntervaland resolves when it finishes, sotimeoutcovers the whole operation and defaults to 60 seconds. - The send is accepted when the operation status is
Succeeded.FailedorCanceledfails withMessageRejectedErrorandacceptance: "rejected". Any other final status fails withUnexpectedResponseError. - The receipt's reference has kind
operationId. Failures after the operation started carry that reference inreferences. - Azure takes the sender address only. A display name on
fromfails before sending with featuresenderName. 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.
field | Raised when |
|---|---|
connectionString | The SDK client could not be created from the connection string. |
timeout | The timeout is not finite and positive. |
pollInterval | The poll interval is not finite and positive. |
| Azure failure | Reason |
|---|---|
Operation ends Failed or Canceled | MessageRejectedError (acceptance: "rejected") |
| Operation id changes while polling, or an unknown final status | UnexpectedResponseError |
timeout elapses | TimeoutError |
TypeError or DOMException from the SDK | TransportError |
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.