- Add /v3/action/email/send router (api_v3_actions_email.py) replacing /util/email/send - Disable util_email router in registry; register new email action router - Mark /api/request_jwt and /api/temp_token as deprecated (TODO: remove) - Guide: add §8 Email Send Action, mark Axonius section EXPIRED, renumber §9-§11 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
"""
|
|
Aether API V3 - Email Action Router
|
|
-------------------------------------
|
|
Handles transactional email sending.
|
|
|
|
Routes:
|
|
POST /send — send a transactional email
|
|
|
|
Replaces: POST /util/email/send (legacy — see util_email.py)
|
|
"""
|
|
|
|
import logging
|
|
from typing import Optional
|
|
|
|
from fastapi import APIRouter, Depends, Query, Response
|
|
from pydantic import BaseModel, Field
|
|
|
|
from app.lib_email import send_email
|
|
from app.lib_general_v3 import AccountContext, get_account_context
|
|
from app.models.response_models import Resp_Body_Base, mk_resp
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class EmailSendRequest(BaseModel):
|
|
from_email: str = Field(..., description="Sender email address")
|
|
from_name: Optional[str] = None
|
|
to_email: str = Field(..., description="Recipient email address")
|
|
to_name: Optional[str] = None
|
|
cc_email: Optional[str] = None
|
|
cc_name: Optional[str] = None
|
|
bcc_email: Optional[str] = None
|
|
bcc_name: Optional[str] = None
|
|
subject: str = Field(..., description="Email subject line")
|
|
body_html: str = Field(..., description="HTML email body")
|
|
body_text: Optional[str] = None
|
|
|
|
|
|
@router.post('/send', response_model=Resp_Body_Base)
|
|
async def action_email_send(
|
|
req: EmailSendRequest,
|
|
test: bool = Query(False, description="Simulate send without delivering"),
|
|
account_ctx: AccountContext = Depends(get_account_context),
|
|
response: Response = Response,
|
|
):
|
|
log.setLevel(logging.INFO)
|
|
|
|
success = send_email(
|
|
from_email=req.from_email,
|
|
from_name=req.from_name,
|
|
to_email=req.to_email,
|
|
to_name=req.to_name,
|
|
cc_email=req.cc_email or '',
|
|
cc_name=req.cc_name or '',
|
|
bcc_email=req.bcc_email or '',
|
|
bcc_name=req.bcc_name or '',
|
|
subject=req.subject,
|
|
body_text=req.body_text,
|
|
body_html=req.body_html,
|
|
test=test,
|
|
)
|
|
|
|
if success:
|
|
status_code = 200
|
|
status_message = f'Email sent to <{req.to_email}>.'
|
|
else:
|
|
status_code = 400
|
|
status_message = f'Email failed to send to <{req.to_email}>.'
|
|
|
|
log.info(status_message)
|
|
resp_data = {
|
|
'from_email': req.from_email,
|
|
'to_email': req.to_email,
|
|
'subject': req.subject[:40],
|
|
}
|
|
return mk_resp(data=resp_data, status_code=status_code, response=response, status_message=status_message)
|