Official Metigan SDK - Email, OTP, Transactional, Forms, Contacts, and Audiences management with built-in security features
npm install metiganbash
npm install metigan
or
yarn add metigan
`
🚀 Quick Start
`typescript
import Metigan from 'metigan';
// Initialize the client with all features
const metigan = new Metigan({
apiKey: 'your-api-key'
});
// Send email
await metigan.email.sendEmail({
from: 'Your Company ',
recipients: ['customer@email.com'],
subject: 'Welcome!',
content: 'Hello!
Thank you for signing up.
'
});
// Send OTP (fast lane)
await metigan.email.sendOtp({
from: 'Your Company ',
to: 'customer@email.com',
code: '348921',
appName: 'Metigan',
expiresInMinutes: 10
});
// Send transactional email (fast lane)
await metigan.email.sendTransactional({
from: 'Your Company ',
to: 'customer@email.com',
subject: 'Your receipt',
content: 'Thanks for your purchase.
'
});
// Submit form
await metigan.forms.submit({
formId: 'form-123',
data: {
email: 'user@email.com',
name: 'John Doe'
}
});
// Create contact
await metigan.contacts.create({
email: 'new@email.com',
firstName: 'Jane',
audienceId: 'audience-456'
});
`
📧 Email Module
$3
`typescript
const response = await metigan.email.sendEmail({
from: 'Your Company ',
recipients: ['recipient@email.com'],
subject: 'Email Subject',
content: 'HTML Content
'
});
`
$3
`typescript
import fs from 'fs';
const response = await metigan.email.sendEmail({
from: 'company@email.com',
recipients: ['customer@email.com'],
subject: 'Important Document',
content: 'Please find the document attached.',
attachments: [
{
buffer: fs.readFileSync('./document.pdf'),
originalname: 'document.pdf',
mimetype: 'application/pdf'
}
]
});
`
$3
`typescript
await metigan.email.sendEmail({
from: 'company@email.com',
recipients: ['main@email.com'],
subject: 'Meeting',
content: 'Email content',
cc: ['copy@email.com'],
bcc: ['hidden-copy@email.com'],
replyTo: 'reply-here@email.com'
});
`
$3
`typescript
await metigan.email.sendOtp({
from: 'Your Company ',
to: 'user@email.com',
code: '482193',
appName: 'Metigan',
expiresInMinutes: 10
});
`
$3
`typescript
await metigan.email.sendTransactional({
from: 'Your Company ',
to: 'user@email.com',
subject: 'Password changed',
content: 'Your password was updated successfully.
'
});
`
📋 Forms Module
$3
`typescript
const response = await metigan.forms.submit({
formId: 'form-123', // or form slug
data: {
'field-email': 'user@email.com',
'field-name': 'John Doe',
'field-message': 'Hello, I would like more information.'
}
});
console.log(response.message); // "Thank you for your submission!"
`
$3
`typescript
// By slug (for public display)
const form = await metigan.forms.getPublicForm('my-form');
console.log(form.title);
console.log(form.fields);
`
$3
`typescript
const { forms, pagination } = await metigan.forms.listForms({
page: 1,
limit: 10
});
forms.forEach(form => {
console.log(${form.title} - ${form.analytics?.submissions || 0} responses);
});
`
$3
`typescript
const newForm = await metigan.forms.createForm({
title: 'Contact Form',
description: 'Get in touch with us',
fields: [
{
id: 'field-email',
type: 'email',
label: 'Your Email',
required: true
},
{
id: 'field-name',
type: 'text',
label: 'Your Name',
required: true
},
{
id: 'field-subject',
type: 'select',
label: 'Subject',
options: ['Support', 'Sales', 'Partnerships']
},
{
id: 'field-message',
type: 'textarea',
label: 'Message',
required: true
}
],
settings: {
successMessage: 'Thank you! We will get back to you soon.',
notifyEmail: 'contact@company.com'
}
});
`
$3
`typescript
const { publishedUrl, slug } = await metigan.forms.publishForm('form-123', 'contact');
console.log(Form published at: ${publishedUrl});
`
$3
`typescript
const analytics = await metigan.forms.getAnalytics('form-123');
console.log(Views: ${analytics.views});
console.log(Submissions: ${analytics.submissions});
console.log(Conversion rate: ${analytics.conversionRate}%);
`
👥 Contacts Module
$3
`typescript
const contact = await metigan.contacts.create({
email: 'new@email.com',
firstName: 'Jane',
lastName: 'Doe',
audienceId: 'audience-123',
tags: ['customer', 'newsletter']
});
`
$3
`typescript
// By ID
const contact = await metigan.contacts.get('contact-456');
// By email
const contact = await metigan.contacts.getByEmail('jane@email.com', 'audience-123');
`
$3
`typescript
const updated = await metigan.contacts.update('contact-456', {
firstName: 'Jane Marie',
tags: ['customer', 'vip']
});
`
$3
`typescript
// Unsubscribe
await metigan.contacts.unsubscribe('contact-456');
// Resubscribe
await metigan.contacts.subscribe('contact-456');
`
$3
`typescript
// Add tags
await metigan.contacts.addTags('contact-456', ['vip', 'black-friday']);
// Remove tags
await metigan.contacts.removeTags('contact-456', ['test']);
`
$3
`typescript
const { contacts, pagination } = await metigan.contacts.list({
audienceId: 'audience-123',
status: 'subscribed',
tag: 'customer',
page: 1,
limit: 50
});
`
$3
`typescript
const result = await metigan.contacts.bulkImport(
[
{ email: 'john@email.com', firstName: 'John' },
{ email: 'jane@email.com', firstName: 'Jane' },
{ email: 'peter@email.com', firstName: 'Peter', tags: ['vip'] }
],
'audience-123'
);
console.log(Imported: ${result.imported});
console.log(Failed: ${result.failed});
`
$3
`typescript
const results = await metigan.contacts.search('doe', 'audience-123');
`
📊 Audiences Module
$3
`typescript
const audience = await metigan.audiences.create({
name: 'Main Newsletter',
description: 'Main subscriber list'
});
`
$3
`typescript
const { audiences, pagination } = await metigan.audiences.list({
page: 1,
limit: 10
});
audiences.forEach(audience => {
console.log(${audience.name}: ${audience.count} contacts);
});
`
$3
`typescript
const stats = await metigan.audiences.getStats('audience-123');
console.log(Total: ${stats.total});
console.log(Subscribed: ${stats.subscribed});
console.log(Unsubscribed: ${stats.unsubscribed});
console.log(Bounced: ${stats.bounced});
`
$3
`typescript
// Remove bounced and unsubscribed contacts
const { removed } = await metigan.audiences.clean('audience-123');
console.log(${removed} contacts removed);
`
$3
`typescript
// Merge source into target (source is deleted)
const merged = await metigan.audiences.merge(
'source-audience-id',
'target-audience-id'
);
`
⚙️ Advanced Configuration
`typescript
const metigan = new Metigan({
apiKey: 'your-api-key',
// User ID for logging
userId: 'user-123',
// Disable logging
disableLogs: true,
// Timeout in milliseconds
timeout: 60000,
// Number of retries on failure
retryCount: 5,
// Delay between retries (ms)
retryDelay: 2000,
// Security options (see Security section)
debug: false,
sanitizeHtml: true,
enableRateLimit: true,
maxRequestsPerSecond: 10
});
`
🔒 Security Features
The SDK includes built-in security features:
$3
Automatically removes dangerous HTML tags and attributes from email content to prevent XSS attacks:
`typescript
// HTML sanitization is enabled by default
const metigan = new Metigan({
apiKey: 'your-api-key',
sanitizeHtml: true // default
});
// Dangerous content is automatically sanitized
await metigan.email.sendEmail({
from: 'company@email.com',
recipients: ['user@email.com'],
subject: 'Newsletter',
content: 'Hello
' // Script tag will be removed
});
`
$3
Prevents accidental API abuse with built-in rate limiting:
`typescript
const metigan = new Metigan({
apiKey: 'your-api-key',
enableRateLimit: true, // default
maxRequestsPerSecond: 10 // default
});
// Check rate limit before making requests
if (metigan.email.canMakeRequest()) {
await metigan.email.sendEmail({...});
} else {
const waitTime = metigan.email.getTimeUntilNextRequest();
console.log(Please wait ${waitTime}ms before next request);
}
// Reset rate limiter if needed
metigan.email.resetRateLimit();
`
$3
Validates file attachments for security:
`typescript
import { isAllowedMimeType, isSafeFileExtension, ALLOWED_MIME_TYPES } from 'metigan';
// Check if file type is safe
const filename = 'document.pdf';
const mimetype = 'application/pdf';
if (isSafeFileExtension(filename) && isAllowedMimeType(mimetype)) {
// Safe to attach
}
// View allowed MIME types
console.log(ALLOWED_MIME_TYPES);
`
$3
Email addresses and subjects are automatically sanitized to prevent header injection attacks:
`typescript
import { sanitizeEmail, sanitizeSubject } from 'metigan';
// Remove newlines and dangerous characters
const safeEmail = sanitizeEmail('user@email.com\r\nBcc: hacker@evil.com');
const safeSubject = sanitizeSubject('Subject\r\nFrom: hacker@evil.com');
`
$3
Enable debug mode for troubleshooting (logs are hidden by default in production):
`typescript
const metigan = new Metigan({
apiKey: 'your-api-key',
debug: true // Shows internal logs
});
// Or enable/disable at runtime
metigan.email.enableDebug();
metigan.email.disableDebug();
`
$3
For advanced use cases, you can create your own rate limiter:
`typescript
import { RateLimiter } from 'metigan';
const limiter = new RateLimiter({
maxRequests: 5,
windowMs: 1000 // 5 requests per second
});
if (limiter.tryRequest()) {
// Request allowed and recorded
await makeApiCall();
} else {
// Rate limited
console.log(Wait ${limiter.getTimeUntilNextRequest()}ms);
}
`
🔧 Using Individual Modules
If you only need a specific module:
`typescript
import { MetiganForms, MetiganContacts, MetiganAudiences } from 'metigan';
// Forms only
const forms = new MetiganForms({
apiKey: 'your-api-key'
});
// Contacts only
const contacts = new MetiganContacts({
apiKey: 'your-api-key'
});
// Audiences only
const audiences = new MetiganAudiences({
apiKey: 'your-api-key'
});
`
🌐 Browser Usage
`html
`
🛡️ Error Handling
`typescript
import { MetiganError, ValidationError, ApiError } from 'metigan';
try {
await metigan.email.sendEmail({
from: 'invalid',
recipients: [],
subject: '',
content: ''
});
} catch (error) {
if (error instanceof ValidationError) {
console.error('Invalid data:', error.message);
} else if (error instanceof ApiError) {
console.error(API error (${error.status}):, error.message);
} else if (error instanceof MetiganError) {
console.error('Metigan error:', error.message);
} else {
console.error('Unknown error:', error);
}
}
`
📝 TypeScript
The library includes full TypeScript definitions:
`typescript
import Metigan, {
EmailOptions,
OtpSendOptions,
TransactionalSendOptions,
FormConfig,
Contact,
Audience,
FormFieldType
} from 'metigan';
const emailOptions: EmailOptions = {
from: 'company@email.com',
recipients: ['customer@email.com'],
subject: 'Test',
content: 'Content
'
};
const fieldType: FormFieldType = 'email';
const otpOptions: OtpSendOptions = {
from: 'company@email.com',
to: 'user@email.com',
code: '123456'
};
const transactionalOptions: TransactionalSendOptions = {
from: 'company@email.com',
to: 'user@email.com',
subject: 'Invoice ready',
content: 'Your invoice is ready.
'
};
``