I'm trying to make a step function workflow for processing transactions and broadcasting a message when the transaction has been successful. Came up with something like this:
new SnsPublish(this, 'publish-successful-transaction', {
message: TaskInput.fromText(`transaction #${TaskInput.fromJsonPathAt('$.transactionId')} was processed successfully!`),
resultPath: '$.message',
topic: this.notification.topic
})
However, predictably .fromJsonPath()
returns an instance of TaskInput
which results in the normal object-in-a-string behaviour i.e [Object object]
.
I tried getting the value
property from the TaskInput
instance but that results in an error:
Error: Field references must be the entire string, cannot concatenate them
(found 'transaction #${Token[transactionId.269]} was processed successfully!')
Is there a way to have a custom text message with injected input path parameter? Can't seem to find anything on this even though it seems like quite a straightforward use case. What am I missing?
<Edit> Turns out there is a simple, one-line solution after all:
message: sfn.TaskInput.fromJsonPathAt("States.Format('transaction {} was processed successfully!', $.transactionId)")
The answer's original options are valid but more verbose </Edit>
Step Functions have a States.Format
intrinsic function to interpolate strings. But because intrinsic functions aren't accepted in all fields (including not in SnsPublish.message
), the solution is a bit less straightforward than you might hope.
First, the formatting. There are two equivalent CDK syntaxes for intrinsic functions:
// produce identical State Machine JSON output:
{
// State Machine Language JSON Syntax - DON'T FORGET .$ SUFFIX IN THE KEY
'myMessage.$' "States.Format('transaction {} was processed successfully!', $.transactionId)",
// JsonPath helpers - CDK only
sameMessage: sfn.JsonPath.format('transaction {} was processed successfully!', sfn.JsonPath.stringAt('$.transactionId'))
}
Next, you have two options to wire things up:
sfn.Pass
+ tasks.SnsPublish
Add a Pass
task to format the message and use the result inSnsPublish
's message property:
const formatMessage = new sfn.Pass(this, 'formatMessage', {
parameters: { 'message.$': "States.Format('transaction {} was processed successfully!', $.transactionId)", },
resultPath: '$.formatted',
});
const snsPublish = new tasks.SnsPublish(this, 'SnsPublish', {
topic: this.notification.topic,
message: sfn.TaskInput.fromJsonPathAt('$.formatted.message'),
});
tasks.CallAwsService
The parameters
property of the generic CallAwsService
task can handle intrinsic functions. Format and publish in a single task state:
const snsPublish2 = new tasks.CallAwsService(this, 'SnsPublish2', {
service: 'sns',
action: 'publish',
parameters: {
TopicArn: this.notification.topic.topicArn,
'Message.$': "States.Format('transaction {} was processed successfully!', $.transactionId)",
},
iamResources: [this.notification.topic.topicArn],
});