XYLEX Group

Email System Documentation

Email System Documentation

Note: This documentation has been moved to a more comprehensive location.

Please see the new documentation at /docs/email/resend/

Quick Links


Environment Variables (Quick Reference)

Add these to your .env file:

# Resend API Configuration
RESEND_API_KEY=re_xxxxxxxxxx
RESEND_FROM_EMAIL=noreply@suitsbooks.com
RESEND_FROM_NAME=SuitsBooks
RESEND_REPLY_TO=support@suitsbooks.com

# Optional: Enable test mode (logs instead of sending)
EMAIL_TEST_MODE=false
```typescript

## Usage

### Basic Email Sending

```tsx
import { useSendEmail } from "@/hooks/use-send-email";

function MyComponent() {
  const { sendEmail, isLoading, isError, error } = useSendEmail();

  const handleSendEmail = async () => {
    const result = await sendEmail({
      to: "recipient@example.com",
      subject: "Hello from SuitsBooks",
      template_id: "welcome",
      template_data: {
        USER_NAME: "John Doe",
        LOGIN_URL: "https://app.suitsbooks.com/login",
        SUPPORT_EMAIL: "support@suitsbooks.com",
      },
    });

    if (result.success) {
      console.log("Email sent:", result.email_id);
    }
  };

  return (
    <button onClick={handleSendEmail} disabled={isLoading}>
      Send Email
    </button>
  );
}
```typescript

### With Notifications

```tsx
import { useSendEmailWithNotification } from "@/hooks/use-send-email-with-notification";

function MyComponent() {
  const { sendEmail, isLoading } = useSendEmailWithNotification({
    showSuccessNotification: true,
    showErrorNotification: true,
    messages: {
      sendSuccess: "Invoice sent successfully!",
      sendError: "Failed to send invoice",
    },
  });

  // ... same usage as above
}
```typescript

### Custom Configuration

```tsx
const { sendEmail } = useSendEmail({
  // Rate limiting
  enableRateLimiting: true,
  maxEmailsPerMinute: 5,
  maxEmailsPerHour: 50,
  maxEmailsPerDay: 200,

  // Duplicate detection
  enableDuplicateDetection: true,
  duplicateWindowSeconds: 120, // 2 minutes

  // Domain restrictions
  blockedRecipientDomains: ["tempmail.com", "mailinator.com"],
  allowedRecipientDomains: [], // Empty = all allowed

  // Bulk settings
  requireBulkConfirmation: true,
  bulkThreshold: 10,

  // Callbacks
  onSuccess: (response) => console.log("Sent:", response),
  onError: (error) => console.error("Error:", error),
  onRateLimited: () => console.warn("Rate limited!"),
});
```typescript

### Bulk Email Sending

```tsx
const { sendBulkEmails } = useSendEmail();

const emails = [
  {
    id: "email-1",
    to: "user1@example.com",
    subject: "Invoice #001",
    template_id: "invoice",
    template_data: { INVOICE_NUMBER: "001", AMOUNT: "€100" },
  },
  {
    id: "email-2",
    to: "user2@example.com",
    subject: "Invoice #002",
    template_id: "invoice",
    template_data: { INVOICE_NUMBER: "002", AMOUNT: "€200" },
  },
];

const result = await sendBulkEmails(emails, {
  skipConfirmation: true, // Skip confirmation for bulk > 10
  batchDelay: 1000, // 1 second between batches
});

console.log(`Sent: ${result.sent}/${result.total}`);
```typescript

### Check Rate Limit Status

```tsx
const { getRateLimitStatus, canSendEmail } = useSendEmail();

// Check if we can send
const { canSend, reason } = canSendEmail("user@example.com", "Test Subject");
if (!canSend) {
  console.log("Cannot send:", reason);
}

// Get detailed status
const status = getRateLimitStatus();
console.log(`Remaining today: ${status.remainingDay}`);
```typescript

## Available Templates

| Template ID | Description | Required Variables |
|------------|-------------|-------------------|
| `invoice` | Invoice notification | AUTHOR_NAME, AMOUNT_TOTAL, DUE_DATE, RECIPIENT_NAME, INVOICE_URL, INVOICE_NUMBER |
| `company-invite` | Team invitation | TEAM_NAME, ORGANIZATION_NAME, RECIPIENT_NAME, SENDER_NAME, SENDER_EMAIL, INVITE_LINK |
| `quote-recipient` | Quote for customer | Similar to invoice |
| `quote-author` | Quote viewed notification | - |
| `batch-invoice` | Multiple invoices | - |
| `password-reset` | Password reset | USER_NAME, RESET_URL, EXPIRY_TIME, REQUEST_IP, REQUEST_LOCATION |
| `welcome` | New user welcome | USER_NAME, LOGIN_URL, SUPPORT_EMAIL |
| `verification` | Email verification | USER_NAME, VERIFICATION_URL, VERIFICATION_CODE, EXPIRY_TIME |
| `payment-received` | Payment confirmation | RECIPIENT_NAME, AUTHOR_NAME, AMOUNT_PAID, PAYMENT_DATE, PAYMENT_METHOD, RECEIPT_URL |
| `payment-reminder` | Payment reminder | RECIPIENT_NAME, AUTHOR_NAME, INVOICE_NUMBER, AMOUNT_DUE, DUE_DATE, DAYS_OVERDUE, INVOICE_URL |
| `custom` | Custom HTML | html_body required |

## API Endpoints

### POST /api/email/send

Send a single email.

```json
{
  "to": "user@example.com",
  "subject": "Hello",
  "template_id": "welcome",
  "template_data": {
    "USER_NAME": "John"
  }
}
```typescript

### POST /api/email/bulk

Send multiple emails.

```json
{
  "emails": [
    {
      "id": "1",
      "to": "user1@example.com",
      "subject": "Hello 1",
      "template_id": "welcome",
      "template_data": {}
    }
  ],
  "batchDelay": 1000
}
```typescript

### GET /api/email/status/[email_id]

Get email status.

### GET /api/email/track?view_key=xxx

Track email opens (returns tracking pixel).

## Database Schema

Emails are stored in the `emails` table with fields including:

- `email_id` - Unique identifier
- `status` - pending, sent, delivered, opened, failed, etc.
- `template_id` - Template used
- `recipient_email` - Recipient address
- `opened` - Whether email was opened
- `delivered` - Whether email was delivered
- `view_key` - Unique key for tracking
- `resource_type_ref` / `resource_id_ref` - Link to other resources (e.g., invoice_id)

## Adding New Templates

1. Create a new file in `emails/templates/`:

```tsx
// emails/templates/my-template.tsx
import { Html, Head, Preview, Body, ... } from "@react-email/components";

export default function MyTemplate() {
  return (
    <Html>
      <Head />
      <Preview>Preview text</Preview>
      <Body>
        Hello {"{{USER_NAME}}"}!
      </Body>
    </Html>
  );
}
```typescript

2. Add to `emails/templates/index.ts`:

```tsx
import MyTemplate from "./my-template";

export const EMAIL_TEMPLATES = {
  // ... existing templates
  "my-template": MyTemplate,
};
```typescript

3. Add to types in `lib/email/types.ts`:

```tsx
export type EmailTemplateId =
  | // ... existing
  | "my-template";
```typescript

4. Add config in `lib/email/config.ts`:

```tsx
export const TEMPLATE_CONFIG = {
  // ... existing
  "my-template": {
    defaultSubject: "My Template Subject",
    requiresAuth: true,
    category: "notification",
  },
};

Preview Templates

Run the React Email dev server:

pnpm email

This opens a preview at http://localhost:3040 where you can view and test templates.