# 邮件服务 (/docs/infrastructure/services/email)

Better Auth Infrastructure 提供托管式事务邮件服务，并为常见身份验证流程提供预构建模板。无需管理邮件基础设施，即可发送验证邮件、密码重置邮件、邀请邮件等。



## 概述 [#概述]

邮件服务提供：

* 预构建的专业设计邮件模板
* 多供应商支持（AWS SES、SendGrid、Resend）
* 类型安全的模板变量
* 无需管理的基础设施
* 投递优化

## 安装 [#安装]

邮件服务包含在 `@better-auth/infra` 包中：

```ts
import { sendEmail, createEmailSender } from "@better-auth/infra";
```

## 快速开始 [#快速开始]

### 发送单个邮件 [#发送单个邮件]

```ts
import { sendEmail } from "@better-auth/infra";

await sendEmail({
  template: "verify-email",
  to: "user@example.com",
  variables: {
    verificationUrl: "https://yourapp.com/verify?token=abc123",
    userEmail: "user@example.com",
    userName: "John",
    appName: "Your App",
  },
});
```

### 创建可复用的发送器 [#创建可复用的发送器]

```ts
import { createEmailSender } from "@better-auth/infra";

const emailSender = createEmailSender({
  apiKey: process.env.BETTER_AUTH_API_KEY,
  apiUrl: process.env.BETTER_AUTH_API_URL,
});

// 发送多封邮件
await emailSender.send({
  template: "reset-password",
  to: "user@example.com",
  variables: {
    resetLink: "https://yourapp.com/reset?token=xyz",
    userEmail: "user@example.com",
  },
});
```

## 可用模板 [#可用模板]

### verify-email [#verify-email]

向新用户发送邮件验证链接。

```ts
await sendEmail({
  template: "verify-email",
  to: "user@example.com",
  variables: {
    verificationUrl: "https://yourapp.com/verify?token=abc",
    userEmail: "user@example.com",
    verificationCode: "123456",        // 可选：基于验证码的验证
    userName: "John",                   // 可选
    appName: "Your App",               // 可选
    expirationMinutes: "60",           // 可选
  },
});
```

### reset-password [#reset-password]

发送密码重置链接。

```ts
await sendEmail({
  template: "reset-password",
  to: "user@example.com",
  variables: {
    resetLink: "https://yourapp.com/reset?token=xyz",
    userEmail: "user@example.com",
    userName: "John",                   // 可选
    appName: "Your App",               // 可选
    expirationMinutes: "60",           // 可选
  },
});
```

### change-email [#change-email]

确认邮箱地址变更请求。

```ts
await sendEmail({
  template: "change-email",
  to: "newemail@example.com",
  variables: {
    confirmationLink: "https://yourapp.com/confirm-email?token=abc",
    newEmail: "newemail@example.com",
    currentEmail: "oldemail@example.com",
    userName: "John",                   // 可选
    appName: "Your App",               // 可选
    expirationMinutes: "60",           // 可选
  },
});
```

### sign-in-otp [#sign-in-otp]

发送一次性密码（OTP）用于无密码登录。

```ts
await sendEmail({
  template: "sign-in-otp",
  to: "user@example.com",
  variables: {
    otpCode: "123456",
    userEmail: "user@example.com",
    appName: "Your App",               // 可选
    expirationMinutes: "10",           // 可选
  },
});
```

### verify-email-otp [#verify-email-otp]

发送邮件验证用的 OTP 码。

```ts
await sendEmail({
  template: "verify-email-otp",
  to: "user@example.com",
  variables: {
    otpCode: "123456",
    userEmail: "user@example.com",
    appName: "Your App",               // 可选
    expirationMinutes: "10",           // 可选
  },
});
```

### reset-password-otp [#reset-password-otp]

发送密码重置用的 OTP 码。

```ts
await sendEmail({
  template: "reset-password-otp",
  to: "user@example.com",
  variables: {
    otpCode: "123456",
    userEmail: "user@example.com",
    appName: "Your App",               // 可选
    expirationMinutes: "10",           // 可选
  },
});
```

### magic-link [#magic-link]

发送无密码认证用的魔法链接。

```ts
await sendEmail({
  template: "magic-link",
  to: "user@example.com",
  variables: {
    magicLink: "https://yourapp.com/auth/magic?token=abc",
    userEmail: "user@example.com",
    appName: "Your App",               // 可选
    expirationMinutes: "15",           // 可选
  },
});
```

### two-factor [#two-factor]

发送两步验证代码。

```ts
await sendEmail({
  template: "two-factor",
  to: "user@example.com",
  variables: {
    otpCode: "123456",
    userEmail: "user@example.com",
    userName: "John",                   // 可选
    appName: "Your App",               // 可选
    expirationMinutes: "5",            // 可选
  },
});
```

### invitation [#invitation]

发送组织邀请。

```ts
await sendEmail({
  template: "invitation",
  to: "newmember@example.com",
  variables: {
    inviteLink: "https://yourapp.com/invite?token=abc",
    inviterName: "John Smith",
    inviterEmail: "john@company.com",
    organizationName: "Acme Corp",
    role: "Member",
    appName: "Your App",               // 可选
    expirationDays: "7",               // 可选
  },
});
```

### application-invite [#application-invite]

发送应用级邀请（邀请用户加入平台）。

```ts
await sendEmail({
  template: "application-invite",
  to: "newuser@example.com",
  variables: {
    inviteLink: "https://yourapp.com/join?token=abc",
    inviterName: "John Smith",
    inviterEmail: "john@company.com",
    inviteeEmail: "newuser@example.com",
    appName: "Your App",               // 可选
    expirationDays: "7",               // 可选
  },
});
```

### delete-account [#delete-account]

发送账户删除确认。

```ts
await sendEmail({
  template: "delete-account",
  to: "user@example.com",
  variables: {
    deletionLink: "https://yourapp.com/confirm-delete?token=abc",
    userEmail: "user@example.com",
    userName: "John",                   // 可选
    appName: "Your App",               // 可选
    expirationMinutes: "60",           // 可选
  },
});
```

### stale-account-user [#stale-account-user]

通知用户其闲置账户被访问。

```ts
await sendEmail({
  template: "stale-account-user",
  to: "user@example.com",
  variables: {
    userEmail: "user@example.com",
    daysSinceLastActive: "90",
    loginTime: "2026年2月20日 15:45 UTC",
    userName: "John",                   // 可选
    appName: "Your App",               // 可选
    loginLocation: "纽约，美国",         // 可选
    loginDevice: "Windows 下的 Chrome",   // 可选
    loginIp: "192.168.1.1",            // 可选
  },
});
```

### stale-account-admin [#stale-account-admin]

通知管理员闲置账户重新激活。

```ts
await sendEmail({
  template: "stale-account-admin",
  to: "admin@yourapp.com",
  variables: {
    userEmail: "user@example.com",
    userId: "user_123",
    adminEmail: "admin@yourapp.com",
    daysSinceLastActive: "90",
    loginTime: "2026年2月20日 15:45 UTC",
    userName: "John",                   // 可选
    appName: "Your App",               // 可选
    loginLocation: "纽约，美国",         // 可选
    loginDevice: "Windows 下的 Chrome",   // 可选
    loginIp: "192.168.1.1",            // 可选
  },
});
```

## 配置 [#配置]

### EmailConfig [#emailconfig]

```ts
interface EmailConfig {
  apiKey?: string;   // 你的 Better Auth Infrastructure API 密钥
  apiUrl?: string;   // 自定义 API URL（可选）
}
```

### 环境变量 [#环境变量]

邮件服务会自动读取以下环境变量：

```dotenv
BETTER_AUTH_API_KEY=your_api_key_here
BETTER_AUTH_API_URL=https://api.betterauth.com  # 可选
```

## 返回格式 [#返回格式]

### SendEmailResult [#sendemailresult]

```ts
interface SendEmailResult {
  success: boolean;
  messageId?: string;  // 邮件提供商的消息 ID
  error?: string;      // 失败时的错误信息
}
```

### 使用示例 [#使用示例]

```ts
const result = await sendEmail({
  template: "verify-email",
  to: "user@example.com",
  variables: {
    verificationUrl: "https://yourapp.com/verify?token=abc",
    userEmail: "user@example.com",
  },
});

if (result.success) {
  console.log("邮件已发送:", result.messageId);
} else {
  console.error("邮件发送失败:", result.error);
}
```

## 套餐要求 [#套餐要求]

| 功能   | Starter | Pro | Business | Enterprise |
| ---- | ------- | --- | -------- | ---------- |
| 事务邮件 | -       | Yes | Yes      | Yes        |

## 与 Better Auth 集成 [#与-better-auth-集成]

## 与 Better Auth 集成 [#与-better-auth-集成-1]

邮件服务与 Better Auth 的身份验证流程无缝集成。以下是一个完整示例：

```ts title="auth.ts"
import { betterAuth } from "better-auth";
import { organization } from "better-auth/plugins";
import { sendEmail } from "@better-auth/infra";

export const auth = betterAuth({
  emailAndPassword: {
    enabled: true,
    async sendResetPassword({ user, url }) {
      await sendEmail({
        template: "reset-password",
        to: user.email,
        variables: {
          resetLink: url,
          userEmail: user.email,
          userName: user.name,
          appName: "Your App",
        },
      });
    },
  },
  emailVerification: {
    sendOnSignUp: true,
    async sendVerificationEmail({ user, url }) {
      await sendEmail({
        template: "verify-email",
        to: user.email,
        variables: {
          verificationUrl: url,
          userEmail: user.email,
          userName: user.name,
          appName: "Your App",
        },
      });
    },
  },
  plugins: [
    organization({
      async sendInvitationEmail(data) {
        const inviteLink = `https://yourapp.com/accept-invitation/${data.id}`;
        await sendEmail({
          template: "invitation",
          to: data.email,
          variables: {
            inviteLink,
            inviterName: data.inviter.user.name,
            inviterEmail: data.inviter.user.email,
            organizationName: data.organization.name,
            role: data.role,
            appName: "Your App",
          },
        });
      },
    }),
  ],
});
```

<Callout type="warn">
  在生产环境中避免等待邮件发送完成以防止时间攻击。在无服务器平台上，请使用 `waitUntil` 或类似方式确保邮件发送完成，同时不阻塞响应。
</Callout>

