💌

AWS Lambdaで遊ぼう #3 LambdaからSNSでメール送信

2022/01/09に公開

こんにちは。 中村です。

今回は、LambdaからSNSへ連携してメール送付する手順を紹介します。

Amazon SNSとは

AWS様の直引用ですみません。m(___)m 以下の通りです。

Amazon SNS

Amazon Simple Notification Service (Amazon SNS) は、アプリケーション対アプリケーション(A2A)間と、アプリケーション対個人(A2P)間の両方の通信に使用できる、フルマネージド型メッセージングサービスです。
A2A での pub/sub 機能により、分散型システムやマイクロサービス、そして、イベント駆動型のサーバーレスアプリケーションにおいて、高スループットでプッシュベースの、多対多メッセージングをトピックで利用できるようになります。Amazon SNS トピックを使用することで、パブリッシャーシステムは、Amazon SQS キュー、AWS Lambda 関数、HTTPS エンドポイント、および Amazon Kinesis Data Firehose などの多数のサブスクライバーシステムに対しメッセージをファンアウトし、並列処理を行えます。A2P 機能を使用すると、SMS、モバイルプッシュ、E メールなどを介して、大量のユーザーに対しメッセージを送信できるようになります。

AWSリソースからSMSやEメールが遅れる感じですね ( ・ ∀ ・ )っ💌

前提条件

  • AWSアカウント作成ずみである事

構成図

こんな感じのものを作ります。

手順

① SNSトピック作成

何だかいつもこの流れですがw

AWSコンソール画面の検索窓に「sns」と入力し、SNSを選択する

左メニューの「トピック」をクリック、「トピックの作成」を実施する

タイプに「スタンダード」を選択し、SNSトピック名を入力する

画面一番下の「トピックの作成」をクリックする

トピックが作成されました。 続いて送信先を設定します。「サブスクリプションの作成」をクリックする

プロトコルに「Eメール」を選択する

エンドポイントにメールアドレスを入力する

画面一番下の「サブスクリプションの作成」をクリックする

ここまででSNSトピックの画面を見ると、サブスクリプションが登録され、ステータスが「保留中の確認(?)」となります。

サブスクリプションを登録すると、登録したメアド宛に確認メールが届きます。

「Confirm subscription」をクリックする

ブラウザに遷移し、この画面が表示されればOK

ステータスが「確認済み」になっている事を確認します。

② Lambda関数

Lambda関数を作成します。作り方はこちら

IAM設定

LambdaくんがSNSを操作できるように権限を追加してあげる必要があります。

AWSコンソール画面の検索窓に「iam」と入力し、IAMを選択する

左メニューから「ポリシー」を開き、「ポリシーを作成」をクリックする

「サービス」を展開し、検索窓に「sns」と入力。ヒットした「SNS」を選択する

「アクション」→「書き込み」と展開し、「Publish」にチェックを付ける

「リソース」は「すべてのリソース」を選択する

ここまでで「JSON」タブを開くと、権限情報がJSON形式で記載されています。
得意な人はこっちでJSONで書くのもアリですね

一番下の「次のステップ: タグ」をクリックする

タグは今回は特に不要なので、「次のステップ: 確認」をクリックする

ポリシー名を入力して「ポリシーの作成」をクリックする

Lambdaの画面へ行き、「設定」タブから「アクセス権限」を開く。 Lambdaに付いているロールをクリックする

ロールの画面に遷移するので、「ポリシーをアタッチします」をクリックする

先ほど作成したポリシー名を選択して、「ポリシーのアタッチ」をクリックする

ポリシーがアタッチされればOK

Lambdaソースコードを更新

さてさて、ここからプログラムを書いて行きますぞ!

Node.jsとPythonの両方を用意しました。 とにかく最もシンプルな書き方にしているので、プログラミングが得意な方はガンガンにカスタマイズしちゃってください。

パラメータ定義や、SNS連携の部分は関数で外だししてあげが方が良いでしょうし、 arnなどの特定情報は環境変数に入れてあげる方が良いでしょうし。 Lambda環境変数の活用については、また別途記事を書こうと思います。

Node.js 14.xの場合

index.js
const AWS = require('aws-sdk');
const sns = new AWS.SNS();

exports.handler = async (event) => {
    let params = {
        TopicArn: 'arn:aws:sns:ap-northeast-1:999999999999:sns-topic-name',
        Subject: 'Subject Lambda(node) -> SNSでメール送ったよ',
        Message: 'Message\n\nLambda -> SNSでメール送ったよ\n届いた?'
    };
    await sns.publish(params).promise();
};

Python 3.9の場合

lambda_function.py
import boto3
client = boto3.client('sns')

def lambda_handler(event, context):
    
    params = {
    'TopicArn': 'arn:aws:sns:ap-northeast-1:999999999999:sns-topic-name',
    'Subject': 'Subject Lambda(python) -> SNSでメール送ったよ',
    'Message': 'Message\n\nLambda -> SNSでメール送ったよ\n届いた?'
    }
    
    client.publish(**params)

AWS SDK

Lambdaから他のAWSリソースへアクセスするにはAWS SDKというものが必要になります。言語ごとにAWS-SDKのAPIリファレンスがあるのでそちらを参考にしつつ、コードを書いて行きます。全部英語なので、気合入れて行きましょうwww

また、Nodeで書く場合はAWS SDK for JavaScriptを使うのですが、v2とv3があるようです。新しいv3が推奨されているようですが、情報量的にはv2の方が圧倒的に多いので、どっちを使うか悩ましいところですね( ´Д`)y━・~~ 本記事ではv2を使っています。v3にも慣れていかねば。。。。

SNSトピックARNを確認する

上記ソースコードのSNSトピックARNの部分は実際に作ったSNSのARNに書き換えます。

SNSトピックの画面からARNを確認してください

③ 動作確認

よし!じゃあLambdaを動かしてみましょう!

「テスト」タブから「テスト」をクリックして動かします。

Lambdaは成功しましたね!

メールもちゃんと届きました!

念のため、CloudWatchLogsでエラー等出てないか確認しましょう。うん。大丈夫そうですね。

まとめ

LambdaとSNSの連携方法を紹介しましたが、SNSを作るのはそんなに難しくは無かったですね。
そして今回、IAMの設定手順が登場しました。Lambdaに限らずですがAWSを触っていると、とにかくIAMとの戦いになる気がしています。 たくさん触れば慣れてくるかと思います。

それでは左様なら( ・ ∀ ・ )ノシ

Discussion