@mohamedelsaady/mail-ms
v1.2.0
Published
Typed HTTP client SDK for the Gabster mail-ms microservice
Readme
@mohamedelsaady/mail-ms
Typed HTTP client SDK for the Gabster mail microservice.
Installation
npm install @mohamedelsaady/mail-msWhat's New in v1.2.0
✨ Batch Sending: Send to multiple recipients with a single API call via BCC
📮 CC Support: Group emails where recipients can see each other
↩️ Reply-To Field: Direct replies to monitored addresses
📊 Enhanced Types: Full TypeScript support for all operations
🔒 Privacy Focused: Flexible visibility options (BCC for privacy, CC for transparency)
Quick Start
import Mailer from "@mohamedelsaady/mail-ms";
const mail = new Mailer({
host: process.env.GABSTER_MAIL_HOST,
apiKey: process.env.GABSTER_MAIL_API_KEY,
});Sending Emails
Raw HTML
const result = await mail.send.raw({
to: "[email protected]",
subject: "Welcome aboard",
html: "<h1>Hello!</h1><p>Welcome to our platform.</p>",
text: "Hello! Welcome to our platform.", // optional plain-text fallback
tags: ["onboarding"], // optional tags
metadata: { userId: "abc123" }, // optional metadata (stored in logs)
});
console.log(result);
// { success: true, emailLogId: "664f...", messageId: "msg_..." }Templated (server-side templates)
await mail.send.templated({
template: "welcome",
to: "[email protected]",
subject: "You're invited!", // optional (uses template default)
variables: {
recipientEmail: "[email protected]",
orgName: "Your Organization",
invitationId: "inv_123",
link: "https://app.example.com/invite/inv_123",
isNewUser: true,
},
});Available templates: welcome, notification, ticket, otp, expiration, usage-limit, custom.
Dynamic (block-based)
Build emails on the fly using content blocks:
await mail.send.dynamic({
to: "[email protected]",
subject: "Your Weekly Report",
styles: {
primaryColor: "#2563eb",
backgroundColor: "#f3f4f6",
fontFamily: "Arial, sans-serif",
},
blocks: [
{ type: "heading", text: "Hello {{name}}", level: 1, align: "center" },
{ type: "text", text: "Here is your weekly summary." },
{ type: "divider" },
{ type: "text", text: "You completed {{tasks}} tasks this week." },
{ type: "button", text: "View Dashboard", link: "https://app.example.com/dashboard" },
{ type: "image", src: "https://cdn.example.com/banner.png", alt: "Banner", width: "100%" },
],
variables: { name: "John", tasks: "12" }, // replaces {{name}}, {{tasks}} in blocks
});Block types:
| Type | Required fields | Optional fields |
|-------------|----------------------|--------------------------------------|
| heading | text | level (1-3), color, align |
| text | text | color, align |
| button | text, link | color, bgColor, align |
| image | src | alt, width, align |
| divider | -- | color, thickness |
Reply-To Support
Control where replies are sent using the optional replyTo field. Useful when sending from no-reply addresses but wanting replies to go to a monitored inbox.
await mail.send.raw({
to: "[email protected]",
replyTo: "[email protected]", // replies go here instead of 'from'
subject: "Order Confirmation",
html: "<h1>Thank you for your order!</h1><p>Questions? Just reply to this email.</p>"
});Without replyTo: Replies go to the from address (or default sender)
With replyTo: Replies go to the specified address, regardless of from
Available on all send methods (single, batch, and CC).
Batch Sending
Send to multiple recipients efficiently with a single API call. All recipients receive the email privately via BCC, ensuring recipient privacy.
Key Features
- Privacy First: Recipients cannot see other email addresses (BCC delivery)
- Efficient: Single API call for multiple recipients (up to 50 per request)
- Unified Tracking: One email log and message ID for the entire batch
- Cost Effective: Single provider charge regardless of recipient count
Usage
All three sending methods support batch mode:
// Templated batch send
await mail.send.templatedBatch({
template: "notification",
to: ["[email protected]", "[email protected]", "[email protected]"],
variables: {
recipientName: "Team",
senderName: "Support",
message: "System maintenance scheduled for Sunday.",
link: "https://status.example.com"
}
});
// Raw HTML batch send
await mail.send.rawBatch({
to: ["[email protected]", "[email protected]"],
subject: "Weekly Update",
html: "<h1>Team Update</h1><p>This week's highlights...</p>"
});
// Dynamic blocks batch send
await mail.send.dynamicBatch({
to: ["[email protected]", "[email protected]"],
subject: "New Feature",
blocks: [
{ type: "heading", text: "New Feature Launch", level: 1 },
{ type: "text", text: "Check out our latest updates." },
{ type: "button", text: "Learn More", link: "https://example.com" }
]
});Limits: Maximum 50 recipients per batch request.
CC Sending (Visible Recipients)
Send to multiple recipients where everyone can see each other's email addresses. Ideal for group discussions and team communications.
Key Features
- Transparent: All recipients see each other (CC visibility)
- Group Communication: Perfect for team discussions
- Primary + CC: One main recipient plus CC'd participants
- Efficient: Single API call (up to 50 CC recipients)
Usage
// Templated CC send
await mail.send.templatedCC({
template: "notification",
to: "[email protected]",
cc: ["[email protected]", "[email protected]", "[email protected]"],
variables: {
recipientName: "Team",
message: "Meeting notes - everyone is CC'd for visibility."
}
});
// Raw HTML CC send
await mail.send.rawCC({
to: "[email protected]",
cc: ["[email protected]", "[email protected]"],
subject: "Project Update",
html: "<h1>Team Update</h1><p>All stakeholders are CC'd.</p>"
});
// Dynamic blocks CC send
await mail.send.dynamicCC({
to: "[email protected]",
cc: ["[email protected]", "[email protected]"],
subject: "Q4 Planning",
blocks: [
{ type: "heading", text: "Planning Discussion", level: 1 },
{ type: "text", text: "All stakeholders are CC'd for transparency." }
]
});Limits: Maximum 50 CC recipients per request.
Email Logs
// Query logs with filters
const logs = await mail.logs.query({
status: "failed", // "pending" | "sent" | "failed" | "retrying"
template: "welcome", // filter by template name
to: "[email protected]",
page: 1,
limit: 20,
});
console.log(logs.data); // EmailLog[]
console.log(logs.total); // total matching records
console.log(logs.totalPages); // total pages
// Get a single log by ID
const log = await mail.logs.getById("664fa1b2c3d4e5f6a7b8c9d0");
console.log(log.data.status); // "sent"Health Check
const status = await mail.health();
console.log(status);
// {
// success: true,
// service: "mail-ms",
// uptime: 3600.5,
// mongo: "connected",
// timestamp: "2026-04-05T23:00:00.000Z"
// }Configuration
| Parameter | Required | Description |
|-----------|----------|------------------------------------------|
| host | Yes | Base URL of the mail-ms service |
| apiKey | Yes | Per-service API key (from /v1/api-keys)|
Environment Variables
GABSTER_MAIL_HOST=https://your-mail-service-url
GABSTER_MAIL_API_KEY=your_api_key_hereAPI Reference
new Mailer(config)
Creates a new client instance.
mail.send.raw(params): Promise<SendResult>
Send an email with raw HTML content.
mail.send.templated(params): Promise<SendResult>
Send an email using a server-side template.
mail.send.dynamic(params): Promise<SendResult>
Send an email built from dynamic content blocks.
mail.send.templatedBatch(params): Promise<SendResult>
Send a templated email to multiple recipients via BCC (up to 50 recipients).
mail.send.rawBatch(params): Promise<SendResult>
Send a raw HTML email to multiple recipients via BCC (up to 50 recipients).
mail.send.dynamicBatch(params): Promise<SendResult>
Send a dynamic block-based email to multiple recipients via BCC (up to 50 recipients).
mail.send.templatedCC(params): Promise<SendResult>
Send a templated email with CC recipients (up to 50). All recipients see each other.
mail.send.rawCC(params): Promise<SendResult>
Send a raw HTML email with CC recipients (up to 50). All recipients see each other.
mail.send.dynamicCC(params): Promise<SendResult>
Send a dynamic block-based email with CC recipients (up to 50). All recipients see each other.
mail.logs.query(params?): Promise<PaginatedLogs>
Query email logs with optional filters and pagination.
mail.logs.getById(id): Promise<LogDetailResponse>
Get a single email log entry by its ID.
mail.health(): Promise<HealthStatus>
Check the health of the mail-ms service.
Types
All TypeScript interfaces are exported for full autocomplete:
import Mailer, {
MailerConfig,
SendRawParams,
SendTemplatedParams,
SendDynamicParams,
SendRawBatchParams,
SendTemplatedBatchParams,
SendDynamicBatchParams,
SendResult,
DynamicBlock,
DynamicStyles,
HeadingBlock,
TextBlock,
ButtonBlock,
ImageBlock,
DividerBlock,
EmailLog,
PaginatedLogs,
LogQueryParams,
HealthStatus,
TemplateName,
EmailStatus,
} from "@mohamedelsaady/mail-ms";License
UNLICENSED -- Internal use only.
