跳轉到主要內容

概述

Resend 是專為開發人員設計的現代電子郵件 API。它提供了一種簡單、可靠的方法來從 Superun 應用程序發送交易和營銷電子郵件。使用 Resend,您只需幾行代碼即可發送電子郵件。

什麼是 Resend

Resend 提供開發人員友好的電子郵件服務:
  • 簡單的 API: 乾淨、RESTful API,易於集成
  • 高送達率: 針對收件箱放置進行了優化
  • React Email: 對基於 React 的電子郵件模板的內置支持
  • Webhooks: 實時交付和參與跟踪
  • 分析: 詳細的電子郵件績效指標
  • 模板: 適用於常見用例的預構建電子郵件模板

主要優點

  • 開發者體驗: 由開發者設計,為開發者服務
  • 高送達率: 比傳統 SMTP 更好的收件箱放置
  • React 集成: 對 React 電子郵件組件的本機支持
  • 實時跟踪: 用於交付和參與活動的 Webhooks
  • 可擴展: 處理大量電子郵件發送
  • 價格實惠: 有競爭力的價格和慷慨的免費套餐

入門

1. 創建一個 Resend 帳戶

  1. 前往 Resend.com 並註冊
  2. 驗證您的電子郵件地址
  3. 完成帳戶設置過程

2. 獲取您的 API 密鑰

  1. 前往 Resend 儀表板中的 API Keys
  2. 點擊創建 API 密鑰
  3. 為其命名(例如,“Superun App”)
  4. 複製 API 密鑰(以”re_“開頭)
  5. 確保其安全,切勿在客戶端代碼中公開它

3. 在 Superun 中配置 Resend

在您的 Superun 項目中:
  1. 轉到 設置 → 集成
  2. 找到 Resend 並單擊 連接
  3. 輸入您的 API 密鑰
  4. 單擊“保存
Superun 將自動配置您的項目以使用 Resend。

基本電子郵件發送

安裝Resend SDK

Superun 自動包含 Resend SDK,但您也可以手動安裝:
npm install Resend

發送一封簡單的電子郵件

import { Resend } from 'Resend';

const Resend = new Resend(process.env.RESEND_API_KEY);

// Send a simple email
const sendEmail = async (to, subject, text) => {
  try {
    const { data, error } = await Resend.emails.send({
      from: '[email protected]',
      to: [to],
      subject: subject,
      text: text,
    });

    if (error) {
      console.error('Error sending email:', error);
      return { success: false, error };
    }

    console.log('Email sent successfully:', data);
    return { success: true, data };
  } catch (error) {
    console.error('Error sending email:', error);
    return { success: false, error };
  }
};

發送 HTML 電子郵件

const sendHtmlEmail = async (to, subject, html) => {
  try {
    const { data, error } = await Resend.emails.send({
      from: '[email protected]',
      to: [to],
      subject: subject,
      html: html,
    });

    if (error) {
      console.error('Error sending email:', error);
      return { success: false, error };
    }

    return { success: true, data };
  } catch (error) {
    console.error('Error sending email:', error);
    return { success: false, error };
  }
};

React 電子郵件集成

安裝 React 電子郵件

npm install @react-email/components

創建電子郵件模板

// components/emails/WelcomeEmail.jsx
import {
  Html,
  Head,
  Body,
  Container,
  Section,
  Text,
  Button,
} from '@react-email/components';

export const WelcomeEmail = ({ name, verificationLink }) => {
  return (
    <Html>
      <Head />
      <Body style={main}>
        <Container style={container}>
          <Section style={box}>
            <Text style={heading}>Welcome to Superun!</Text>
            <Text style={paragraph}>
              Hi {name}, welcome to our platform. We're excited to have you on board!
            </Text>
            <Text style={paragraph}>
              Please verify your email address by clicking the button below:
            </Text>
            <Button style={button} href={verificationLink}>
              Verify Email
            </Button>
            <Text style={paragraph}>
              If you didn't create an account, you can safely ignore this email.
            </Text>
          </Section>
        </Container>
      </Body>
    </Html>
  );
};

const main = {
  backgroundColor: '#f6f9fc',
  fontFamily: '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
};

const container = {
  backgroundColor: '#ffffff',
  margin: '0 auto',
  padding: '20px 0 48px',
  marginBottom: '64px',
};

const box = {
  padding: '0 48px',
};

const heading = {
  fontSize: '32px',
  lineHeight: '1.3',
  fontWeight: '700',
  color: '#484848',
  margin: '0 0 20px',
};

const paragraph = {
  fontSize: '16px',
  lineHeight: '1.4',
  color: '#3c4149',
  margin: '0 0 16px',
};

const button = {
  backgroundColor: '#5F51E8',
  borderRadius: '3px',
  color: '#fff',
  fontSize: '16px',
  textDecoration: 'none',
  textAlign: 'center',
  display: 'block',
  padding: '12px 20px',
  margin: '20px 0',
};

發送反應電子郵件

import { render } from '@react-email/render';
import { WelcomeEmail } from './components/emails/WelcomeEmail';

const sendWelcomeEmail = async (to, name, verificationLink) => {
  try {
    const emailHtml = render(WelcomeEmail({ name, verificationLink }));
    
    const { data, error } = await Resend.emails.send({
      from: '[email protected]',
      to: [to],
      subject: 'Welcome to Superun!',
      html: emailHtml,
    });

    if (error) {
      console.error('Error sending email:', error);
      return { success: false, error };
    }

    return { success: true, data };
  } catch (error) {
    console.error('Error sending email:', error);
    return { success: false, error };
  }
};

電子郵件模板

密碼重置電子郵件

// components/emails/PasswordResetEmail.jsx
import {
  Html,
  Head,
  Body,
  Container,
  Section,
  Text,
  Button,
} from '@react-email/components';

export const PasswordResetEmail = ({ name, resetLink }) => {
  return (
    <Html>
      <Head />
      <Body style={main}>
        <Container style={container}>
          <Section style={box}>
            <Text style={heading}>Password Reset Request</Text>
            <Text style={paragraph}>
              Hi {name}, we received a request to reset your password.
            </Text>
            <Text style={paragraph}>
              Click the button below to reset your password:
            </Text>
            <Button style={button} href={resetLink}>
              Reset Password
            </Button>
            <Text style={paragraph}>
              This link will expire in 1 hour. If you didn't request this, you can safely ignore this email.
            </Text>
          </Section>
        </Container>
      </Body>
    </Html>
  );
};

通知電子郵件

// components/emails/NotificationEmail.jsx
import {
  Html,
  Head,
  Body,
  Container,
  Section,
  Text,
  Button,
} from '@react-email/components';

export const NotificationEmail = ({ name, title, message, actionLink, actionText }) => {
  return (
    <Html>
      <Head />
      <Body style={main}>
        <Container style={container}>
          <Section style={box}>
            <Text style={heading}>{title}</Text>
            <Text style={paragraph}>
              Hi {name},
            </Text>
            <Text style={paragraph}>
              {message}
            </Text>
            {actionLink && actionText && (
              <Button style={button} href={actionLink}>
                {actionText}
              </Button>
            )}
          </Section>
        </Container>
      </Body>
    </Html>
  );
};

高級功能

發送給多個收件人

const sendBulkEmail = async (recipients, subject, html) => {
  try {
    const { data, error } = await Resend.emails.send({
      from: '[email protected]',
      to: recipients, // Array of email addresses
      subject: subject,
      html: html,
    });

    if (error) {
      console.error('Error sending email:', error);
      return { success: false, error };
    }

    return { success: true, data };
  } catch (error) {
    console.error('Error sending email:', error);
    return { success: false, error };
  }
};

帶附件發送

const sendEmailWithAttachment = async (to, subject, html, attachment) => {
  try {
    const { data, error } = await Resend.emails.send({
      from: '[email protected]',
      to: [to],
      subject: subject,
      html: html,
      attachments: [
        {
          filename: attachment.name,
          content: attachment.content, // Base64 encoded content
        },
      ],
    });

    if (error) {
      console.error('Error sending email:', error);
      return { success: false, error };
    }

    return { success: true, data };
  } catch (error) {
    console.error('Error sending email:', error);
    return { success: false, error };
  }
};

使用自定義標頭髮送

const sendEmailWithHeaders = async (to, subject, html) => {
  try {
    const { data, error } = await Resend.emails.send({
      from: '[email protected]',
      to: [to],
      subject: subject,
      html: html,
      headers: {
        'X-Custom-Header': 'Custom Value',
        'X-Priority': '1', // High priority
      },
    });

    if (error) {
      console.error('Error sending email:', error);
      return { success: false, error };
    }

    return { success: true, data };
  } catch (error) {
    console.error('Error sending email:', error);
    return { success: false, error };
  }
};

網絡鉤子

設置 Webhooks

  1. 轉到 Resend 儀表板中的 Webhooks
  2. 單擊“添加 Webhook
  3. 輸入您的 Webhook URL(例如“https://yourapp.com/api/webhooks/Resend”)
  4. 選擇您要監聽的事件
  5. 複製 webhook 密鑰

處理 Webhooks

// webhook handler
import crypto from 'crypto';

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).end();
  }

  const signature = req.headers['Resend-signature'];
  const webhookSecret = process.env.RESEND_WEBHOOK_SECRET;

  // Verify webhook signature
  const expectedSignature = crypto
    .createHmac('sha256', webhookSecret)
    .update(JSON.stringify(req.body))
    .digest('hex');

  if (signature !== expectedSignature) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const { type, data } = req.body;

  // Handle different webhook events
  switch (type) {
    case 'email.sent':
      console.log('Email sent:', data.email.id);
      // Update database, log activity, etc.
      break;

    case 'email.delivered':
      console.log('Email delivered:', data.email.id);
      // Update delivery status
      break;

    case 'email.bounced':
      console.log('Email bounced:', data.email.id);
      // Handle bounce, update user status
      break;

    case 'email.complained':
      console.log('Email complained:', data.email.id);
      // Handle complaint, update user preferences
      break;

    case 'email.opened':
      console.log('Email opened:', data.email.id);
      // Track engagement, update analytics
      break;

    case 'email.clicked':
      console.log('Email clicked:', data.email.id);
      // Track click-through, update analytics
      break;

    default:
      console.log(`Unhandled webhook event: ${type}`);
  }

  res.json({ received: true });
}

電子郵件分析

跟踪電子郵件打開情況

// Add tracking pixel to email template
const TrackingPixel = ({ emailId }) => {
  return (
    <img
      src={`https://yourapp.com/api/track-email-open?emailId=${emailId}`}
      width="1"
      height="1"
      style={{ display: 'none' }}
      alt=""
    />
  );
};

跟踪電子郵件點擊

// Wrap links with tracking
const TrackedLink = ({ href, emailId, linkId }) => {
  const trackedHref = `https://yourapp.com/api/track-email-click?emailId=${emailId}&linkId=${linkId}&redirect=${encodeURIComponent(href)}`;
  
  return (
    <a href={trackedHref} style={linkStyle}>
      {children}
    </a>
  );
};

常見用例

用戶註冊

const sendWelcomeEmail = async (user) => {
  const verificationLink = `${process.env.NEXT_PUBLIC_APP_URL}/verify-email?token=${user.verificationToken}`;
  
  return await sendWelcomeEmail(
    user.email,
    user.name,
    verificationLink
  );
};

密碼重置

const sendPasswordResetEmail = async (user, resetToken) => {
  const resetLink = `${process.env.NEXT_PUBLIC_APP_URL}/reset-password?token=${resetToken}`;
  
  const emailHtml = render(PasswordResetEmail({ 
    name: user.name, 
    resetLink 
  }));
  
  return await sendHtmlEmail(
    user.email,
    'Reset Your Password',
    emailHtml
  );
};

訂單確認

const sendOrderConfirmationEmail = async (order) => {
  const emailHtml = render(OrderConfirmationEmail({ 
    order,
    customer: order.customer,
    items: order.items
  }));
  
  return await sendHtmlEmail(
    order.customer.email,
    `Order Confirmation #${order.id}`,
    emailHtml
  );
};

時事通訊

const sendNewsletter = async (subscribers, content) => {
  const emailHtml = render(NewsletterEmail({ content }));
  
  return await sendBulkEmail(
    subscribers,
    'Weekly Newsletter',
    emailHtml
  );
};

最佳實踐

電子郵件設計

  1. 移動優先: 首先為移動設備設計
  2. 一致的品牌: 使用您的品牌color和字體
  3. 清晰的 CTA: 使號召性用語按鈕突出
  4. 可讀文本: 使用足夠的對比度和fontSize
  5. 跨客戶端測試: 在不同的電子郵件客戶端中測試
### 表現
  1. 優化圖像: 壓縮圖像並使用適當的格式
  2. 最小化 HTML: 保持電子郵件 HTML 乾淨且最小化
  3. 謹慎使用網頁字體: 後備字體以獲得更好的兼容性
  4. 測試加載速度: 確保電子郵件快速加載

送達率

  1. 驗證您的域: 設置 SPF、DKIM 和 DMARC
  2. 維持良好聲譽: 避免垃圾郵件觸發因素
  3. 使用雙重選擇加入: 發送前確認電子郵件地址
  4. 提供取消訂閱: 始終包含取消訂閱鏈接

故障排除

常見問題

問:電子郵件未送達 答:檢查:
  • API 密鑰正確且有效
  • 發件人電子郵件已驗證
  • 域認證已設置
  • 電子郵件內容不會觸發垃圾郵件過濾器
問:未收到 Webhook 答:驗證:
  • Webhook URL 可從互聯網訪問
  • Webhook 端點返回 200 狀態
  • Webhook 秘密正確
  • 活動選擇正確
問:React 電子郵件模板未呈現 答:確保:
  • @react-email/組件已安裝
  • 電子郵件模板已正確導出
  • render() 函數使用正確
  • HTML結構有效
問:電子郵件將成為垃圾郵件 答:通過以下方式提高交付能力:
  • 設置域認證
  • 使用經過驗證的發件人地址
  • 避免垃圾郵件觸發詞
  • 保持良好的發件人聲譽

需要幫助嗎?

查看我們的常見問題解答,了解常見的 Resend 集成問題和故障排除提示。