如何基于AWS Step Functions实现审批后向指定员工发送邮件
AWS Step Functions人工审批流程:经理审批后自动通知员工的实现方案
整体流程逻辑
用Step Functions + SNS + API Gateway + Lambda的组合实现:
- Step Functions触发SNS给经理发送带审批/拒绝链接的邮件,链接指向API Gateway端点,包含唯一任务令牌和员工邮箱
- 经理点击链接后,API Gateway触发Lambda函数
- Lambda完成两个核心动作:更新Step Functions状态机的审批结果,同时调用SNS给员工发送审批结果邮件
具体实现步骤
1. 配置Step Functions状态机
状态机需要包含「发送审批请求给经理」「等待审批结果」「处理审批通过/拒绝」「超时处理」等节点。关键是在发送审批邮件时,将Step Functions的任务令牌(唯一标识当前审批任务)和员工邮箱编码后放入链接:
{ "Comment": "员工晋升审批流程", "StartAt": "SendApprovalRequestToManager", "States": { "SendApprovalRequestToManager": { "Type": "Task", "Resource": "arn:aws:sns:us-east-1:123456789012:ManagerApprovalTopic", "Parameters": { "TopicArn": "arn:aws:sns:us-east-1:123456789012:ManagerApprovalTopic", "Message": "员工${$.employeeName}提交了晋升申请,点击链接审批:\n同意:https://your-api-id.execute-api.us-east-1.amazonaws.com/prod/approve?taskToken=${States.UriEncode($$.Task.Token)}&employeeEmail=${$.employeeEmail}\n拒绝:https://your-api-id.execute-api.us-east-1.amazonaws.com/prod/reject?taskToken=${States.UriEncode($$.Task.Token)}&employeeEmail=${$.employeeEmail}", "Subject": "晋升申请审批通知" }, "Next": "WaitForApproval" }, "WaitForApproval": { "Type": "Wait", "Seconds": 86400, "Next": "HandleTimeout" }, "HandleApproval": { "Type": "Choice", "Choices": [ { "Variable": "$.status", "StringEquals": "approved", "Next": "NotifyEmployeeApproved" }, { "Variable": "$.status", "StringEquals": "rejected", "Next": "NotifyEmployeeRejected" } ], "Default": "HandleTimeout" }, "NotifyEmployeeApproved": { "Type": "Task", "Resource": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic", "Parameters": { "TopicArn": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic", "Message": "你的晋升申请已被批准!", "Subject": "晋升申请结果通知", "TargetArn": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic:${$.employeeEmail}" }, "End": true }, "NotifyEmployeeRejected": { "Type": "Task", "Resource": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic", "Parameters": { "TopicArn": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic", "Message": "你的晋升申请已被拒绝,请联系经理了解详情。", "Subject": "晋升申请结果通知", "TargetArn": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic:${$.employeeEmail}" }, "End": true }, "HandleTimeout": { "Type": "Task", "Resource": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic", "Parameters": { "TopicArn": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic", "Message": "你的晋升申请审批超时,请联系经理跟进。", "Subject": "晋升申请超时通知", "TargetArn": "arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic:${$.employeeEmail}" }, "End": true } } }
$$.Task.Token是Step Functions内置的任务令牌,用States.UriEncode编码避免特殊字符导致链接失效$.employeeName和$.employeeEmail是启动状态机时传入的参数
2. 创建API Gateway端点
- 新建REST API,添加
/approve和/reject两个GET方法 - 每个方法的集成类型选择Lambda函数,关联同一个处理Lambda
- 启用CORS(允许所有来源或指定域名),确保链接能在浏览器中正常打开
- 部署API到生产环境,获取完整的端点URL,替换到状态机的SNS消息中
3. 编写Lambda处理函数
Lambda需要解析API Gateway传入的参数,更新Step Functions状态,同时触发员工通知:
import boto3 import urllib.parse stepfunctions = boto3.client('stepfunctions') sns = boto3.client('sns') def lambda_handler(event, context): # 解析并解码查询参数 query_params = event['queryStringParameters'] task_token = urllib.parse.unquote(query_params['taskToken']) employee_email = query_params['employeeEmail'] action = event['requestContext']['resourcePath'].strip('/') # 更新Step Functions状态机 try: if action == 'approve': stepfunctions.send_task_success( taskToken=task_token, output='{"status": "approved"}' ) message = "你的晋升申请已被经理批准!" else: stepfunctions.send_task_failure( taskToken=task_token, error="Rejected", cause="经理拒绝了你的晋升申请" ) message = "你的晋升申请已被经理拒绝,请联系经理了解详情。" except Exception as e: return { 'statusCode': 500, 'body': f"处理失败:{str(e)}" } # 给员工发送结果邮件 sns.publish( TopicArn='arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic', Message=message, Subject="晋升申请结果通知", TargetArn=f"arn:aws:sns:us-east-1:123456789012:EmployeeNotificationTopic:{employee_email}" ) return { 'statusCode': 200, 'body': f"{action}操作已完成,员工通知已发送" }
- 用
urllib.parse.unquote解码任务令牌 - 生产环境建议添加请求合法性验证(比如检查任务令牌对应的执行是否存在),防止恶意调用
4. 配置IAM权限
- 给Step Functions角色添加
SNS:Publish权限,允许向经理通知主题发送消息 - 给API Gateway的Lambda集成角色添加
StepFunctions:SendTaskSuccess和StepFunctions:SendTaskFailure权限,以及SNS:Publish权限 - 给Lambda角色添加对应的Step Functions和SNS权限
5. 测试流程
- 启动Step Functions状态机,传入
employeeName和employeeEmail参数 - 经理收到邮件后点击同意/拒绝链接
- 检查Lambda日志和SNS消息,确认状态机更新和员工邮件发送成功
生产环境优化建议
- 给API Gateway启用IAM认证或API密钥,防止未授权调用
- 给SNS邮件配置自定义域名和DKIM签名,降低垃圾邮件概率
- 在Lambda中添加错误处理和重试机制,确保通知可靠性
- 记录审批日志到CloudWatch,方便审计
内容的提问来源于stack exchange,提问作者Nikhil Dnyaneshwar Dalvi
相关产品推荐
相关产品推荐

