An open API service indexing awesome lists of open source software.

https://github.com/lee-lou2/rust-aws-ses-sender

[Rust] AWS SES Email Sender
https://github.com/lee-lou2/rust-aws-ses-sender

aws-ses aws-sns notifications notify rust rust-lang

Last synced: 6 months ago
JSON representation

[Rust] AWS SES Email Sender

Awesome Lists containing this project

README

          

# ๐Ÿ“ง AWS SES ์ด๋ฉ”์ผ ๋ฐœ์†ก๊ธฐ

[ํ•œ๊ตญ์–ด](README.ko.md) | [English](README.md)

AWS SES์™€ SNS๋ฅผ ํ™œ์šฉํ•œ ๊ณ ์„ฑ๋Šฅ ๋Œ€๋Ÿ‰ ์ด๋ฉ”์ผ ๋ฐœ์†ก ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.
Rust์™€ Tokio๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋˜์–ด ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ์•ˆ์ •์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

## ๐Ÿ— ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

### ๊ธฐ์ˆ  ์Šคํƒ
- ๐Ÿฆ€ **Backend**: Rust + Axum
- ๐Ÿ“จ **Email Service**: AWS SES
- ๐Ÿ”” **Notification**: AWS SNS
- ๐Ÿ”„ **Async Runtime**: Tokio
- ๐Ÿ’พ **Database**: SQLite

### ๋™์ž‘ ๋ฐฉ์‹

#### ์ฆ‰์‹œ ๋ฐœ์†ก ํ”„๋กœ์„ธ์Šค
1. API ์š”์ฒญ ์ˆ˜์‹  (`/v1/messages`)
2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐœ์†ก ์š”์ฒญ ์ €์žฅ
3. Tokio ์ฑ„๋„์„ ํ†ตํ•ด ๋ฐœ์†ก๊ธฐ๋กœ ์ฆ‰์‹œ ์ „๋‹ฌ
4. AWS SES ๋ฐœ์†ก ์†๋„ ์ œํ•œ์— ๋งž์ถฐ ์ˆœ์ฐจ ์ฒ˜๋ฆฌ
5. ๋ฐœ์†ก ๊ฒฐ๊ณผ ๋น„๋™๊ธฐ ์ €์žฅ

#### ์˜ˆ์•ฝ ๋ฐœ์†ก ํ”„๋กœ์„ธ์Šค
1. API ์š”์ฒญ ์ˆ˜์‹  (scheduled_at ํฌํ•จ)
2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜ˆ์•ฝ ์ •๋ณด ์ €์žฅ
3. ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ 1๋ถ„ ์ฃผ๊ธฐ๋กœ ์˜ˆ์•ฝ๋œ ์ž‘์—… ํ™•์ธ
4. ๋ฐœ์†ก ์‹œ๊ฐ„์ด ๋œ ๋ฉ”์ผ์„ ๋ฐœ์†ก๊ธฐ๋กœ ์ „๋‹ฌ
5. ์ฆ‰์‹œ ๋ฐœ์†ก๊ณผ ๋™์ผํ•œ ํ”„๋กœ์„ธ์Šค๋กœ ์ฒ˜๋ฆฌ

### ์„ฑ๋Šฅ ์ตœ์ ํ™”
- Tokio ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ๋Ÿฐํƒ€์ž„ ํ™œ์šฉ
- ๊ฒฝ๋Ÿ‰ ์Šค๋ ˆ๋“œ๋กœ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ ์ตœ์†Œํ™”
- ์ฑ„๋„ ๊ธฐ๋ฐ˜ ํšจ์œจ์  ํƒœ์Šคํฌ ๋ถ„๋ฐฐ
- AWS SES ๋ฐœ์†ก ์†๋„ ์ œํ•œ ์ž๋™ ์ค€์ˆ˜

![img.png](docs/process_diagram_ko.png)

## โœจ ์ฃผ์š” ๊ธฐ๋Šฅ

- ๐Ÿš€ ๋Œ€๋Ÿ‰ ์ด๋ฉ”์ผ ๋ฐœ์†ก ๋ฐ ์˜ˆ์•ฝ ๋ฐœ์†ก
- ๐Ÿ“Š ์‹ค์‹œ๊ฐ„ ๋ฐœ์†ก ๊ฒฐ๊ณผ ๋ชจ๋‹ˆํ„ฐ๋ง
- ๐Ÿ‘€ ์ด๋ฉ”์ผ ์—ด๋žŒ ์ถ”์ 
- โธ ๋Œ€๊ธฐ ์ค‘์ธ ์ด๋ฉ”์ผ ๋ฐœ์†ก ์ทจ์†Œ
- ๐Ÿ“ˆ ๋ฐœ์†ก ํ†ต๊ณ„ ๋ฐ ๊ฒฐ๊ณผ ๋ถ„์„

## ๐Ÿ”ง ์„ค์ • ๊ฐ€์ด๋“œ

### AWS SES ์„ค์ •ํ•˜๊ธฐ

[๐Ÿ‘‰ ์ž์„ธํžˆ ๋ณด๊ธฐ: ํ•ด๋‹น ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”](https://lee-lou2.notion.site/19d4d6ae33b58092a019ee88de9ca8a0?pvs=4)

#### 1๏ธโƒฃ ์ƒŒ๋“œ๋ฐ•์Šค ๋ชจ๋“œ ํ•ด์ œ (ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ)
- AWS SES๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒŒ๋“œ๋ฐ•์Šค ๋ชจ๋“œ๋กœ ์‹œ์ž‘
- ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์„ ์œ„ํ•ด [AWS Support Center์—์„œ ์ƒŒ๋“œ๋ฐ•์Šค ํ•ด์ œ ์š”์ฒญ](https://docs.aws.amazon.com/ses/latest/dg/request-production-access.html) ํ•„์š”

#### 2๏ธโƒฃ ๋„๋ฉ”์ธ ์ธ์ฆ
- AWS SES ์ฝ˜์†”์—์„œ ๋„๋ฉ”์ธ ๋“ฑ๋ก
- DNS์— DKIM, SPF ๋ ˆ์ฝ”๋“œ ์ถ”๊ฐ€ (์ œ๊ณต๋œ ๋ ˆ์ฝ”๋“œ ์‚ฌ์šฉ)
- ์ธ์ฆ ์™„๋ฃŒ๊นŒ์ง€ ์ตœ๋Œ€ 72์‹œ๊ฐ„ ์†Œ์š”

#### 3๏ธโƒฃ ์ด๋ฉ”์ผ ์ฃผ์†Œ ์ธ์ฆ (์ƒŒ๋“œ๋ฐ•์Šค ๋ชจ๋“œ)
- AWS SES ์ฝ˜์†”์—์„œ ๋ฐœ์‹ ์ž ์ด๋ฉ”์ผ ๋“ฑ๋ก
- ์ธ์ฆ ์ด๋ฉ”์ผ์˜ ํ™•์ธ ๋งํฌ๋กœ ์ธ์ฆ ์™„๋ฃŒ

### AWS SNS ์„ค์ •ํ•˜๊ธฐ (์„ ํƒ์‚ฌํ•ญ)

#### 1๏ธโƒฃ SNS ์ฃผ์ œ ์ƒ์„ฑ
- AWS SNS ์ฝ˜์†”์—์„œ ์ƒˆ ์ฃผ์ œ ์ƒ์„ฑ
- ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ฃผ์ œ ์ด๋ฆ„ ์„ค์ •

#### 2๏ธโƒฃ SES ์ด๋ฒคํŠธ ์„ค์ •
- SES Configuration Sets์—์„œ ์ƒˆ ์„ค์ • ์ƒ์„ฑ
- SNS ์ด๋ฒคํŠธ ๋Œ€์ƒ ์ถ”๊ฐ€
- ์ด๋ฒคํŠธ: Bounce, Complaint, Delivery
- ์ƒ์„ฑํ•œ SNS ์ฃผ์ œ ์—ฐ๊ฒฐ

#### 3๏ธโƒฃ SNS ๊ตฌ๋… ์„ค์ •
- SNS ์ฃผ์ œ์— ๊ตฌ๋… ์ถ”๊ฐ€ (HTTP/HTTPS, Email, SQS)
- ๊ตฌ๋… ํ™•์ธ ์ ˆ์ฐจ ์™„๋ฃŒ
- HTTP/HTTPS: ์—”๋“œํฌ์ธํŠธ์—์„œ ํ™•์ธ ์š”์ฒญ ์ฒ˜๋ฆฌ
- Email: ํ™•์ธ ๋งํฌ ํด๋ฆญ

![img_1.png](docs/aws_diagram.png)

## โš™๏ธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜

```env
# AWS ์„ค์ •
AWS_REGION=ap-northeast-2
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_SES_FROM_EMAIL=your_verified_email

# ์„œ๋ฒ„ ์„ค์ •
SERVER_URL=http://localhost:3000
SERVER_PORT=3000
DATABASE_URL=sqlite://sqlite3.db
JWT_SECRET=your_secret_key # Optional
MAX_SEND_PER_SECOND=12

SENTRY_DSN=your_sentry_dsn # Optional
```

## ๐Ÿ“ก API ๊ฐ€์ด๋“œ

### ์ด๋ฉ”์ผ ๋ฐœ์†ก

```http
POST /v1/messages
```

๋Œ€๋Ÿ‰ ์ด๋ฉ”์ผ ๋ฐœ์†ก ๋ฐ ์˜ˆ์•ฝ ๋ฐœ์†ก์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

```json
{
"messages": [
{
"topic_id": "newsletter_2024_01", // ์ปค์Šคํ…€ ์‹๋ณ„์ž
"emails": ["user@example.com"],
"subject": "1์›” ๋‰ด์Šค๋ ˆํ„ฐ",
"content": "์•ˆ๋…•ํ•˜์„ธ์š”..." // HTML ํ˜•์‹
}
],
"scheduled_at": "2024-01-01 09:00:00" // ์„ ํƒ์‚ฌํ•ญ
}
```

### ๋ฐœ์†ก ๊ฒฐ๊ณผ ์ถ”์ 

#### ๐Ÿ“จ SNS ์ด๋ฒคํŠธ ์ˆ˜์‹ 
```http
POST /v1/events/results
```
AWS SES๋กœ๋ถ€ํ„ฐ ์‹ค์‹œ๊ฐ„ ๋ฐœ์†ก ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค:
- โœ… Delivery: ๋ฐœ์†ก ์„ฑ๊ณต
- โŒ Bounce: ๋ฐœ์†ก ์‹คํŒจ
- โš ๏ธ Complaint: ์ŠคํŒธ ์‹ ๊ณ 

#### ๐Ÿ‘ ์ด๋ฉ”์ผ ์—ด๋žŒ ํ™•์ธ
```http
GET /v1/events/open?request_id={request_id}
```
1x1 ํˆฌ๋ช… ์ด๋ฏธ์ง€๋ฅผ ํ†ตํ•ด ์ด๋ฉ”์ผ ์—ด๋žŒ ์—ฌ๋ถ€๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
- ์ด๋ฉ”์ผ ๋ณธ๋ฌธ ํ•˜๋‹จ์— ์ž๋™ ํฌํ•จ
- ์ด๋ฉ”์ผ ์—ด๋žŒ ์‹œ ์ž๋™์œผ๋กœ ์„œ๋ฒ„์— ๊ธฐ๋ก
- request_id๋กœ ๊ฐœ๋ณ„ ์ˆ˜์‹ ์ž ํ™•์ธ ๊ฐ€๋Šฅ

### ๋ชจ๋‹ˆํ„ฐ๋ง & ๊ด€๋ฆฌ

#### ๐Ÿ“Š ๋ฐœ์†ก ํ•œ๋„ ํ™•์ธ
```http
GET /v1/events/counts/sent
```
AWS SES ์ผ์ผ ๋ฐœ์†ก ํ•œ๋„ ๋ฐ ์ž”์—ฌ ์ˆ˜๋Ÿ‰์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

#### ๐Ÿ“ˆ ํ† ํ”ฝ๋ณ„ ๊ฒฐ๊ณผ ์กฐํšŒ
```http
GET /v1/topics/{topic_id}
```
topic_id ๊ธฐ์ค€์œผ๋กœ ๋ฐœ์†ก ๊ฒฐ๊ณผ๋ฅผ ์ง‘๊ณ„ํ•ฉ๋‹ˆ๋‹ค:
- ์ด ๋ฐœ์†ก ์ˆ˜
- ์„ฑ๊ณต/์‹คํŒจ ์ˆ˜
- ์—ด๋žŒ ์ˆ˜

#### โน ๋ฐœ์†ก ์ทจ์†Œ
```http
DELETE /v1/topics/{topic_id}
```
๋Œ€๊ธฐ ์ค‘์ธ ์ด๋ฉ”์ผ ๋ฐœ์†ก์„ ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค.
- topic_id์— ํ•ด๋‹นํ•˜๋Š” ๋ชจ๋“  ๋Œ€๊ธฐ ๋ฉ”์ผ ์ทจ์†Œ
- ์ด๋ฏธ ๋ฐœ์†ก๋œ ๋ฉ”์ผ์€ ์ทจ์†Œ ๋ถˆ๊ฐ€

## ๐Ÿ“š ์ฐธ๊ณ  ์ž๋ฃŒ

- [AWS SES ๊ฐœ๋ฐœ์ž ๊ฐ€์ด๋“œ](https://docs.aws.amazon.com/ses/latest/dg/Welcome.html)
- [AWS SNS ๊ฐœ๋ฐœ์ž ๊ฐ€์ด๋“œ](https://docs.aws.amazon.com/sns/latest/dg/welcome.html)