LoginSignup
2
0

[ TypeScript/JavaScript ] LambdaからSlackへカスタム通知を送る方法

Last updated at Posted at 2023-12-21

はじめに

この記事は、ミロゴス Advent Calendar 2023 22日目の投稿です。

業務でLambdaからSlackへAWS Chatbotのカスタム通知を送る実装を行ったので、実際のコードとポイントを紹介していきたいと思います。
既にSlackチャンネルと紐づいたSNSトピックを作成済みの前提で、カスタム通知をLambdaから送信する方法を記述していきます。

カスタム通知とは

Chatbotのカスタム通知は通常の通知とは異なり、ユーザー側でメッセージをカスタマイズすることが可能です。

今まではSlackで任意のメッセージ通知を行いたい場合、LambdaとSlackのIncomming Webhook機能を組み合わせて使うことが主流だったかと思います。
Chatbotのカスタム通知機能の登場により、Slackと紐づいたSNSトピックを準備するだけで任意のメッセージを送ることが可能になりました。

実行環境

  • AWS CDK

    • パッケージ: aws-cdk
    • バージョン: 2.110.1
  • AWS CDK ライブラリ

    • パッケージ: aws-cdk-lib
    • バージョン: 2.110.0
  • AWS SDK

    • パッケージ: aws-sdk
    • バージョン: 2.1304.0
  • TypeScript

    • パッケージ: typescript
    • バージョン: 4.8.4
  • Lambda Node.js

    • バージョン:18.x

実装の紹介

LambdaからSlackへカスタム通知を送るに当たり必要な実装を紹介します。

Lambda関数の作成

まずは呼び出すLambdaの作成です。

Lambdaを作成するに当たり、下記の二つが必要になります。

  • LambdaからSNSへのアクセス権限を設定する
  • SNSのTopic ARNを環境変数として渡す

SNSトピックの作成、SNSとChatbotを紐付けてSlackに通知できるようにするには別途設定が必要になります。
今回は作成済みのSNSからTopic ARNを引用する想定で記載しています。

import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as nodejs from 'aws-cdk-lib/aws-lambda-nodejs';

export default class LambdaConstruct extends Construct {
  constructor(
    scope: Construct,
    id: string,
    topicArn: string
  ) {
    super(scope, id);
    
    const customRole = new iam.Role(this, 'S3DownloaderRole', {
      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSNSFullAccess'),
      ],
        }),
      },
    });

    new nodejs.NodejsFunction(
      this,
      'lambda',
      {
           role: customRole,
           environment: {
               TOPIC_ARN: topicArn
           },
           //その他設定は省略
        },
    );
  }
}

Slackクラスの定義

Lambdaで使用するSlackクラスを作成します。
このクラスからカスタム通知を送信します。
PublishCommandで送信するMessageプロパティは、型にあったJSON化できる文字列でなければいけないので注意が必要です。
型の参考:https://docs.aws.amazon.com/ja_jp/chatbot/latest/adminguide/custom-notifs.html#parameter-details

import { PublishCommand, SNSClient } from '@aws-sdk/client-sns';

export class Slack {
  private topic: SNSClient;
  private topicArn: string;

  constructor(topicArn: string) {
    this.topic = new SNSClient({ region: 'ap-northeast-1' });
    this.topicArn = topicArn;
    log.info('slack', { slack: this });
  }

  public async sendMessage() {
    const description =
      `@channel\n$エラーが発生しました`

    const message = {
      version: '1.0',
      source: 'custom',
      content: {
        title: this.service,
        description: description,
      },
    };

    const result = await this.topic.send(
      new PublishCommand({
        Message: JSON.stringify(message),
        TopicArn: this.topicArn,
      })
    );
    log.info('Success send message');
  }

Lambda本体の実装

エラーをキャッチして、カスタム通知を送信する処理の例です。

import { Slack } from './slack';
import { ScheduledEvent } from 'aws-lambda';

const TOPIC_ARN = process.env.TOPIC_ARN || '';

export const handler = async (event: ScheduledEvent) => {

  const slack = new Slack(TOPIC_ARN);

  try {
    // 処理を記述
    log.info('Success All Process');
  } catch (error) {
    log.error('Error S3Downloader', { error });
    await slack.sendMessage(error);
    throw error;
  }
};

まとめ

今回は、Chatbotを利用してLambdaからSlackへカスタム通知を送る方法を紹介しました。
Chatbotのカスタム通知設定は新機能で情報も少ないと思われるので、少しでも他の方の助けになれば幸いです。

2
0
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
2
0