home / skills / aidotnet / moyucode / nodemailer

nodemailer skill

/skills/tools/nodemailer

This skill helps you send emails from Node.js using SMTP, OAuth2, attachments, and HTML templates with ease.

npx playbooks add skill aidotnet/moyucode --skill nodemailer

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.9 KB
---
name: nodemailer
description: 从Node.js应用发送邮件。最流行的邮件发送模块,支持SMTP、OAuth2、附件和HTML模板。
metadata:
  short-description: Node.js邮件发送
source:
  repository: https://github.com/nodemailer/nodemailer
  license: MIT
  stars: 17k+
---

# Nodemailer Tool

## Description
Send emails from Node.js with SMTP, OAuth2, attachments, and HTML templates.

## Source
- Repository: [nodemailer/nodemailer](https://github.com/nodemailer/nodemailer)
- License: MIT

## Installation

```bash
npm install nodemailer
```

## Usage Examples

### Basic Email

```typescript
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.gmail.com',
  port: 587,
  secure: false,
  auth: {
    user: process.env.EMAIL_USER,
    pass: process.env.EMAIL_PASS,
  },
});

async function sendEmail() {
  const info = await transporter.sendMail({
    from: '"My App" <[email protected]>',
    to: '[email protected]',
    subject: 'Welcome to My App',
    text: 'Hello, welcome to our platform!',
    html: '<h1>Hello</h1><p>Welcome to our platform!</p>',
  });
  
  console.log('Message sent:', info.messageId);
}
```

### HTML Email with Template

```typescript
async function sendWelcomeEmail(user: { name: string; email: string }) {
  const html = `
    <!DOCTYPE html>
    <html>
      <head>
        <style>
          .container { max-width: 600px; margin: 0 auto; font-family: Arial; }
          .header { background: #4F46E5; color: white; padding: 20px; }
          .content { padding: 20px; }
          .button { background: #4F46E5; color: white; padding: 12px 24px; 
                    text-decoration: none; border-radius: 4px; }
        </style>
      </head>
      <body>
        <div class="container">
          <div class="header">
            <h1>Welcome, ${user.name}!</h1>
          </div>
          <div class="content">
            <p>Thank you for joining our platform.</p>
            <a href="https://myapp.com/dashboard" class="button">Get Started</a>
          </div>
        </div>
      </body>
    </html>
  `;
  
  await transporter.sendMail({
    from: '"My App" <[email protected]>',
    to: user.email,
    subject: `Welcome, ${user.name}!`,
    html,
  });
}
```

### Email with Attachments

```typescript
async function sendEmailWithAttachment() {
  await transporter.sendMail({
    from: '"Reports" <[email protected]>',
    to: '[email protected]',
    subject: 'Monthly Report',
    text: 'Please find the monthly report attached.',
    attachments: [
      {
        filename: 'report.pdf',
        path: './reports/monthly-report.pdf',
      },
      {
        filename: 'data.xlsx',
        content: Buffer.from('...'), // Buffer content
      },
      {
        filename: 'logo.png',
        path: './assets/logo.png',
        cid: 'logo@myapp', // For embedding in HTML
      },
    ],
    html: '<img src="cid:logo@myapp" /><p>See attached report.</p>',
  });
}
```

### OAuth2 Authentication (Gmail)

```typescript
const transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    type: 'OAuth2',
    user: process.env.GMAIL_USER,
    clientId: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    refreshToken: process.env.GOOGLE_REFRESH_TOKEN,
  },
});
```

### Email Queue with Rate Limiting

```typescript
class EmailQueue {
  private queue: Array<() => Promise<void>> = [];
  private processing = false;
  
  async add(emailFn: () => Promise<void>) {
    this.queue.push(emailFn);
    this.process();
  }
  
  private async process() {
    if (this.processing) return;
    this.processing = true;
    
    while (this.queue.length > 0) {
      const emailFn = this.queue.shift()!;
      await emailFn();
      await new Promise(r => setTimeout(r, 1000)); // Rate limit
    }
    
    this.processing = false;
  }
}
```

## Tags
`email`, `smtp`, `notification`, `communication`, `automation`

## Compatibility
- Codex: ✅
- Claude Code: ✅

Overview

This skill sends email from Node.js applications using a robust, production-ready mailer. It supports SMTP, OAuth2 (for providers like Gmail), attachments, embedded images, and HTML templates for rich messages. The API is TypeScript-friendly and works well for transactional notifications, reports, and user onboarding emails.

How this skill works

You create a transporter configured with SMTP credentials or OAuth2 tokens, then call sendMail with message options (from, to, subject, text, html). Attachments and inline images are passed in an attachments array with file paths, Buffers, or content strings. For high-volume use, you can queue sends and apply rate limiting to avoid provider throttling.

When to use it

  • Send transactional emails (password resets, receipts, confirmations).
  • Deliver scheduled or periodic reports with PDF or spreadsheet attachments.
  • Send HTML marketing or onboarding emails with templated content.
  • Embed images inside emails using CID for branded content.
  • Integrate with Gmail via OAuth2 to avoid storing raw passwords.

Best practices

  • Keep credentials and OAuth tokens in environment variables or a secrets store.
  • Use HTML templates and inline CSS for consistent cross-client rendering.
  • Attach only required files and stream large attachments to avoid memory spikes.
  • Implement a queue with rate limiting and retries to handle provider limits and transient failures.
  • Verify SPF/DKIM/DMARC and use a proper from-domain to improve deliverability.

Example use cases

  • Welcome emails with personalized HTML templates and a CTA button.
  • Automated monthly reports sent as PDF attachments to stakeholders.
  • Password reset emails with short plaintext and an HTML fallback.
  • Embedding company logo in newsletters using CID-linked images.
  • Gmail-based sending using OAuth2 to manage app-level authorization.

FAQ

Can I send attachments and inline images?

Yes. Use the attachments array to attach files by path, Buffer, or content, and set a cid to embed images referenced from the HTML.

How do I avoid being rate-limited by email providers?

Implement an email queue with delays, batch sends, and exponential backoff for retries. Monitor provider quotas and spread traffic over time.