The top-level mail facade exposes:
mail.inbox(...) is a thin facade over the currently configured emails client. If no client has been configured, it throws a setup error that points callers to configureEmailsClient(...).
Example:
import { mail } from "@qawolf/emails";
const inbox = await mail.inbox({ new: true });
console.log(inbox.emailAddress);
Inbox Handle
The returned inbox handle exposes:
emailAddress
sendMessage(...)
waitForMessage(...)
waitForMessages(...)
The current exported wait type is shared by both wait methods. The sections below describe which fields each method actually uses. Pass {} when you want default wait behavior.
Example:
const inbox = await mail.inbox({ new: true });
await inbox.sendMessage({
subject: "Sign in link",
text: "Use the link in this email",
to: [inbox.emailAddress],
});
const latestMessage = await inbox.waitForMessage({});
Current GetInboxOptions
type GetInboxOptions = {
address?: string | undefined;
delimiter?: string | undefined;
new?: boolean | undefined;
};
Current validation and behavior:
new: true derives a unique address
delimiter customizes the separator used for derived addresses
address must come from the allowed workspace address set
- omitting
address triggers a lookup of the workspace default address
If teamId is missing from the runtime client configuration, inbox creation fails.
Examples:
const defaultInbox = await mail.inbox();
const namedInbox = await mail.inbox({ address: "flows@example.com" });
const derivedInbox = await mail.inbox({ new: true, delimiter: "-" });
sendMessage(...)
Current input shape:
type SendMessage = {
attachments?: {
content: Buffer;
contentId?: string;
disposition?: "attachment" | "inline";
fileName: string;
type?: string;
}[];
bcc?: string[];
cc?: string[];
html?: string;
replyTo?: string[];
replyToMessageId?: string;
subject: string;
text?: string;
to: string[];
};
Behavior:
to is always an array of strings
- at least one of
html or text is required
- attachments are base64-encoded before the request is sent to the email service
Return shape:
type SendMessageResult = {
id: string;
};
Example:
const result = await inbox.sendMessage({
attachments: [
{
content: Buffer.from("hello"),
fileName: "note.txt",
type: "text/plain",
},
],
html: "<p>Hello from QA Wolf</p>",
subject: "Welcome",
to: [inbox.emailAddress],
});
console.log(result.id);
Current method options:
type WaitForMessageOptions = {
after?: Date;
timeout?: number;
};
For waitForMessage(...), the implementation uses:
after when it is provided
- otherwise the time when
mail.inbox(...) was called
timeout when it is provided
It returns one ParsedEmail and throws if no message arrives in time.
Example:
const message = await inbox.waitForMessage({
after: new Date(Date.now() - 60_000),
timeout: 15_000,
});
console.log(message.subject);
Current method options:
type WaitForMessagesOptions = {
after?: Date;
delay?: number;
minCount?: number;
timeout?: number;
};
Behavior:
- it uses
after when provided, otherwise the time when mail.inbox(...) was called
- it waits for
delay first
- it polls until at least
minCount messages are found, or until timeout
- it returns the matching parsed emails
Example:
const messages = await inbox.waitForMessages({
delay: 2_000,
minCount: 2,
timeout: 30_000,
});
console.log(messages.map((message) => message.subject));
Parsed Email Shape
The parsed email shape is:
type ParsedEmail = {
attachments?: {
content: Buffer;
fileName: string;
type?: string;
}[];
bcc?: string[];
cc?: string[];
from: string;
html: string;
id: string;
replyTo?: string[];
subject: string;
teamId: string;
text: string;
to: string[];
urls: string[];
};
urls is derived by parsing links from the HTML body.
Example:
const message = await inbox.waitForMessage({});
console.log(message.from);
console.log(message.subject);
console.log(message.urls);
Last modified on April 24, 2026