CAKE20

AI Web PaaS

이메일

웹사이트별 SMTP를 설정하고 mail.send로 이메일을 전송합니다.

SMTP 설정

  • host에는 https:// 같은 프로토콜 없이 SMTP 호스트만 입력합니다.
  • 일반적으로 port 587과 secure false를 사용하며 서버가 지원하면 STARTTLS로 전환합니다.
  • 연결부터 TLS를 사용하는 SMTPS는 보통 port 465와 secure true를 사용합니다.
  • from은 모든 mail.send 호출에 적용되는 웹사이트 기본 발신자입니다.
  • 설정 변경은 웹사이트를 다시 시작한 뒤 적용됩니다.
// package.json
{
  "mail": {
    "host": "smtp.example.com",
    "port": 587,
    "secure": false,
    "from": "Cake20 <[email protected]>"
  }
}

SMTP 인증정보

  • 웹사이트 설정의 Secret에 SMTP_USER와 SMTP_PASSWORD를 저장합니다.
  • 두 값 중 하나만 설정할 수 없으며 인증이 필요 없는 SMTP라면 둘 다 생략합니다.
  • 인증정보를 package.json이나 서버 소스에 직접 작성하지 않습니다.
  • Secret은 암호화해서 저장하고 웹사이트 실행 환경에만 전달합니다.

이메일 전송

  • to, subject와 text 또는 html 중 하나가 필요합니다.
  • to, cc, bcc와 replyTo에는 문자열, 주소 객체 또는 배열을 사용할 수 있습니다.
  • 전송 결과에는 messageId, accepted, rejected와 SMTP response가 들어 있습니다.
  • API, job과 task의 에디터 테스트 실행도 실제 SMTP로 이메일을 전송합니다.
// server/api/welcome.post.ts
export const config = {
  filter: { email: z.string().email() },
  sample: { email: "[email protected]" }
};

export default async (
  data: Input<typeof config.filter>,
  context: ApiContext
) => {
  await auth.require(context.request);
  return mail.send({
    to: data.email,
    subject: "가입을 환영합니다.",
    text: "가입이 완료됐습니다.",
    html: "<strong>가입이 완료됐습니다.</strong>"
  });
};

첨부파일

  • 첨부 content에는 문자열이나 Uint8Array를 전달합니다.
  • 웹사이트 파일 경로나 외부 URL을 첨부파일로 직접 읽는 기능은 차단합니다.
  • 대량 발송은 API 요청 안에서 반복하지 말고 DB에 대상을 기록한 뒤 task로 나눠 처리합니다.
  • 공개 API에서는 인증, 수신자 제한과 요청 제한을 적용해 오픈 릴레이를 방지합니다.
const content = await storage.get("reports/monthly.pdf");
if (!content) throw new Error("첨부파일이 없습니다.");

await mail.send({
  to: "[email protected]",
  subject: "월간 보고서",
  text: "보고서를 첨부합니다.",
  attachments: [{
    filename: "monthly.pdf",
    content,
    contentType: "application/pdf"
  }]
});