Express.js에서 이메일 보내는 방법: SMTP 및 API 가이드
Source: Dev.to
사전 요구 사항
- Node.js가 머신에 설치되어 있어야 합니다. 여기에서 최신 버전을 다운로드하세요.
- 코드 편집기(예: Visual Studio Code).
- JavaScript에 대한 기본 지식.
- SendLayer 계정. 무료 체험을 시작하면 최대 200개의 이메일을 무료로 보낼 수 있습니다. SendLayer에서 무료 체험 시작.
SendLayer 계정을 만든 후, 이메일 전송 가능성을 높이기 위해 발신 도메인을 인증하세요.
Express.js 서버 설정
# 프로젝트 폴더 생성
mkdir send-email
cd send-email
# npm 프로젝트 초기화
npm init -y
# 의존성 설치
npm install express dotenv
프로젝트 루트에 server.js 파일을 생성합니다:
// server.js
const express = require('express');
const dotenv = require('dotenv');
dotenv.config(); // 환경 변수 로드
const app = express();
const port = process.env.PORT || 3000;
// JSON 데이터 파싱 미들웨어
app.use(express.json());
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
서버를 실행합니다:
node server.js
다음과 같이 표시됩니다:
Server running on port 3000
이제 http://localhost:3000에서 서버에 접근할 수 있습니다.
SMTP를 통한 이메일 전송
Nodemailer 설치
npm install nodemailer
환경 변수 설정
.env 파일을 만들고 SMTP 인증 정보를 추가합니다(예제는 SendLayer 사용):
SMTP_HOST=smtp.sendlayer.net
SMTP_PORT=587
SMTP_USER=your-smtp-username
SMTP_PASS=your-smtp-password
FROM_EMAIL=sender@example.com
Note: SendLayer의 경우, 발신 이메일은 인증된 도메인에 속해야 합니다(예:
@example.com).
server.js에 이메일 로직 추가
// server.js (continued)
const nodemailer = require('nodemailer');
// SMTP를 통해 이메일을 보내는 함수
const sendEmail = async (to, subject, message) => {
try {
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: Number(process.env.SMTP_PORT),
secure: false, // TLS(587)일 경우 false, SSL(465)일 경우 true
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
const mailOptions = {
from: process.env.FROM_EMAIL,
to,
subject,
text: message,
};
const info = await transporter.sendMail(mailOptions);
console.log('Email sent:', info.messageId);
} catch (error) {
console.error('Error sending email:', error);
throw error;
}
};
// 이메일 전송을 트리거하는 POST 라우트
app.post('/send-email', async (req, res) => {
const { to, subject, message } = req.body;
if (!to || !subject || !message) {
return res.status(400).json({ status: 'error', message: 'Missing required fields' });
}
try {
await sendEmail(to, subject, message);
res.status(200).json({ status: 'success', message: 'Email sent successfully' });
} catch (err) {
res.status(500).json({ status: 'error', message: 'Failed to send email' });
}
});
첨부 파일 전송 (선택 사항)
mailOptions에 attachments 배열을 추가합니다:
const mailOptions = {
from: process.env.FROM_EMAIL,
to,
subject,
text: message,
attachments: [
{
filename: 'example.pdf',
path: './path/to/example.pdf', // 올바른 경로로 업데이트
},
],
};
엔드포인트 테스트
서버 시작:
node server.js
cURL이나 Postman을 사용해 http://localhost:3000/send-email에 JSON 본문을 POST합니다:
{
"to": "recipient@example.com",
"subject": "Test Email",
"message": "Hello from Express.js!"
}
성공적인 응답 예시:
{
"status": "success",
"message": "Email sent successfully"
}
수신자의 받은편지함을 확인해 전송 여부를 확인하세요.
여러 수신자에게 보낼 경우, to 필드에 이메일 주소를 쉼표로 구분하면 됩니다.
API를 통한 이메일 전송
이 섹션에서는 SMTP 대신 이메일 서비스의 HTTP API(예: SendLayer)를 사용하는 방법을 설명합니다. 이 접근 방식은 대량 전송 시 전송 성공률과 확장성을 높여줍니다.
Axios(또는 다른 HTTP 클라이언트) 설치
npm install axios
.env에 API 자격 증명 추가
SENDLAYER_API_KEY=your-api-key
API 기반 전송 구현
// server.js (continued)
const axios = require('axios');
const sendEmailViaAPI = async (to, subject, message) => {
try {
const response = await axios.post(
'https://api.sendlayer.com/v1/email',
{
from: process.env.FROM_EMAIL,
to,
subject,
text: message,
},
{
headers: {
Authorization: `Bearer ${process.env.SENDLAYER_API_KEY}`,
'Content-Type': 'application/json',
},
}
);
console.log('API email sent:', response.data);
return response.data;
} catch (error) {
console.error('API error:', error.response?.data || error.message);
throw error;
}
};
// API 방식을 사용하는 예시 라우트
app.post('/send-email-api', async (req, res) => {
const { to, subject, message } = req.body;
if (!to || !subject || !message) {
return res.status(400).json({ status: 'error', message: 'Missing required fields' });
}
try {
await sendEmailViaAPI(to, subject, message);
res.status(200).json({ status: 'success', message: 'Email sent via API' });
} catch (err) {
res.status(500).json({ status: 'error', message: 'Failed to send email via API' });
}
});
API 방식은 SMTP 연결을 관리할 필요가 없으며, 템플릿, 추적, 속도 제한 등 더 풍부한 기능을 제공하는 경우가 많습니다.
일반적인 오류 해결
| 증상 | 가능한 원인 | 해결 방법 |
|---|---|---|
Error: self signed certificate | TLS 인증 실패 | 개발 환경에서만 secure: false 로 설정하고 tls: { rejectUnauthorized: false } 를 transporter 설정에 추가합니다. |
550 5.1.1 (recipient not found) | 잘못된 to 주소 | 이메일 주소 형식을 확인하고 도메인이 존재하는지 검증합니다. |
401 Unauthorized from API | 잘못된 또는 누락된 API 키 | SENDLAYER_API_KEY 가 정확하고 Authorization 헤더에 포함되어 있는지 확인합니다. |
| No email received | 이메일이 스팸함에 들어감 | 도메인의 SPF/DKIM 레코드를 확인하고 인증된 발신 주소를 사용합니다. |
Server crashes on sendMail | 처리되지 않은 프로미스 거부 | sendEmail 호출을 try/catch 로 감싸고 적절한 HTTP 상태 코드를 반환합니다. |
자주 묻는 질문
Q: SMTP와 이메일 API 중 어느 것을 사용해야 하나요?
A: 간단하거나 저용량일 경우 Nodemailer와 SMTP가 충분합니다. 대량 전송, 높은 전송 성공률, 템플릿·분석·추적 같은 고급 기능이 필요하면 이메일 API 사용을 권장합니다.
Q: HTML 이메일을 어떻게 보내나요?
A: mailOptions에 html 속성을 추가하거나 API 페이로드에 html을 포함하면 됩니다.
const mailOptions = {
from: process.env.FROM_EMAIL,
to,
subject,
html: '
## Hello
This is an HTML email.
',
};
Q: 이메일을 예약 전송할 수 있나요?
A: Nodemailer와 대부분의 이메일 API는 내장된 예약 기능을 제공하지 않습니다. node-cron 같은 작업 스케줄러나 Bull 같은 작업 큐를 사용해 원하는 시점에 전송을 트리거하세요.
Q: 속도 제한을 어떻게 처리하나요?
A: 이메일 제공자가 문서화한 제한을 준수하세요. 지수 백오프를 적용한 재시도 로직을 구현하거나, 대량 메일 전송 시 배치 요청을 사용합니다.