@armco/mesa-sdk
v1.0.3
Published
Official Node.js SDK for Sandesh/Mesa Email Platform
Maintainers
Readme
@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-sdkQuick Start
import { MesaClient } from '@armco/mesa-sdk';
const mesa = new MesaClient({
apiKey: process.env.MESA_API_KEY!,
});
await mesa.send({
from: { email: '[email protected]', name: 'My App' },
to: '[email protected]',
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: '[email protected]', name: 'My App' },
defaultReplyTo: { email: '[email protected]' },
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: '[email protected]',
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: '[email protected]', name: 'User One' },
{ email: '[email protected]', name: 'User Two' },
],
cc: '[email protected]',
bcc: ['[email protected]'],
subject: 'Team Update',
html: '<p>Important announcement...</p>',
});Using Templates
await mesa.send({
to: '[email protected]',
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: '[email protected]',
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: '[email protected]',
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: '[email protected]',
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: '[email protected]', subject: 'Hello User 1', html: '...' },
{ to: '[email protected]', subject: 'Hello User 2', html: '...' },
{ to: '[email protected]', 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-secretLicense
MIT
