# Email Message

> Email message with recipients, subject, body (text/HTML), and attachments.

- Name: `email-message`
- Categories: common
- Detail page: https://open-types.dev/types/email-message

## Install

```bash
# Types only
npx shadcn add @open-types/email-message

# Types + Zod v4 validators
npx shadcn add @open-types/email-message-zod

# Types + real-world examples
npx shadcn add @open-types/email-message-examples
```

## Types

```typescript
export interface EmailAttachment {
  filename: string;
  content_type: string;
  size: number;
}

export interface EmailMessage {
  from: string;
  to: string[];
  cc?: string[];
  bcc?: string[];
  subject: string;
  text?: string;
  html?: string;
  reply_to?: string;
  attachments?: EmailAttachment[];
}
```

## Zod validator

```typescript
import * as z from "zod";
import type { EmailAttachment, EmailMessage } from "../types/email-message";

export const emailAttachmentSchema = z.object({
  filename: z.string().min(1, { error: "Attachment filename is required" }),
  content_type: z.string().min(1, { error: "Attachment content type is required" }),
  size: z.number().int({ error: "Attachment size must be a whole number" }).min(0, {
    error: "Attachment size cannot be negative",
  }),
}) satisfies z.ZodType<EmailAttachment>;

export const emailMessageSchema = z.object({
  from: z.string().email({ error: "From must be a valid email address" }),
  to: z
    .array(z.string().email({ error: "Recipient must be a valid email address" }))
    .min(1, { error: "At least one recipient is required" }),
  cc: z.array(z.string().email({ error: "CC recipient must be a valid email address" })).optional(),
  bcc: z
    .array(z.string().email({ error: "BCC recipient must be a valid email address" }))
    .optional(),
  subject: z.string().min(1, { error: "Subject is required" }),
  text: z.string().optional(),
  html: z.string().optional(),
  reply_to: z.string().email({ error: "Reply-to must be a valid email address" }).optional(),
  attachments: z.array(emailAttachmentSchema).optional(),
}) satisfies z.ZodType<EmailMessage>;

export type { EmailAttachment, EmailMessage } from "../types/email-message";
```

## Examples

```typescript
// Source: hand-crafted
import type {
  EmailAttachment,
  EmailMessage,
} from "../types/email-message";

const receiptPdf = {
  filename: "receipt.pdf",
  content_type: "application/pdf",
  size: 24_500,
} as const satisfies EmailAttachment;

export const emailAttachmentExamples = {
  pdf: receiptPdf,
  image: {
    filename: "screenshot.png",
    content_type: "image/png",
    size: 102_400,
  } satisfies EmailAttachment,
  zip: {
    filename: "export.zip",
    content_type: "application/zip",
    size: 5_242_880,
  } satisfies EmailAttachment,
} as const;

const transactional = {
  from: "no-reply@example.com",
  to: ["customer@example.com"],
  subject: "Your order has shipped",
  text: "Your order #1001 is on its way.",
  html: "<p>Your order <strong>#1001</strong> is on its way.</p>",
  reply_to: "support@example.com",
  attachments: [receiptPdf],
} as const satisfies EmailMessage;

export const emailMessageExamples = {
  transactional,
  plainText: {
    from: "alerts@example.com",
    to: ["oncall@example.com"],
    subject: "Production alert",
    text: "Service X is degraded.",
  } satisfies EmailMessage,
  broadcastWithCcBcc: {
    from: "newsletter@example.com",
    to: ["customer-a@example.com", "customer-b@example.com"],
    cc: ["editor@example.com"],
    bcc: ["archive@example.com"],
    subject: "Weekly update",
    html: "<h1>Weekly update</h1><p>Highlights below.</p>",
  } satisfies EmailMessage,
  htmlOnly: {
    from: "marketing@example.com",
    to: ["lead@example.com"],
    subject: "Special offer",
    html: "<p>Save 20% this week.</p>",
  } satisfies EmailMessage,
} as const;
```
