Skip to content

Command-line tool to send an email, or automate repetitive emails. Built with TypeScript and https://nodemailer.com/.

License

Notifications You must be signed in to change notification settings

isocialPractice/sendEmail

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sendEmail

Command-line tool to send an email, or automate repetitive emails.

Built with TypeScript and nodemailer. Engine-like design — can be embedded in VS Code extensions, GUIs, or any Node.js application.


Quick Start

# Install dependencies
npm install

# Build TypeScript
npm run build

# Send a quick text email
sendEmail -t someone@example.com "Hello from sendEmail"

# Show full help
sendEmail -h

Setup

1. Configure Your Email Account

Run the setup script to create config/accounts/_default.js from the template:

Unix/macOS/Git Bash

bash .github/scripts/setup.sh

Windows CMD

.github\scripts\setup.bat

Then edit config/accounts/_default.js with your credentials.

For Gmail, use an App Password (requires 2FA).

Caution

config/accounts/ is excluded from git — it contains real credentials. Never run git add -f config/accounts/ — this bypasses .gitignore and will expose your credentials. See config/README.md for full details.

2. Build

npm run build

3. (Optional) Add to PATH

# Unix/macOS
chmod +x bin/sendEmail.sh
ln -s $(pwd)/bin/sendEmail.sh /usr/local/bin/sendEmail

# Windows: add the bin/ directory to your PATH

Usage

sendEmail [options] [arguments]

Send Modes

Mode Example
Raw (quick text) sendEmail -t user@example.com "Message"
Normal (structured) sendEmail --send-to user@example.com --subject "Hello" --message-html body.html
Repetitive (bulk) sendEmail --config-email newsletter --email-list subscribers --force

Common Examples

# Quick text email
sendEmail -t someone@example.com "Quick message"

# HTML email
sendEmail --send-to john@example.com --subject "Report" --message-html ./report.html

# Markdown email (auto-converted to HTML)
sendEmail --send-to team@company.com --subject "Update" --message-file ./update.md

# Configured email template
sendEmail --config-email billing --send-to client@example.com

# Bulk send to list
sendEmail --config-email newsletter --email-list subscribers --force

# Show help
sendEmail -h
sendEmail -h options
sendEmail -h options:configurable

Relative paths for --message-file, --message-html, and --message-text are resolved from your current working directory first; if no match is found, sendEmail falls back to its config/tool root.


Project Structure

sendEmail/
├── src/
│   ├── core/                  # Core engine (interface-agnostic)
│   │   ├── engine.ts          # EmailEngine class
│   │   ├── types.ts           # All TypeScript interfaces
│   │   ├── config-loader.ts   # Load configurations
│   │   ├── template-engine.ts # Template variable substitution
│   │   ├── list-processor.ts  # Email list iteration
│   │   ├── attachment-loader.ts
│   │   └── validator.ts
│   ├── cli/                   # CLI entry point
│   │   ├── index.ts           # Main CLI runner
│   │   ├── parser.ts          # Argument parsing
│   │   ├── help.ts            # Help documentation
│   │   └── prompts.ts         # Confirmation prompts
│   ├── utils/                 # Utilities
│   │   ├── file-utils.ts
│   │   ├── logger.ts
│   │   ├── error-handler.ts
│   │   └── markdown-html.ts
│   └── tools/                 # Tool scripts
│       ├── list-generator.ts  # --new-list
│       ├── copy-tool.ts       # --copy
│       └── test-runner.ts     # --test
├── bin/
│   ├── sendEmail.js           # Node.js entry (npm bin)
│   ├── sendEmail.sh           # Unix/macOS wrapper
│   ├── sendEmail.cmd          # Windows CMD wrapper
│   └── sendEmail.ps1          # PowerShell wrapper
├── config/
│   ├── _accounts/             # Template (versioned) — rename to accounts/ to activate
│   ├── accounts/              # !! git-ignored !! — your real credentials live here
│   │   ├── _default.js        # REQUIRED default account
│   │   └── example.js
│   ├── emails/                # Configured email templates
│   │   ├── billing/
│   │   └── example/
│   └── globals/               # Reusable global templates
│       ├── footer/
│       └── example/
├── lists/                     # Email lists (.json)
├── attachments/               # Email attachments
├── img/                       # Embedded images
├── tests/
│   ├── unit/                  # Unit tests (vitest)
│   ├── mock/server/           # Mock SMTP server
│   └── logs/                  # Test logs
└── docs/
    ├── CLI-OPTIONS.md         # Full options reference
    ├── CLI-CHEATSHEET.md      # Quick reference
    ├── API.md                 # Engine API documentation
    └── EXAMPLES.md            # Real-world examples

Configuration

Account Config (config/accounts/*.js)

// New-style (recommended):
export const account = {
  service: 'gmail',
  auth: { user: 'your@gmail.com', pass: 'app-password' },
};

// Or with custom SMTP:
export const account = {
  host: 'smtp.example.com',
  port: 587,
  secure: false,
  auth: { user: 'user@example.com', pass: 'password' },
};

Email Config (config/emails/<name>/email.json)

{
  "from": "_default",
  "subject": "Billing Statement - {{contact.name}}",
  "html": "billingStatement",
  "globals": ["footer"]
}

Email List (lists/<name>.json)

{
  "email-list": [
    { "email": "alice@example.com", "name": "Alice" },
    { "email": "bob@example.com", "name": "Bob" }
  ]
}

Template Variables

Use in subject lines, HTML templates, and configurable text:

Variable Value
{{contact.name}} Contact's name
{{contact.email}} Contact's email
{{contact.<field>}} Any custom field
{{date}} 2026-02-19
{{date.formatted}} February 19, 2026
{{list.index}} Current index (bulk send)
{{list.count}} Total recipients

Legacy placeholders (CH-EMAILONLIST, CHANGE_SEND_TO) are also supported.


Using as a Library

import { EmailEngine, createEngineConfig } from './dist/core/engine.js';

const engine = new EmailEngine(createEngineConfig(process.cwd()));
await engine.initialize();

const result = await engine.sendEmail({
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Hello',
  html: '<p>Hello, World!</p>',
});

See docs/API.md for full API documentation.


Scripts

Command Description
npm run build Compile TypeScript to dist/
npm run build:watch Watch mode compilation
npm run dev Run CLI directly with tsx (no build needed)
npm test Run tests in watch mode
npm run test:run Run all tests once
sendEmail --test Run tests via CLI

Documentation

About

Command-line tool to send an email, or automate repetitive emails. Built with TypeScript and https://nodemailer.com/.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published