初めに
chatbotってLambdaがイベントソースの場合はslack連携してくれず、いけているのかいけていないのかよく分からないサービスですよね
step functionsだと、実行ステータスの変更イベントでEventBridgeが発火してSNSからslack連携することが出来ました
slack連携は出来ましたが、デフォルトのメッセージ内容が実行ステータスしか読み取れない状態でしたので、そこら辺に一工夫必要でした
断片的な情報はWebや生成AIから拾えましたが、欲しい情報に辿り着くまで苦労したので、ここに纏めておきます
コンテンツ
SFnの実行ステータス遷移イベント
step functionsのイベント例 と interface EventPattern からセットしていきます
下のようになりました
const rule = new Rule(this, this.SFnName, {
eventPattern: {
source: ["aws.states"],
detailType: ["Step Functions Execution Status Change"],
detail: {
status: ["SUCCEEDED", "FAILED", "TIMED_OUT", "ABORTED"],
// status: ["FAILED", "TIMED_OUT", "ABORTED"],
},
},
ruleName: `${this.SFnName}-event`,
});
データ連携SNS Topic
適当にTopicを作成します
createTopic(): Topic {
const topicName = `${this.SFnName}-topic`;
return new Topic(this, topicName, { topicName: topicName });
}
Slack連携メッセージの整形
slackで知りたい内容は、どのSFnなのかと実行ステータスなので、下のようにしました
AWSのイベントのサンプルを参照に必要なもののみをInputPathsMapにセットします
InputTemplateは文字列を渡す必要があるため、Objectを文字列化しています
slackのmarkdownを使いたかったので、「_」(イタリック)や「*」(ボールド)で囲んでいます
AWSのドキュメントからフォーマットや必須の内容を確認してセットします
makeTransformer() {
return {
InputPathsMap: {
account: '$.account',
sfnName: '$.detail.stateMachineArn',
execArn: '$.detail.executionArn',
status: '$.detail.status',
time: '$.time',
},
InputTemplate: JSON.stringify({
version: '1.0',
source: 'custom',
content: {
textType: 'client-markdown',
title: '<status>: _<sfnName>_',
description: 'Finished at *<time>*\nAccount: *<account>*\nexecArn: *<execArn>*',
},
}),
};
}
トランスフォーマーのセット
Ruleへのトランスフォーマーの適用メソッドとかオプションのプロパティは、通常触るL2には提供されていないので、L1に変更して適用します
AWSのドキュメントはこちら。ArnとIdが必須ですね
const cfnEventRule = rule.node.defaultChild as CfnRule;
cfnEventRule.addPropertyOverride('Targets', [
{
Arn: topic.topicArn,
Id: 'SNS-Topic',
InputTransformer: tfr,
},
]);
上記で良さそうでしたが、L2でもターゲットを追加しないとダメでした
rule.addTarget(new SnsTopic(topic, {message: RuleTargetInput.fromObject(tfr)}));
参考資料
L1, L2の説明
https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/constructs.html
L2からL1へのキャスト
https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Node.html#defaultchild
Chatbotの設定
特に変わったところはないかと思います
new SlackChannelConfiguration(this, this.chatbotName, {
slackChannelConfigurationName: this.chatbotName,
slackChannelId: props.channelID,
slackWorkspaceId: this.workspaceID,
notificationTopics: [topic],
});
追記
普段はL2しか使っていないため、L1へのキャストは中々敷居が高かったです
ですが、CDKの理解につながる良いきっかけを頂きました
slack連携用のLambdaを作らず、CDKへの追記のみでslack連携出来るのはありがたいものです
この記事がどなたかの参考になると嬉しいです