Use Cases

How to Implement SendGrid Email: Claude Code 활용 가이드

implement sendgrid email: Claude Code 활용. 실용적인 코드 예시와 단계별 가이드를 포함합니다.

SendGridメール전송をClaude Code로효율적으로구현する

SendGridはTwilioが提供する클라우드メール配信サービスです。高い到達率と스케일러블な配信基盤を備え、트랜잭션メールからマーケティングメールまで幅広く대응します。Claude Codeを활용して、メール전송機能を효율적으로구축합시다。

기본적인メール전송

> SendGridでメール전송するサービス클래스を作って。
> 템플릿대응と에러 핸들링も含めて。
// src/services/email.ts
import sgMail from '@sendgrid/mail';

sgMail.setApiKey(process.env.SENDGRID_API_KEY!);

interface EmailOptions {
  to: string | string[];
  subject: string;
  text?: string;
  html?: string;
  templateId?: string;
  dynamicData?: Record<string, unknown>;
}

export class EmailService {
  private from = {
    email: '[email protected]',
    name: 'MyApp',
  };

  async send(options: EmailOptions): Promise<void> {
    const msg: sgMail.MailDataRequired = {
      to: options.to,
      from: this.from,
      subject: options.subject,
    };

    if (options.templateId) {
      msg.templateId = options.templateId;
      msg.dynamicTemplateData = options.dynamicData;
    } else {
      msg.text = options.text || '';
      msg.html = options.html || '';
    }

    try {
      await sgMail.send(msg);
      console.log(`Email sent to ${options.to}`);
    } catch (error: any) {
      if (error.response) {
        console.error('SendGrid error:', error.response.body);
      }
      throw new Error(`Failed to send email: ${error.message}`);
    }
  }

  async sendBulk(
    recipients: { email: string; data: Record<string, unknown> }[],
    templateId: string
  ): Promise<void> {
    const messages = recipients.map((r) => ({
      to: r.email,
      from: this.from,
      templateId,
      dynamicTemplateData: r.data,
    }));

    // SendGridは1요청で1000通まで
    const chunks = this.chunk(messages, 1000);
    for (const chunk of chunks) {
      await sgMail.send(chunk);
    }
  }

  private chunk<T>(array: T[], size: number): T[][] {
    const chunks: T[][] = [];
    for (let i = 0; i < array.length; i += size) {
      chunks.push(array.slice(i, i + size));
    }
    return chunks;
  }
}

ダイナミック템플릿の활용

> ウェルカムメールと비밀번호리셋メールの
> 템플릿를 사용한전송処理를 구현해줘。
// src/services/transactional-emails.ts
import { EmailService } from './email';

const emailService = new EmailService();

// 템플릿IDの상수관리
const TEMPLATES = {
  WELCOME: 'd-xxxxxxxxxxxxxxxxxxxx',
  PASSWORD_RESET: 'd-yyyyyyyyyyyyyyyyyyyy',
  ORDER_CONFIRMATION: 'd-zzzzzzzzzzzzzzzzzzzz',
} as const;

export async function sendWelcomeEmail(
  email: string,
  name: string
) {
  await emailService.send({
    to: email,
    subject: 'ようこそ!',
    templateId: TEMPLATES.WELCOME,
    dynamicData: {
      name,
      loginUrl: `${process.env.APP_URL}/login`,
      supportEmail: '[email protected]',
    },
  });
}

export async function sendPasswordResetEmail(
  email: string,
  resetToken: string
) {
  const resetUrl = `${process.env.APP_URL}/reset-password?token=${resetToken}`;

  await emailService.send({
    to: email,
    subject: 'パスワードリセットのご案内',
    templateId: TEMPLATES.PASSWORD_RESET,
    dynamicData: {
      resetUrl,
      expiresIn: '24時間',
    },
  });
}

export async function sendOrderConfirmation(
  email: string,
  order: { id: string; items: any[]; total: number }
) {
  await emailService.send({
    to: email,
    subject: `ご注文確認 #${order.id}`,
    templateId: TEMPLATES.ORDER_CONFIRMATION,
    dynamicData: {
      orderId: order.id,
      items: order.items,
      total: order.total.toLocaleString('en-US'),
    },
  });
}

Webhook で이벤트処理

> SendGridのEvent Webhookを処理して、
> バウンスやスパム報告を記録する엔드포인트を作って。
// src/api/sendgrid-webhook.ts
interface SendGridEvent {
  email: string;
  event: string;
  timestamp: number;
  reason?: string;
  sg_message_id?: string;
}

export async function handleSendGridWebhook(events: SendGridEvent[]) {
  for (const event of events) {
    switch (event.event) {
      case 'bounce':
        await handleBounce(event.email, event.reason || '');
        break;
      case 'spamreport':
        await handleSpamReport(event.email);
        break;
      case 'unsubscribe':
        await handleUnsubscribe(event.email);
        break;
      case 'delivered':
        await logDelivery(event.email, event.sg_message_id || '');
        break;
    }
  }
}

async function handleBounce(email: string, reason: string) {
  // バウンスしたアドレスを전송停止리스트に추가
  console.log(`Bounce: ${email} - ${reason}`);
}

async function handleSpamReport(email: string) {
  // スパム報告があったアドレスを除外
  console.log(`Spam report: ${email}`);
}

async function handleUnsubscribe(email: string) {
  // 配信停止処理
  console.log(`Unsubscribed: ${email}`);
}

async function logDelivery(email: string, messageId: string) {
  console.log(`Delivered to ${email}: ${messageId}`);
}

정리

SendGridとClaude Codeを활용すれば、트랜잭션メールからバルク配信まで효율적으로구현할 수 있습니다。メール자동화가이드Webhook구현도 함께 참고하세요.

SendGrid의 상세 정보는SendGrid공식 문서를 참고하세요.

#Claude Code #SendGrid #email #API #automation