You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于AWS Step Functions实现审批后向指定员工发送邮件

AWS Step Functions人工审批流程:经理审批后自动通知员工的实现方案

整体流程逻辑

用Step Functions + SNS + API Gateway + Lambda的组合实现:

  1. Step Functions触发SNS给经理发送带审批/拒绝链接的邮件,链接指向API Gateway端点,包含唯一任务令牌和员工邮箱
  2. 经理点击链接后,API Gateway触发Lambda函数
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:42:04