An open API service indexing awesome lists of open source software.

https://github.com/nurulislamrimon/sendora

A developer-first email service library for Node.js with SMTP support, Handlebars templates, and queue management
https://github.com/nurulislamrimon/sendora

mail mail-integration mail-package mailchimp mailer mailgun mailtrap node-mail nodemailer npm npm-package npmjs

Last synced: 11 days ago
JSON representation

A developer-first email service library for Node.js with SMTP support, Handlebars templates, and queue management

Awesome Lists containing this project

README

          

# sendora

[![npm version](https://img.shields.io/npm/v/sendora)](https://www.npmjs.com/package/sendora)
[![license](https://img.shields.io/npm/l/sendora)](LICENSE)
[![author](https://img.shields.io/badge/author-Nurul%20Islam%20Rimon-blue)](https://github.com/nurulislamrimon)
[![repo](https://img.shields.io/badge/repo-github.com%2Fnurulislamrimon%2Fsendora-lightgrey)](https://github.com/nurulislamrimon/sendora)

A developer-first email service library for Node.js that simplifies sending emails with templates, multiple providers, and excellent developer experience.

## Features

- **Simple API** - Intuitive interface for sending emails
- **Multiple Providers** - SMTP support with Nodemailer (SendGrid, Resend, Mailgun coming soon)
- **Template Engine** - Handlebars-based templates with layouts and partials
- **Type-safe** - Full TypeScript support with strong typing
- **Queue Support** - Built-in queue for background email processing
- **Developer-friendly Logging** - Powered by pino
- **Configuration Validation** - Zod-powered validation

## Installation

```bash
npm install sendora
```

## Quick Start

```typescript
import { Sendora } from 'sendora';

const mail = new Sendora({
provider: 'smtp',
smtp: {
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASS,
},
},
});

await mail.initialize();

await mail.send({
to: 'user@example.com',
subject: 'Welcome',
html: '

Hello World!

',
});
```

## Configuration

### SMTP Configuration

```typescript
const mail = new Sendora({
provider: 'smtp',
smtp: {
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: 'your-email@gmail.com',
pass: 'your-app-password',
},
},
from: 'Your App ',
});
```

### Full Configuration Options

```typescript
const mail = new Sendora({
provider: 'smtp',
smtp: {
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASS,
},
},
from: 'Sender ',
templates: {
dir: './templates',
ext: '.hbs',
layouts: {
dir: './templates/layouts',
default: 'main',
},
partials: {
dir: './templates/partials',
},
defaultData: {
company: 'My Company',
year: new Date().getFullYear(),
},
},
queue: {
enabled: true,
concurrency: 5,
delay: 1000,
},
logger: {
enabled: true,
level: 'debug',
prettyPrint: true,
},
defaultHeaders: {
'X-Mailer': 'Sendora',
},
});
```

## Email Options

```typescript
await mail.send({
from: 'Sender ',
to: ['user1@example.com', 'user2@example.com'],
cc: 'cc@example.com',
bcc: 'bcc@example.com',
subject: 'Email Subject',
text: 'Plain text version',
html: '

HTML version

',
replyTo: 'reply@example.com',
attachments: [
{
filename: 'document.pdf',
path: '/path/to/file.pdf',
},
],
headers: {
'X-Custom-Header': 'value',
},
});
```

## Templates

### Creating Templates

Create your templates in the configured templates directory:

```handlebars
{{!-- templates/welcome.hbs --}}

Hello {{name}}!


Welcome to {{company}}.


```

### Using Templates

```typescript
await mail.send({
to: 'user@example.com',
subject: 'Welcome!',
template: 'welcome',
data: {
name: 'John',
company: 'Acme Inc',
},
});
```

### Layouts

```handlebars
{{!-- templates/layouts/main.hbs --}}

{{title}}

{{{body}}}

```

### Partials

```handlebars
{{!-- templates/partials/button.hbs --}}
{{text}}
```

```handlebars
{{!-- Usage in template --}}
{{> button url="https://example.com" text="Click Me" }}
```

### Custom Helpers

```typescript
const mail = new Sendora({
provider: 'smtp',
smtp: { /* ... */ },
templates: {
helpers: {
uppercase: (str: string) => str.toUpperCase(),
formatDate: (date: Date) => date.toLocaleDateString(),
},
},
});
```

## Queue Support

Enable the built-in queue for background email processing:

```typescript
const mail = new Sendora({
provider: 'smtp',
smtp: { /* ... */ },
queue: true,
});

await mail.initialize();

await mail.send({
to: 'user@example.com',
subject: 'Welcome',
template: 'welcome',
data: { name: 'John' },
});

console.log(mail.getQueueSize());
```

## Logging

```typescript
const mail = new Sendora({
provider: 'smtp',
smtp: { /* ... */ },
logger: {
enabled: true,
level: 'info',
prettyPrint: true,
},
});
```

Log levels: `trace`, `debug`, `info`, `warn`, `error`, `fatal`

## Error Handling

```typescript
import { Sendora, TemplateNotFoundError, ProviderError } from 'sendora';

try {
await mail.send({
to: 'user@example.com',
template: 'nonexistent',
});
} catch (error) {
if (error instanceof TemplateNotFoundError) {
console.error('Template not found:', error.message);
} else if (error instanceof ProviderError) {
console.error('Provider error:', error.message);
}
}
```

## Type Safety

```typescript
interface WelcomeData {
name: string;
company: string;
}

await mail.send({
to: 'user@example.com',
template: 'welcome',
data: {
name: 'John',
company: 'Acme',
},
});
```

## API Reference

### `new Sendora(config)`

Creates a new Sendora instance.

**Parameters:**
- `config` - Configuration object

### `mail.send(options)`

Sends an email.

**Parameters:**
- `options` - Email options

**Returns:** `Promise`

### `mail.sendBulk(emails)`

Sends multiple emails.

**Parameters:**
- `emails` - Array of email options

**Returns:** `Promise`

### `mail.initialize()`

Initializes the template engine.

**Returns:** `Promise`

### `mail.close()`

Closes the provider connection.

**Returns:** `Promise`

### `mail.getQueueSize()`

Returns the number of queued emails.

**Returns:** `number`

### `mail.clearQueue()`

Clears all queued emails.

## License

MIT © [Nurul Islam Rimon](https://github.com/nurulislamrimon)

## Contributing

Contributions are welcome! This project is open source and we invite developers to contribute.

### Ways to Contribute

- **Bug Reports** - Open an issue with clear steps to reproduce
- **Feature Requests** - Suggest new features or improvements
- **Pull Requests** - Submit patches or new features
- **Documentation** - Improve docs, examples, or add translations
- **Testing** - Add more test cases

### Getting Started

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Development Setup

```bash
# Clone the repo
git clone https://github.com/nurulislamrimon/sendora.git
cd sendora

# Install dependencies
npm install

# Run tests
npm test

# Build
npm run build
```

We appreciate all contributions, no matter how small!