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

如何在AWS Step Functions中向SQS关联Lambda传递输入与回调Token?

问题

我有一个关联Lambda函数的SQS FIFO队列,该SQS被AWS Step Functions包裹,通过回调完成执行,状态机模板如下:

{
  "Comment": "A description of my state machine",
  "StartAt": "SQS SendMessage",
  "States": {
    "SQS SendMessage": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken",
      "Parameters": {
        "MessageBody": {
          "input.$": "$",
          "token.$": "$$.Task.Token"
        },
        "QueueUrl": "https://sqs.eu-west-1.amazonaws.com/xxxx/myqueue.fifo",
        "MessageGroupId": "mygroupid"
      },
      "End": true
    }
  }
}

调用Step Functions时传入输入值"{\"foo\": \"bar\"}",Step Functions成功发送消息到SQS,但Lambda收到的响应中消息体为空:

{
    "Records": [
        {
            "messageId": "f24bdd16-4234b-47534-a67a-f12234234356",
            "receiptHandle": "some random string",
            "body": null,  // 问题所在
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1667313159855",
                "SequenceNumber": "49120530206362825178",
                "MessageGroupId": "mygroupid",
                "SenderId": "47X80CVTPC853VD6U5WSN:B9iwHdV1PkL1EbIDduFevS6KZ3YTrO0k",
                "MessageDeduplicationId": "njijzrghtu1hgatdkwjub3j08i2fzuqs0wj5q7kl9mlxfkrad3xz35mt43kyq602",
                "ApproximateFirstReceiveTimestamp": "1667313159855"
            },
            "messageAttributes": {},
            "md5OfBody": "kvzz7dtgoxv6kivo66260e3yn95igltj",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:eu-west-1:xxxxx:myqueue.fifo",
            "awsRegion": "eu-west-1"
        }
    ]
}

期望在Lambda中获取输入值和回调Token,认为MessageBody应为string类型而非object,并将Token附加到MessageBody中,预期结果如下:

"body": "{\"foo\": \"bar\",\"token\": \"callbacktoken\"}"

或

"body": {"payload": {"foo": "bar"}, "token": "callbacktoken"}

尝试过以下写法但无效:

"MessageBody.$":"States.JsonToString('{\"input.$\": \"$\", \"token.$\": \"$$.Task.Token\"}', $")"

请问我的思路是否正确?正确的实现方式是什么?

解决方案

你的思路方向是对的——SQS要求MessageBody必须是字符串类型,直接传入JSON对象会导致解析异常,最终Lambda收到的body为null。

正确实现方式

需要使用Step Functions的States.JsonToString函数,构造包含输入和Token的JSON结构后转换为字符串:

方式1:合并输入与Token为JSON字符串

修改状态机的MessageBody参数如下:

"MessageBody.$": "States.JsonToString({\"input\": $, \"token\": $$.Task.Token})"

此写法会将Step Functions的输入对象和Task Token合并为一个JSON对象,再转换为字符串发送到SQS。Lambda收到后,body字段会是类似"{\"input\":{\"foo\":\"bar\"},\"token\":\"callback-token-value\"}"的字符串,可直接在Lambda中解析为JSON对象使用。

方式2:自定义带payload的结构

如果需要更清晰的层级结构,可使用以下写法:

"MessageBody.$": "States.JsonToString({\"payload\": $, \"token\": $$.Task.Token})"

Lambda收到的body会是"{\"payload\":{\"foo\":\"bar\"},\"token\":\"callback-token-value\"}",完全匹配你预期的格式。

为什么之前的写法无效?

你之前的错误在于,在States.JsonToString的参数中错误使用了input.$这类路径引用语法——States.JsonToString的参数是直接构造JSON结构,变量引用只需写$或$$.Task.Token即可,. $后缀仅在Parameters的键值对中用来指定路径,不能嵌套在States.JsonToString的参数里。

内容的提问来源于stack exchange,提问作者Ramesh Murugesan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:20:36