PythonでSESでemailを、SNSのSMSでショートメッセージを送信する


はじめに

みなさんは、アプリケーションからemailやショートメッセージを送信するような機能を実装したりしていませんか?
筆者も先日そのような機能を実装しました。もちろんAWSのSESとSNSを利用して。
Node.jsで書きたかったけど、諸所諸々の事由がありPythonで書いてます。
SESとかSNSとかSMSとかややこしい!ってなりながら実装しましたが、制限とかで詰まったところがあったので、今後のために記事に残しておこっと・・・

SESって?

SES(Simple Email Service)は、ユーザーが各自のEメールアドレスとドメインを利用して費用効率の高い簡単な方法でEメールを送受信するためのEメールプラットフォームのこと。
とりあえずAWSのサービスでEメールを送受信できるサービス。適当でごめんなさい・・・

SNSって?

SNS(Simple Notification Service)は、サブスクライブしているエンドポイントへのメッセージの配信または送信を調整し、管理するウェブサービスです。サブスクライバーとしてLambdaとかSQSとかSMSなどを使用することができます。
今回はSMSを使ってショートメッセージを送信します。

実装方法

アプリ側・AWSのほかのサービスなど呼び出しもとが複数あったのでLambdaに書くことにしました。
基本的にLambdaをキックしてSESやSMSを送信する感じです。

SES

送信先のメールアドレスは配列で渡してやれば、複数アドレスに送信することができます。
基本的にSESを利用する場合はあらかじめSESで登録・許可しておいたアドレスのみ送受信することができます。
しかしそれではアドレスが増えるたびに、SESに登録・許可をしなければいけないので、サポートに連絡して、サンドボックス環境から移動してもらいましょう。そうするとメール受信者の登録をする必要がなくなります。
(送信者のアドレスは必ず登録する必要がありますので注意)

import boto3

def lambda_handler(event, context):
  try:
    ses = boto3.client("ses", region_name = "us-west-2")
    ses.send_email(
      Source = "from_mailaddress",
      Destination = {
        "ToAddresses": "to_mailaddress"
      },
      Message = {
        "Subject": {
          "Data": "subject_title",
          "Charset": "UTF-8"
        },
        "Body": {
          "Text": {
            "Data": "body_message",
            "Charset": "UTF-8"
          }
        }
      }
    )
  except Exception as e:
    print e

SNS(SMS)

送信先の電話番号は国際電話番号(あたまに+81とかつけるやつ)でないと送信できないようです。
あとショートメッセージなので、メッセージの内容はほどほどにしておかないとエラーを吐いてきます。
またデフォルトの利用料金制限が1$/monthとなっていて、そのままでは数十通しか送信することができないです。
しかもその制限を上げることはできない(上げようとすると許可されてないよというエラー文が表示されます)ので、SES同様サポートに問い合わせて制限を上げられるようにしてもらいましょう。

import boto3

def lambda_handler(event, context):
  try:
    sns = boto3.client("sns")
    phoneNumber = "+818012345678"
    message = "send message"
    sns.publish(
      PhoneNumber = phoneNumber
      Message = message
    )
  except Exception as e:
    print e

さいごに

SESやSNS(SMS)の各制限に少し詰まってしまったことがあったので、今回記事に書きました。
AWS-SDKなどを活用すれば、アプリ側から簡単にメッセージを送信することができたりします。便利ですね。
Lambdaのeventに送信先のアドレスや電話番号とかメッセージの内容とか持たせて、それを参照すれば、ひとつのLambdaで使いまわすこともできます。便利ですね(2回目)。

ではまた!