# @scwar/nestjs-mailjet-sdk

A comprehensive NestJS module for integrating with Mailjet API v3.1. This package provides a complete wrapper around Mailjet's email sending capabilities with robust error handling, retries, and TypeScript support.

## Features

- 🚀 **Complete API Coverage**: Mailjet API v3.1 endpoints implemented
- 🔄 **Automatic Retries**: Built-in retry mechanism with exponential backoff
- 🛡️ **Robust Error Handling**: Comprehensive error handling with detailed error messages
- 📝 **TypeScript Support**: Full type definitions for all API requests and responses
- 🧪 **Comprehensive Testing**: Extensive test coverage for all endpoints
- ⚡ **Performance**: Uses native fetch API for optimal performance
- 🔧 **Configurable**: Easy configuration through NestJS module options

## Installation

```bash
npm install @scwar/nestjs-mailjet-sdk
```

## Quick Start

### 1. Import the module

```typescript
import { MailjetModule } from '@scwar/nestjs-mailjet-sdk';

@Module({
  imports: [
    MailjetModule.forRoot({
      apiKey: 'your-mailjet-api-key',
      apiSecret: 'your-mailjet-api-secret',
      baseUrl: 'https://api.mailjet.com/v3.1',
      timeout: 30000,
      retries: 3,
    }),
  ],
})
export class AppModule {}
```

### 2. Inject and use the service

```typescript
import { MailjetService } from '@scwar/nestjs-mailjet-sdk';

@Injectable()
export class EmailService {
  constructor(private readonly mailjetService: MailjetService) {}

  async sendWelcomeEmail(userEmail: string, userName: string) {
    return this.mailjetService.send.sendEmail({
      From: {
        Email: 'noreply@example.com',
        Name: 'Example App',
      },
      To: [
        {
          Email: userEmail,
          Name: userName,
        },
      ],
      Subject: 'Welcome to Example App',
      HTMLPart: `
        <h1>Welcome ${userName}!</h1>
        <p>Thank you for joining Example App.</p>
      `,
      TextPart: `Welcome ${userName}! Thank you for joining Example App.`,
    });
  }
}
```

## Configuration Options

```typescript
interface MailjetModuleOptions {
  apiKey: string;
  apiSecret: string;
  baseUrl?: string;        // Default: 'https://api.mailjet.com/v3.1'
  timeout?: number;        // Default: 30000
  retries?: number;        // Default: 3
  retryDelay?: number;     // Default: 1000
  maxRetryDelay?: number;  // Default: 10000
}
```

### Async Configuration

```typescript
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MailjetModule } from '@scwar/nestjs-mailjet-sdk';

@Module({
  imports: [
    ConfigModule.forRoot(),
    MailjetModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        apiKey: configService.get<string>('MAILJET_API_KEY'),
        apiSecret: configService.get<string>('MAILJET_API_SECRET'),
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}
```

## Available Services

### Send Service

Send transactional and bulk emails:

```typescript
// Send a single email
await mailjetService.send.sendEmail({
  From: { Email: 'sender@example.com', Name: 'Sender' },
  To: [{ Email: 'recipient@example.com', Name: 'Recipient' }],
  Subject: 'Hello',
  HTMLPart: '<h1>Hello World</h1>',
  TextPart: 'Hello World',
});

// Send using template
await mailjetService.send.sendTemplate(
  templateId,
  { Email: 'sender@example.com' },
  [{ Email: 'recipient@example.com' }],
  { name: 'John' },
);

// Send bulk emails
await mailjetService.send.sendBulk([
  { From: {...}, To: [...], Subject: '...', HTMLPart: '...' },
  { From: {...}, To: [...], Subject: '...', HTMLPart: '...' },
]);
```

### Contact Service

Manage contacts and contact lists:

```typescript
// Create contact
await mailjetService.contact.create({
  Email: 'user@example.com',
  Name: 'John Doe',
  IsExcludedFromCampaigns: false,
});

// Get contact
await mailjetService.contact.getByEmail('user@example.com');

// List contacts
await mailjetService.contact.list({
  Limit: 10,
  Offset: 0,
});

// Update contact
await mailjetService.contact.updateByEmail('user@example.com', {
  Name: 'Jane Doe',
});

// Manage contact lists
await mailjetService.contact.manageContactList(contactId, {
  ContactsLists: [
    { ListID: 123, Action: 'addnoforce' },
  ],
});
```

### Template Service

Manage email templates:

```typescript
// Create template
await mailjetService.template.create({
  Name: 'Welcome Template',
  Author: 'John Doe',
});

// Get template
await mailjetService.template.get(templateId);

// List templates
await mailjetService.template.list({
  Limit: 10,
  Offset: 0,
});

// Update template
await mailjetService.template.update(templateId, {
  Name: 'Updated Template Name',
});

// Get template content
await mailjetService.template.getContent(templateId);

// Set template content
await mailjetService.template.setContent(templateId, {
  'Html-part': '<h1>Hello</h1>',
  'Text-part': 'Hello',
});
```

### Statistics Service

Get email and campaign statistics:

```typescript
// Get email statistics
await mailjetService.statistics.getEmailStatistics({
  FromTS: '2024-01-01T00:00:00Z',
  ToTS: '2024-01-31T23:59:59Z',
});

// Get campaign statistics
await mailjetService.statistics.getCampaignStatistics({
  CampaignID: 123,
});

// Get message statistics
await mailjetService.statistics.getMessageStatistics(messageId);

// Get contact statistics
await mailjetService.statistics.getContactStatistics(contactId);
```

## Error Handling

The package provides comprehensive error handling with detailed error messages:

```typescript
import { MailjetError } from '@scwar/nestjs-mailjet-sdk';

try {
  const result = await this.mailjetService.send.sendEmail(data);
} catch (error) {
  if (error instanceof MailjetError) {
    console.log('Mailjet Error:', error.message);
    console.log('Error Code:', error.code);
    console.log('HTTP Status:', error.status);
    console.log('Error Data:', error.data);
  }
}
```

## Retry Mechanism

Automatic retries with exponential backoff for failed requests:

```typescript
// Configure retries in module options
MailjetModule.forRoot({
  apiKey: 'your-key',
  apiSecret: 'your-secret',
  retries: 3,           // Number of retry attempts
  retryDelay: 1000,     // Initial delay in ms
  maxRetryDelay: 10000, // Maximum delay in ms
})
```

## Testing

```bash
# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:cov
```

## Version Management & Releases

This package includes an automated version bumping system that follows semantic versioning and conventional commits.

### Automatic Version Bumping

The system automatically determines the appropriate version bump based on your commits:

```bash
# Automatically determine and bump version
npm run version:auto

# Manual version bumps
npm run version:patch  # 1.0.0 → 1.0.1
npm run version:minor  # 1.0.0 → 1.1.0
npm run version:major  # 1.0.0 → 2.0.0
```

### Conventional Commits

All commits must follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:

```bash
# Feature commits (minor version bump)
git commit -m "feat: add new email template support"

# Bug fix commits (patch version bump)
git commit -m "fix: resolve authentication issue"

# Breaking change commits (major version bump)
git commit -m "feat!: breaking change in API"

# Documentation commits (no version bump)
git commit -m "docs: update README with examples"
```

### Release Process

#### Automated Release (Recommended)
```bash
# Complete release process with automatic version bump
npm run release:auto

# Manual release with specific version bump
npm run release:patch
npm run release:minor
npm run release:major
```

See [VERSION_BUMPING_GUIDE.md](./VERSION_BUMPING_GUIDE.md) for detailed information.

## GitHub Actions

The package includes GitHub Actions workflows for:
- **CI**: Automated testing, linting, and quality checks
- **Release**: Automated version bumping, changelog updates, and npm publishing

## Contributing

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

**Important**: All commits must follow the conventional commit format to ensure proper version bumping.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Support

For support, please open an issue on GitHub or contact the maintainers.

## Changelog

See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.

## References

- [Mailjet API Documentation](https://dev.mailjet.com/email/guides/send-api-v31/)
- [NestJS Documentation](https://docs.nestjs.com/)
- [Conventional Commits](https://www.conventionalcommits.org/)

