1
1

Step Functionsからchatbot経由でslack連携してみた

Posted at

初めに

chatbotってLambdaがイベントソースの場合はslack連携してくれず、いけているのかいけていないのかよく分からないサービスですよね

step functionsだと、実行ステータスの変更イベントでEventBridgeが発火してSNSからslack連携することが出来ました
slack連携は出来ましたが、デフォルトのメッセージ内容が実行ステータスしか読み取れない状態でしたので、そこら辺に一工夫必要でした
断片的な情報はWebや生成AIから拾えましたが、欲しい情報に辿り着くまで苦労したので、ここに纏めておきます

コンテンツ

SFnの実行ステータス遷移イベント

step functionsのイベント例interface EventPattern からセットしていきます

下のようになりました

sfn_event.ts
    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を作成します

topic.ts
  createTopic(): Topic {
    const topicName = `${this.SFnName}-topic`;
    return new Topic(this, topicName, { topicName: topicName });
  }

Slack連携メッセージの整形

slackで知りたい内容は、どのSFnなのかと実行ステータスなので、下のようにしました

AWSのイベントのサンプルを参照に必要なもののみをInputPathsMapにセットします

InputTemplateは文字列を渡す必要があるため、Objectを文字列化しています
slackのmarkdownを使いたかったので、「_」(イタリック)や「*」(ボールド)で囲んでいます
AWSのドキュメントからフォーマットや必須の内容を確認してセットします

transform.ts
    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が必須ですね

ruleL1.ts
 const cfnEventRule = rule.node.defaultChild as CfnRule;
    cfnEventRule.addPropertyOverride('Targets', [
          {
              Arn: topic.topicArn,
              Id: 'SNS-Topic',
              InputTransformer: tfr,
          },
    ]);

上記で良さそうでしたが、L2でもターゲットを追加しないとダメでした

ruleL2.ts
    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の設定

特に変わったところはないかと思います

chatbot.ts
    new SlackChannelConfiguration(this, this.chatbotName, {
      slackChannelConfigurationName: this.chatbotName,
      slackChannelId: props.channelID,
      slackWorkspaceId: this.workspaceID,
      notificationTopics: [topic],
    });

追記

普段はL2しか使っていないため、L1へのキャストは中々敷居が高かったです
ですが、CDKの理解につながる良いきっかけを頂きました

slack連携用のLambdaを作らず、CDKへの追記のみでslack連携出来るのはありがたいものです

この記事がどなたかの参考になると嬉しいです

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1