All checks were successful
armco-org/mesa-client-sdk/pipeline/head This commit looks good
@armco/mesa-sdk
Official Node.js SDK for the Mesa/Sandesh Email Platform.
Installation
npm install @armco/mesa-sdk
# or
yarn add @armco/mesa-sdk
# or
pnpm add @armco/mesa-sdk
Quick Start
import { MesaClient } from '@armco/mesa-sdk';
const mesa = new MesaClient({
apiKey: process.env.MESA_API_KEY!,
});
await mesa.send({
from: { email: 'noreply@example.com', name: 'My App' },
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Hello World</h1>',
});
Configuration
Basic Configuration
const mesa = new MesaClient({
apiKey: 'your-api-key', // Required
baseUrl: 'https://custom.api.url', // Optional (default: https://mesa.armco.dev)
timeout: 30000, // Optional (default: 30000ms)
retries: 3, // Optional (default: 3)
});
Mail Configuration
The mailConfig object allows you to set default email settings. This is a flexible JSON config - new settings added to Sandesh can be passed here without SDK updates.
const mesa = new MesaClient({
apiKey: process.env.MESA_API_KEY!,
mailConfig: {
// Core settings (typed)
defaultFrom: { email: 'noreply@example.com', name: 'My App' },
defaultReplyTo: { email: 'support@example.com' },
trackClicks: true,
trackOpens: true,
trackingDomain: 'track.example.com',
defaultTags: ['transactional'],
sandbox: false,
ipPool: 'dedicated-pool',
sendTimeOptimization: true,
// Any additional config fields (forward compatible)
customField: 'value',
newFeatureFlag: true,
},
});
Available Mail Config Options
| Option | Type | Default | Description |
|---|---|---|---|
defaultFrom |
EmailAddress |
- | Default sender address |
defaultReplyTo |
EmailAddress |
- | Default reply-to address |
trackClicks |
boolean |
true |
Enable click tracking |
trackOpens |
boolean |
true |
Enable open tracking |
trackingDomain |
string |
- | Custom tracking domain |
defaultTags |
string[] |
- | Tags applied to all emails |
sandbox |
boolean |
false |
Sandbox mode (emails logged, not sent) |
ipPool |
string |
- | Dedicated IP pool name |
sendTimeOptimization |
boolean |
false |
AI-powered send time optimization |
[key: string] |
unknown |
- | Any additional config for future features |
Sending Emails
Basic Send
const response = await mesa.send({
to: 'user@example.com',
subject: 'Hello',
html: '<p>Welcome to our platform!</p>',
text: 'Welcome to our platform!',
});
console.log('Email queued:', response.id);
Multiple Recipients
await mesa.send({
to: [
{ email: 'user1@example.com', name: 'User One' },
{ email: 'user2@example.com', name: 'User Two' },
],
cc: 'manager@example.com',
bcc: ['audit@example.com'],
subject: 'Team Update',
html: '<p>Important announcement...</p>',
});
Using Templates
await mesa.send({
to: 'user@example.com',
subject: 'Order Confirmation',
templateId: 'order-confirmation',
templateData: {
orderNumber: 'ORD-12345',
items: [
{ name: 'Widget', quantity: 2, price: 29.99 },
],
total: 59.98,
},
});
With Attachments
import { readFileSync } from 'fs';
await mesa.send({
to: 'user@example.com',
subject: 'Your Invoice',
html: '<p>Please find your invoice attached.</p>',
attachments: [
{
filename: 'invoice.pdf',
content: readFileSync('./invoice.pdf').toString('base64'),
contentType: 'application/pdf',
},
],
});
Scheduled Send
await mesa.send({
to: 'user@example.com',
subject: 'Reminder',
html: '<p>Don\'t forget about your appointment!</p>',
scheduledAt: '2024-01-15T09:00:00Z',
});
Override Tracking per Email
await mesa.send({
to: 'user@example.com',
subject: 'Sensitive Information',
html: '<p>Your password reset link...</p>',
tracking: {
clicks: false, // Disable click tracking for this email
opens: false, // Disable open tracking for this email
},
});
Batch Sending
const responses = await mesa.sendBatch([
{ to: 'user1@example.com', subject: 'Hello User 1', html: '...' },
{ to: 'user2@example.com', subject: 'Hello User 2', html: '...' },
{ to: 'user3@example.com', subject: 'Hello User 3', html: '...' },
]);
responses.forEach((res) => console.log('Sent:', res.id));
Check Email Status
const status = await mesa.getStatus('email-id-here');
console.log(status);
Webhook Handling
Verify Webhook Signature
import express from 'express';
const app = express();
app.post('/webhooks/mesa', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-mesa-signature'] as string;
const payload = req.body.toString();
if (!mesa.verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET!)) {
return res.status(401).send('Invalid signature');
}
const event = mesa.parseWebhook(payload);
switch (event.event) {
case 'email.delivered':
console.log('Email delivered:', event.messageId);
break;
case 'email.bounced':
console.log('Email bounced:', event.messageId, event.data);
break;
case 'email.opened':
console.log('Email opened:', event.messageId);
break;
case 'email.clicked':
console.log('Link clicked:', event.data.url);
break;
}
res.status(200).send('OK');
});
Runtime Configuration Updates
// Update mail config at runtime
mesa.updateMailConfig({
sandbox: true, // Enable sandbox mode
});
// Get current config
const config = mesa.getMailConfig();
Error Handling
import { MesaClient, MesaAPIError, MesaValidationError } from '@armco/mesa-sdk';
try {
await mesa.send({ /* ... */ });
} catch (error) {
if (error instanceof MesaValidationError) {
console.error('Validation error:', error.message, 'Field:', error.field);
} else if (error instanceof MesaAPIError) {
console.error('API error:', error.message);
console.error('Status:', error.statusCode);
console.error('Code:', error.code);
console.error('Details:', error.details);
} else {
console.error('Unknown error:', error);
}
}
TypeScript Support
Full TypeScript support with exported types:
import type {
MesaConfig,
MailConfig,
SendEmailOptions,
SendEmailResponse,
EmailAddress,
Attachment,
WebhookEvent,
WebhookPayload,
} from '@armco/mesa-sdk';
Environment Variables
Recommended setup:
# .env
MESA_API_KEY=your-api-key
MESA_API_URL=https://api.sandesh.armco.dev # Optional
WEBHOOK_SECRET=your-webhook-secret
License
MIT
Description
Languages
TypeScript
99%
Shell
1%