"""Send email notification via SMTP."""
import json
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from shared import get_ssm, update_job
def handler(event, context):
# Step Functions Catch 会把原始 input 包在 error 结构里
# 正常流程: event 有 job_id, email, summary
# 错误流程: event 有 job_id, email + error_info.Error/Cause
job_id = event.get('job_id', 'unknown')
email = event.get('email', '')
user_name = event.get('user_name', '')
summary = event.get('summary', '')
error_info = event.get('error_info', {})
error = error_info.get('Error', '') if isinstance(error_info, dict) else ''
cause = error_info.get('Cause', '') if isinstance(error_info, dict) else ''
if error or cause:
subject = f"[SP Transcribe] 任务 {job_id} 失败"
body = f"任务 {job_id} 处理失败。\n\n错误: {error}\n详情: {cause[:500]}"
if job_id != 'unknown':
update_job(job_id, status='FAILED', error=str(error)[:500])
else:
subject = f"[SP Transcribe] 会议纪要 - {job_id}"
body = summary or '(无总结内容)'
update_job(job_id, status='COMPLETED')
if not email:
return {**event, 'notify': 'skipped (no email)'}
# Send via SMTP
smtp_host = get_ssm('smtp/host')
smtp_port = int(get_ssm('smtp/port'))
smtp_user = get_ssm('smtp/user')
smtp_pass = get_ssm('smtp/pass')
smtp_from = get_ssm('smtp/from')
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = smtp_from
msg['To'] = email
# Plain text
msg.attach(MIMEText(body, 'plain', 'utf-8'))
# HTML (markdown-like)
html_body = body.replace('\n', '
').replace('**', '').replace('', '')
msg.attach(MIMEText(f"{html_body}", 'html', 'utf-8'))
with _smtp_connect(smtp_host, smtp_port, smtp_user, smtp_pass) as server:
server.send_message(msg)
return {**event, 'notify': 'sent'}
def _smtp_connect(host, port, user, passwd):
"""465 用 SMTP_SSL (隐式 TLS), 587 用 SMTP + STARTTLS"""
if port == 465:
server = smtplib.SMTP_SSL(host, port)
else:
server = smtplib.SMTP(host, port)
server.starttls()
server.login(user, passwd)
return server