Plunk
Send email through Plunk with the @effect-kit/emails/plunk Layer.
The @effect-kit/emails/plunk subpath sends messages through Plunk and provides the Email service.
Installation
npm install @effect-kit/emails effect @plunk/node@3.0.3The SDK is a pinned optional peer. It is needed only when you import this subpath.
Setup
Plunk.layerConfig() reads these variables:
| Variable | Required | Value |
|---|---|---|
PLUNK_API_KEY | yes | Secret API key, starting with sk_ |
Example (Sending a Message With Plunk)
import { , , } from "effect";
import { } from "@effect-kit/emails";
import * as from "@effect-kit/emails/plunk";
const = .().(
.(.(.())),
);
const = .(function* () {
const = yield* ;
return yield* .({
: "hello@example.com",
: "ada@example.com",
: "Welcome",
: "<p>Your account is ready.</p>",
});
});
.(.(.()));Use a from address your Plunk account is allowed to send from.
Options
Plunk.layer takes these options. layerConfig builds the same object from a Config.
Prop
Type
Capabilities
Plunk reports this in email.capabilities:
| Text | HTML | Both | Sender name | Cc | Bcc | Reply-to | Headers | Attachments | Inline images | Idempotency |
|---|---|---|---|---|---|---|---|---|---|---|
| no | yes | no | yes | no | no | none | no | no | no | no |
These fail with UnsupportedFeatureError and acceptance: "notSubmitted" before any request:
- A
textbody (featuretext). - A
cclist (featurecc). - A
bcclist (featurebcc). - Any
replyToaddress (featurereplyTo). - Any custom header (feature
headers). - Any attachment (feature
attachments). - An
idempotencyKey(featureidempotency).
Idempotency
Not supported. A key fails with UnsupportedFeatureError before sending.
Provider notes
- Plunk is HTML only. A message needs
htmland exactly onetoaddress without a name. A text-only message fails the capability check, and a message withouthtmlor with a named or second recipient fails withInvalidMessageError(pathto). - Only
from, the sender name,to,subjectand the HTML body are sent. Anything else fails the capability check first:text,cc,bcc,replyTo, headers and attachments. - The
@plunk/nodepackage is marked as no longer supported on npm. Pin it to the version above. - A send is accepted when Plunk reports the recipient as
queued. The statusthrottledorskippedfails withMessageRejectedError. The receipt's single reference is the recipient address.
Using your own client
layerClient takes any object with emails.send({ to, from, name, subject, body }), which a Plunk client has. options is optional.
Example (Borrowing a Plunk Client)
import Plunk from "@plunk/node";
import * as PlunkEmail from "@effect-kit/emails/plunk";
const client = new Plunk("sk_fake_key");
const EmailLive = PlunkEmail.layerClient(client);You own a borrowed client. The Layer never closes it, and the client keeps its own retry, timeout and logging policy.
Errors
ProviderConfigurationError carries provider: "plunk" and a field naming the bad option. Layer construction fails with it, and layerClient fails with it for the client options.
field | Raised when |
|---|---|
timeout | The timeout is not finite and positive. |
token | The key is not printable ASCII without spaces. |
apiKey | The key does not start with sk_. |
baseUrl | The URL is not http or https, has credentials, a query or a fragment, or its path does not end with a slash. |
| Plunk failure | Reason |
|---|---|
| SDK token error | AuthenticationError (status 401, acceptance: "rejected") |
| SDK not found error | ProviderError (status 404) |
A plain Error from the SDK | ProviderError |
Recipient status throttled or skipped | MessageRejectedError (acceptance: "rejected") |
Any other status except queued | UnexpectedResponseError |
Any other HTTP status uses the shared mapping: 401 is AuthenticationError, 403 PermissionDeniedError, 429 RateLimitedError, 400 and 422 InvalidMessageError, 5xx ProviderUnavailableError, and anything else ProviderError. acceptance is rejected for a 4xx status other than 409 and unknown otherwise. See Errors. A network failure with no status is TransportError, and ETIMEDOUT or ECONNABORTED is TimeoutError, both with acceptance: "unknown".