"""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