AWS Lambdaでは多くのプログラミング言語が使えますが、その中にRubyもあります。バージョンは執筆時点(2020年08月)で2.7となっており、最新に対応しています。もちろんこのRubyとCustomers Mail CloudのRubyライブラリを組み合わせてメール送信も可能です。
今回はS3にファイルをアップロードされたのをトリガーにして、そのファイルをメールする仕組みを作ってみます。
ローカルのコードを整備
AWS LambdaではRubygemsでインストールしたライブラリも利用できますが、あらかじめZipなどにまとまっていなければなりません。そのため、まず作業用のフォルダを作成します。
mkdir lambda_ruby cd $_
次に .bundle
フォルダを作成し、その中にconfigファイルを作ります。内容は次の通りです。
--- BUNDLE_PATH: "vendor/bundle"
そして Gemfileを作成します。内容は次の通りです。
source 'https://rubygems.org' gem 'aws-sdk-s3' gem 'customers_mail_cloud' gem 'multipart-post' gem 'mime-types'
後はライブラリをインストールします。
bundle
AWS Lambdaでの準備
AWS Lambdaで関数を作成したら、まず環境変数を作成します。今回は次の通りです。APIユーザ名、APIキーについては Microsoft Azure で手軽にメール送信する - Customers Mail Cloud ブログ を参考に取得してください。
キー | 値 |
---|---|
API_USER | Customers Mail Cloudで作成するAPIユーザ名です |
API_KEY | Customers Mail Cloudで作成するAPIキーです |
FROM_ADDRESS | メール送信元のアドレスです |
FROM_NAME | メール送信元の名前です |
アクセス権限
関数のロールに対してS3のアクセス権限(今回は読み取り権限のみ)を設定します。
実行可能時間
ダウンロードするファイルサイズにもよりますが、標準の5秒では処理がまず終了しません。今回は20秒としています。
コードについて
コードは def lambda_handler(event:, context:)
の中に記述していきます。ファイル名は lambda_function.rb
です。
ライブラリの読み込み
S3のライブラリと、Customers Mail Cloudライブラリを読み込みます。これは関数より前に記述します。
require 'aws-sdk' require 'customers_mail_cloud'
S3の初期化
S3を初期化します。リージョンは自分が使うもの、かつLambdaと同じリージョンにしてください。
s3 = Aws::S3::Resource.new(region: 'us-east-1')
アップロードされてきたオブジェクトを特定する
オブジェクトに関する情報は event 変数の中に入っています。次のようにしてオブジェクトを特定できます。
record = event["Records"][0]['s3'] obj = s3.bucket(record["bucket"]["name"]).object(record["object"]["key"])
ファイルをダウンロードする
S3のファイルを /tmp 以下にダウンロードします。階層構造の場合もあるので File.basename を使っています。
file_path = "/tmp/#{File.basename(record["object"]["key"])}" obj.download_file(file_path)
Customers Mail Cloudを準備する
まず初期化します。環境変数に設定したAPIキーを使って初期化しています。
client = CustomersMailCloud::Client.new(ENV['API_USER'], ENV['API_KEY'])
Web APIのエンドポイントは契約ごとに異なります。それを指定します。
client.trial() # トライアルの場合 client.standard() # スタンダードの場合 client.pro(subdomain) # プロの場合。サブドメイン指定が必須です
後はメール送信に必要な宛先、送信元、件名、本文をそれぞれ指定します。FROMについては環境変数を使っています。
client.from = CustomersMailCloud::MailAddress.new(ENV['FROM_ADDRESS'], ENV['FROM_NAME']) client.to << CustomersMailCloud::MailAddress.new('test@smtps.jp', 'Tester') client.subject = 'We got a file' client.text = 'S3に新しいファイルが追加されました'
添付ファイルを追加する
添付ファイルは attachments にファイルを追加します。ファイルのパスまたはファイルオブジェクトで指定できます。今回はパスで指定しています。
client.attachments << file_path
後はメール送信用のメソッドであるsendを実行すればOKです。
begin json = client.send puts json rescue => e puts e end
実行結果として、今回は14秒かかっています。
14558.70 ms
全体のコードです。実装時の参考にしてください。
require 'json' require 'aws-sdk' require 'customers_mail_cloud' def lambda_handler(event:, context:) s3 = Aws::S3::Resource.new(region: 'us-east-1') record = event["Records"][0]['s3'] obj = s3.bucket(record["bucket"]["name"]).object(record["object"]["key"]) file_path = "/tmp/#{File.basename(record["object"]["key"])}" obj.download_file(file_path) client.trial client = CustomersMailCloud::Client.new(ENV['API_USER'], ENV['API_KEY']) client.from = CustomersMailCloud::MailAddress.new(ENV['FROM_ADDRESS'], ENV['FROM_NAME']) client.to << CustomersMailCloud::MailAddress.new('test@smtps.jp', 'Tester') client.subject = 'We got a file' client.text = 'S3に新しいファイルが追加されました' client.attachments << file_path begin res = client.send { statusCode: 200, body: JSON.generate(res) } rescue => e { statusCode: 503, body: e.message } end end
まとめ
AWS SDKは非常に大きく、すべてインストールしてしまうと10MBを超えてしまい、オンラインでは編集できなくなります。S3だけインストールするのがお勧めです。
今回の実装でAWS Lambdaを使ったメール送信処理がとても簡単にできるのが分かってもらえるかと思います。ぜひAWSを使ったシステム構築でもCustomers Mail Cloudを役立ててください。