Skip to content

Commit 6c6f94e

Browse files
committed
Add /notify/email endpoint and update routes
Introduce a new email notification API under app/api/notify/email.py providing GET metadata and POST to send emails via the Resend SDK (with RESEND_API_KEY checks and goldlabel_email template). Update app/api/routes.py to include the new notify router and remove the old resend import. Update README references from /resend to /notify/email. Rename and update the test to target /notify/email, and remove the large Postman collection file. Also fix a tiny stray character/whitespace in app/__init__.py.
1 parent a91895b commit 6c6f94e

6 files changed

Lines changed: 113 additions & 820 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
This project provides a scalable API backend using FastAPI and PostgreSQL, featuring:
1010

1111
- Automatic full-text search on all text fields (via tsvector)
12-
- Endpoints for health checks, product management, prompt handling (via `/prompt`), resend email, and prospect management
12+
- Endpoints for health checks, product management, prompt handling (via `/prompt`), notify email, and prospect management
1313
- Efficient ingestion and processing of large CSV files
1414

1515
#### Features
@@ -54,7 +54,7 @@ FastAPI auto-generates interactive docs:
5454
- `GET /health` — Health check
5555
- `GET /prompt` or `GET /prompts` — Prompt table metadata (`record_count`, `columns`)
5656
- `POST /prompt` — LLM prompt completion (formerly `/llm`)
57-
- `GET/POST /resend` — Send email via Resend API (see implementation in `app/utils/notify/resend.py`)
57+
- `GET/POST /notify/email` — Send email via Resend API (see implementation in `app/api/notify/email.py`)
5858
- `GET /prospects` — Paginated prospects
5959
- `POST /prospects/process` — Bulk CSV ingestion
6060

app/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
# Current Version
44
__version__ = "3.1.0"
5-
p
5+

app/api/notify/email.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"""Email notification routes."""
2+
3+
import os
4+
import resend
5+
from fastapi import APIRouter, status
6+
from pydantic import BaseModel, EmailStr
7+
8+
from app.utils.make_meta import make_meta
9+
from app.utils.email_templates import goldlabel_email
10+
11+
resend.api_key = os.environ.get("RESEND_API_KEY")
12+
RESEND_API_KEY = resend.api_key
13+
14+
router = APIRouter(prefix="/notify")
15+
16+
class EmailRequest(BaseModel):
17+
to: EmailStr
18+
subject: str
19+
html: str
20+
cta_label: str | None = None
21+
cta_url: str | None = None
22+
23+
24+
def send_email_resend(to: str, subject: str, html: str) -> dict:
25+
if not resend.api_key:
26+
return {"error": "Missing RESEND_API_KEY"}
27+
params: resend.Emails.SendParams = {
28+
"from": "NX° <nx@goldlabel.pro>",
29+
"to": [to],
30+
"subject": subject,
31+
"html": html,
32+
}
33+
try:
34+
email: resend.Emails.SendResponse = resend.Emails.send(params)
35+
return dict(email)
36+
except Exception as e:
37+
return {"error": str(e)}
38+
39+
40+
@router.get("/email")
41+
def root() -> dict:
42+
"""GET /notify/email endpoint."""
43+
if not RESEND_API_KEY:
44+
meta = make_meta("error", "RESEND_API_KEY is missing from environment. Please set it in your .env file.")
45+
return {"meta": meta}
46+
meta = make_meta("success", "GET /notify/email endpoint")
47+
return {
48+
"meta": meta,
49+
"data": {
50+
"hint": "Use POST /notify/email to send an email via Resend API.",
51+
"type": {
52+
"to": {
53+
"type": "string",
54+
"format": "email",
55+
"required": True,
56+
"description": "Recipient email address."
57+
},
58+
"subject": {
59+
"type": "string",
60+
"required": True,
61+
"description": "Subject of the email."
62+
},
63+
"html": {
64+
"type": "string",
65+
"required": True,
66+
"description": "HTML content of the email."
67+
},
68+
"cta_label": {
69+
"type": "string",
70+
"required": False,
71+
"description": "Optional CTA button label. Defaults to 'Call To Action'."
72+
},
73+
"cta_url": {
74+
"type": "string",
75+
"required": False,
76+
"description": "Optional CTA URL. Defaults to the website base URL."
77+
}
78+
}
79+
}
80+
}
81+
82+
83+
@router.post("/email", status_code=status.HTTP_202_ACCEPTED)
84+
def send_email(request: EmailRequest):
85+
"""POST /notify/email endpoint to send email via Resend API."""
86+
if not RESEND_API_KEY:
87+
meta = make_meta("error", "RESEND_API_KEY missing. Please set it in your .env file.")
88+
return {"meta": meta}
89+
90+
result = send_email_resend(
91+
to=request.to,
92+
subject=request.subject,
93+
html=goldlabel_email(
94+
request.subject,
95+
request.html,
96+
cta_label=request.cta_label or "Call To Action",
97+
cta_url=request.cta_url or "https://goldlabel.pro",
98+
),
99+
)
100+
if "error" in result:
101+
meta = make_meta("error", result["error"])
102+
return {"meta": meta}
103+
104+
meta = make_meta("success", "Email sent successfully.")
105+
return {"meta": meta, "data": result}

app/api/routes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from app.api.root import router as root_router
99
from app.utils.health import router as health_router
10-
from app.api.notify.resend import router as resend_router
10+
from app.api.notify.email import router as notify_router
1111
from app.api.prompt.prompt import router as prompt_router
1212
from app.api.prompt.empty import router as prompts_empty_router
1313
from app.api.prompt.delete_id import router as prompt_delete_id_router
@@ -20,7 +20,7 @@
2020
from app.api.youtube import youtube_router
2121

2222
router.include_router(root_router)
23-
router.include_router(resend_router)
23+
router.include_router(notify_router)
2424
router.include_router(health_router)
2525
router.include_router(prompt_router)
2626
router.include_router(prompts_empty_router)

0 commit comments

Comments
 (0)