Socket
Book a DemoInstallSign in
Socket

metigan

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

metigan

Official Metigan SDK - Email, Forms, Contacts, and Audiences management with built-in security features

latest
Source
npmnpm
Version
2.2.0
Version published
Weekly downloads
3
Maintainers
1
Weekly downloads
 
Created
Source

Metigan SDK

The official Metigan library for Node.js and browsers. Send emails, manage forms, contacts, and audiences with ease.

📦 Installation

npm install metigan
# or
yarn add metigan

🚀 Quick Start

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 <noreply@yourcompany.com>',
  recipients: ['customer@email.com'],
  subject: 'Welcome!',
  content: '<h1>Hello!</h1><p>Thank you for signing up.</p>'
});

// 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

Basic Send

const response = await metigan.email.sendEmail({
  from: 'Your Company <noreply@yourcompany.com>',
  recipients: ['recipient@email.com'],
  subject: 'Email Subject',
  content: '<h1>HTML Content</h1>'
});

With Attachments (Node.js)

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'
    }
  ]
});

With CC and BCC

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'
});

📋 Forms Module

Submit Response

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!"

Get Public Form

// By slug (for public display)
const form = await metigan.forms.getPublicForm('my-form');

console.log(form.title);
console.log(form.fields);

List Forms

const { forms, pagination } = await metigan.forms.listForms({
  page: 1,
  limit: 10
});

forms.forEach(form => {
  console.log(`${form.title} - ${form.analytics?.submissions || 0} responses`);
});

Create Form

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'
  }
});

Publish Form

const { publishedUrl, slug } = await metigan.forms.publishForm('form-123', 'contact');
console.log(`Form published at: ${publishedUrl}`);

Form Analytics

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

Create Contact

const contact = await metigan.contacts.create({
  email: 'new@email.com',
  firstName: 'Jane',
  lastName: 'Doe',
  audienceId: 'audience-123',
  tags: ['customer', 'newsletter']
});

Get Contact

// By ID
const contact = await metigan.contacts.get('contact-456');

// By email
const contact = await metigan.contacts.getByEmail('jane@email.com', 'audience-123');

Update Contact

const updated = await metigan.contacts.update('contact-456', {
  firstName: 'Jane Marie',
  tags: ['customer', 'vip']
});

Manage Subscription

// Unsubscribe
await metigan.contacts.unsubscribe('contact-456');

// Resubscribe
await metigan.contacts.subscribe('contact-456');

Manage Tags

// Add tags
await metigan.contacts.addTags('contact-456', ['vip', 'black-friday']);

// Remove tags
await metigan.contacts.removeTags('contact-456', ['test']);

List Contacts

const { contacts, pagination } = await metigan.contacts.list({
  audienceId: 'audience-123',
  status: 'subscribed',
  tag: 'customer',
  page: 1,
  limit: 50
});

Bulk Import

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}`);

Search Contacts

const results = await metigan.contacts.search('doe', 'audience-123');

📊 Audiences Module

Create Audience

const audience = await metigan.audiences.create({
  name: 'Main Newsletter',
  description: 'Main subscriber list'
});

List Audiences

const { audiences, pagination } = await metigan.audiences.list({
  page: 1,
  limit: 10
});

audiences.forEach(audience => {
  console.log(`${audience.name}: ${audience.count} contacts`);
});

Audience Statistics

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}`);

Clean Audience

// Remove bounced and unsubscribed contacts
const { removed } = await metigan.audiences.clean('audience-123');
console.log(`${removed} contacts removed`);

Merge Audiences

// Merge source into target (source is deleted)
const merged = await metigan.audiences.merge(
  'source-audience-id',
  'target-audience-id'
);

⚙️ Advanced Configuration

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:

HTML Sanitization

Automatically removes dangerous HTML tags and attributes from email content to prevent XSS attacks:

// 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: '<h1>Hello</h1><script>alert("xss")</script>' // Script tag will be removed
});

Client-Side Rate Limiting

Prevents accidental API abuse with built-in rate limiting:

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();

Attachment Validation

Validates file attachments for security:

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);

Email Header Injection Prevention

Email addresses and subjects are automatically sanitized to prevent header injection attacks:

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');

Debug Mode

Enable debug mode for troubleshooting (logs are hidden by default in production):

const metigan = new Metigan({
  apiKey: 'your-api-key',
  debug: true // Shows internal logs
});

// Or enable/disable at runtime
metigan.email.enableDebug();
metigan.email.disableDebug();

Custom Rate Limiter

For advanced use cases, you can create your own rate limiter:

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:

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

<script src="https://unpkg.com/metigan/dist/index.js"></script>
<script>
  const metigan = new Metigan({ apiKey: 'your-api-key' });
  
  // Submit form
  document.getElementById('my-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    
    const formData = new FormData(e.target);
    const data = Object.fromEntries(formData);
    
    try {
      const response = await metigan.forms.submit({
        formId: 'form-123',
        data
      });
      alert(response.message);
    } catch (error) {
      alert('Error submitting: ' + error.message);
    }
  });
</script>

🛡️ Error Handling

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:

import Metigan, {
  EmailOptions,
  FormConfig,
  Contact,
  Audience,
  FormFieldType
} from 'metigan';

const emailOptions: EmailOptions = {
  from: 'company@email.com',
  recipients: ['customer@email.com'],
  subject: 'Test',
  content: '<p>Content</p>'
};

const fieldType: FormFieldType = 'email';

📄 License

MIT © Metigan

  • Documentation
  • Dashboard
  • API Reference
  • Examples

Keywords

email

FAQs

Package last updated on 05 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts