Skip to content

A lightweight SMTP client for Deno. Built with native APIs, zero dependencies, send emails with attachments, and more.

License

Notifications You must be signed in to change notification settings

NeaByteLab/Deno-Mailer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deno Mailer Deno License: MIT

A lightweight SMTP client for Deno. Built with native APIs, zero dependencies, simple setup.

Table of Contents

Installation

deno install @neabyte/deno-mailer

Quick Start

import mailer from '@neabyte/deno-mailer'

const transporter = mailer.transporter({
  host: 'smtp.domain.com',
  port: 587,
  secure: false,
  auth: {
    user: '[email protected]',
    pass: 'password'
  }
})

await transporter.send({
  from: '"John Doe" <[email protected]>',
  to: '[email protected]',
  subject: 'Test Email',
  text: 'This is a test email',
  html: '<b>This is a test email</b>'
})

Configuration

SMTP Settings

const config = {
  host: 'smtp.gmail.com', // SMTP server hostname
  port: 587, // SMTP server port
  secure: false, // Use TLS (true for port 465, false for 587)
  auth: {
    user: '[email protected]',
    pass: 'your-app-password'
  }
}

Authentication

Deno-Mailer supports both LOGIN and PLAIN authentication methods:

// Basic authentication
auth: {
  user: 'username',
  pass: 'password'
}

// No authentication (for local SMTP servers)
// Simply omit the auth property

TLS/SSL Options

// Port 587 with STARTTLS (recommended)
{
  host: 'smtp.gmail.com',
  port: 587,
  secure: false  // Will upgrade to TLS via STARTTLS
}

// Port 465 with direct TLS
{
  host: 'smtp.gmail.com',
  port: 465,
  secure: true   // Direct TLS connection
}

Basic Usage

Simple Text Email

await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Hello World',
  text: 'This is a plain text email'
})

HTML Email

await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'HTML Email',
  html: '<h1>Hello!</h1><p>This is an <strong>HTML</strong> email.</p>'
})

Mixed Content

await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Mixed Content',
  text: 'This is the plain text version',
  html: '<h1>This is the HTML version</h1>'
})

Multiple Recipients

await transporter.send({
  from: '[email protected]',
  to: ['[email protected]', '[email protected]'],
  cc: '[email protected]',
  bcc: '[email protected]',
  replyTo: '[email protected]',
  subject: 'Email to Multiple Recipients',
  text: 'This email goes to multiple people'
})

Advanced Recipient Formats

// Mixed recipient formats
await transporter.send({
  from: { name: 'John Doe', address: '[email protected]' },
  to: [
    '[email protected]',
    { name: 'Jane Smith', address: '[email protected]' },
    '"Display Name" <[email protected]>'
  ],
  cc: [
    '[email protected]',
    { name: 'Team Lead', address: '[email protected]' }
  ],
  bcc: '[email protected]',
  replyTo: { name: 'Support Team', address: '[email protected]' },
  subject: 'Advanced Recipient Formats',
  text: 'Supports various recipient formats'
})

Advanced Features

File Attachments

// Single attachment
await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Email with Attachment',
  text: 'Check the attached file',
  attachments: [{
    filename: 'document.pdf',
    content: fileContent, // Uint8Array or base64 string
    contentType: 'application/pdf',
    encoding: 'base64' // 'base64', '7bit', or 'quoted-printable'
  }]
})

// Multiple attachments with different encodings
await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Multiple Attachments',
  text: 'Check the attached files',
  attachments: [
    {
      filename: 'document.pdf',
      content: pdfData,
      contentType: 'application/pdf',
      encoding: 'base64'
    },
    {
      filename: 'image.jpg',
      content: imgData,
      contentType: 'image/jpeg',
      encoding: 'base64'
    },
    {
      filename: 'readme.txt',
      content: 'Plain text content',
      contentType: 'text/plain',
      encoding: '7bit'
    }
  ]
})

Embedded Images

await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Email with Image',
  html: '<h1>Hello!</h1><img src="cid:logo">',
  embeddedImages: [{
    filename: 'logo.png',
    content: imageContent,
    contentType: 'image/png',
    cid: '<[email protected]>',
    disposition: 'inline' // 'inline' or 'attachment'
  }]
})

Calendar Invitations

// Basic calendar event
await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Meeting Invitation',
  text: 'You are invited to a meeting',
  calendarEvent: {
    uid: 'meeting-123',
    summary: 'Team Meeting',
    description: 'Weekly team sync',
    location: 'Conference Room A',
    startTime: '2024-01-15T10:00:00Z',
    endTime: '2024-01-15T11:00:00Z',
    organizer: '[email protected]',
    attendees: ['[email protected]', '[email protected]']
  }
})

// Complete calendar event with all options
await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Important Meeting',
  text: 'Please attend this important meeting',
  html: '<h1>Important Meeting</h1><p>Please attend this meeting.</p>',
  calendarEvent: {
    uid: 'important-meeting-456',
    summary: 'Quarterly Review',
    description: 'Q4 performance review and planning for next quarter',
    location: 'Main Conference Room, Building A',
    startTime: '2024-01-20T14:00:00Z',
    endTime: '2024-01-20T16:00:00Z',
    organizer: '[email protected]',
    attendees: [
      '[email protected]',
      '[email protected]',
      '[email protected]'
    ],
    status: 'CONFIRMED'
  }
})

Custom Headers

await transporter.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Custom Headers',
  text: 'Email with custom headers',
  headers: {
    'X-Priority': '1',
    'X-Custom-Header': 'Custom Value'
  }
})

API Reference

Main API

Method Description Parameters Returns
mailer.transporter(config) Creates email transporter SmtpConnectionConfig EmailSender
transporter.send(message) Sends email message EmailMessage Promise<void>

Configuration Options

Option Type Required Description Example
host string SMTP server hostname 'smtp.gmail.com'
port number SMTP server port 587, 465, 25
secure boolean Use TLS connection true (port 465), false (port 587)
auth.user string SMTP username '[email protected]'
auth.pass string SMTP password 'your-password'

Message Properties

Property Type Required Description Examples
from string/object Sender email address '[email protected]', {name: 'John', address: '[email protected]'}
to string/array Recipient email address(es) '[email protected]', ['[email protected]', '[email protected]']
subject string Email subject line 'Hello World'
text string Plain text content 'This is plain text'
html string HTML content '<h1>Hello</h1>'
cc string/array Carbon copy recipients '[email protected]'
bcc string/array Blind carbon copy recipients '[email protected]'
replyTo string/object Reply-to address '[email protected]'
attachments array File attachments [{filename: 'file.pdf', content: data}]
embeddedImages array Embedded images [{filename: 'img.png', content: data, cid: '<[email protected]>'}]
calendarEvent object Calendar invitation {uid: 'event-123', summary: 'Meeting', startTime: '2024-01-01T10:00:00Z'}
headers object Custom email headers {'X-Priority': '1'}

Error Handling

try {
  await transporter.send(message)
} catch (error) {
  console.error('Email failed:', error.message)
  // Handle specific error types
  if (error.message.includes('authentication')) {
    // Handle auth errors
  } else if (error.message.includes('connection')) {
    // Handle connection errors
  }
}

Examples

Gmail SMTP

const transporter = mailer.transporter({
  host: 'smtp.gmail.com',
  port: 587,
  secure: false,
  auth: {
    user: '[email protected]',
    pass: 'your-app-password' // Use App Password, not regular password
  }
})

Outlook SMTP

const transporter = mailer.transporter({
  host: 'smtp-mail.outlook.com',
  port: 587,
  secure: false,
  auth: {
    user: '[email protected]',
    pass: 'your-password'
  }
})

Custom SMTP Server

const transporter = mailer.transporter({
  host: 'mail.yourcompany.com',
  port: 587,
  secure: false,
  auth: {
    user: '[email protected]',
    pass: 'your-password'
  }
})

Troubleshooting

Common Issues

Authentication Failed

  • Verify username/password are correct
  • For Gmail, use App Passwords instead of regular passwords
  • Check if 2FA is enabled and use App Password

Connection Timeout

  • Verify SMTP server hostname and port
  • Check firewall settings
  • Try different ports (587, 465, 25)

TLS Errors

  • Ensure secure: false for port 587 (STARTTLS)
  • Use secure: true for port 465 (direct TLS)
  • Check server TLS certificate

Debug Mode

// Add error logging
try {
  await transporter.send(message)
  console.log('Email sent successfully')
} catch (error) {
  console.error('SMTP Error:', error.message)
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT license. See the LICENSE file for more info.