【AWS IoTボタンでメッセージ送信 2 】AWS IoT 1-Clickで自動作成されたLambdaを修正してみる
スポンサーリンク
先日、AWS IoTボタンを購入し、AWSに登録、SMS送信までを行った。
ahrk-izo.hatenablog.com
ここでは「AWS IoT 1-Click」というサービスに予め用意されている「SMSに送信する」というアクションを利用した。
実際には、ここでLambda関数が自動で作成され、それが紐付いて動作している。なので今回はそのLambda関数を少し編集して、ボタンのクリックタイプ(シングル、ダブル、長押し)によってメッセージを変えてみる。
[前提]
さて目次
スポンサーリンク
1. 紐付いているLambda関数名を確認する
「AWS IoT 1-Click」で作成したプロジェクト(のプレイスメント)に紐付いているLambda関数を確認する。
「AWS IoT 1-Click」サービスを選択。
管理 > プロジェクト > 作成したプロジェクトを選択
テンプレート > アクション の情報をみる
「iot1click_onclick_sms_2019110311...」となっている。これは(自動で作成された)Lambda関数の名前だ。(「ラムダ」と読む)
つまり、このプロジェクトではボタンを押されたら、このLambda関数にキックされ、ここに書かれた実装コードが走る。それによってSMS送信されている。
Lambdaとは?
このLambda関数は、「AWS Lambda」というサービスで管理されている。
AWS Lambdaとは簡単にいうと、バックエンドで簡単にプログラムを実行できるサービス。
実装コードをアップロード(もしくは直接書いて保存)して、少し設定すれば、何かしらのキック(きっかけ)でそのコードが実行できる。その「キック」は定期実行もできるし、なにかしらのサービスとの連携でもできる。今回は「AWS IoT 1-Click」のサービスからのキックということだ。
※定期実行も正確にいうと「CloudWatch Events」というサービスとの連携
2. Lambda関数の内容を確認する
次にそのLambda関数を確認してみる。
「Lambda」サービスを選択。
Lambda > 関数
「iot1click_onclick_sms_20191103113059」というLambda関数があるね。Python 3.6で書かれたコードのようだ。
※関数名は、iot1click_onclick_sms_ + 作成日時になるんだろうな。
そのLambdaを選択し、中に入る。
このLambda関数が設定やコードがわかる。
まず目に入るのは「Designer」。
これを見ると、CloudWatch Log と SNS というAWSの他のサービスと連携していることがわかる。
簡単に言うと、
「Amazon CloudWatch Logs」は、AWSのいろんなサービスのログを監視して保存・閲覧できるサービス。これによってLambdaの実行内容(エラーとか)チェックできる。
Amazon CloudWatch Logs とは - Amazon CloudWatch Logs
「Amazon SNS」は、EメールやSMSなどでメッセージを配信できるサービス。これによってボタンを押したときケータイにSMSが送信できている。このSNSの設定も自動でされている(なんて便利!)。こっちの説明は割愛する。
Amazon SNS(サーバーレスアプリのための pub/sub メッセージングサービス)| AWS
さて次は、「関数コード」。
ここはいわゆる「実装コード」。つまりボタンを押されたら、このコードが走るということ。
ランタイム : Python 3.6
ハンドラ : lambda_function.lambda_handler
(lambda_function.py)
from __future__ import print_function import boto3 import json import logging logger = logging.getLogger() logger.setLevel(logging.INFO) sns = boto3.client('sns') def lambda_handler(event, context): logger.info('Received event: ' + json.dumps(event)) attributes = event['placementInfo']['attributes'] phone_number = attributes['phoneNumber'] message = attributes['message'] for key in attributes.keys(): message = message.replace('{{%s}}' % (key), attributes[key]) message = message.replace('{{*}}', json.dumps(attributes)) dsn = event['deviceInfo']['deviceId'] click_type = event['deviceEvent']['buttonClicked']['clickType'] message += '\n(DSN: {}, {})'.format(dsn, click_type) sns.publish(PhoneNumber=phone_number, Message=message) logger.info('SMS has been sent to ' + phone_number)
せっかくなので、部分的にざっくり解説してみる。
スポンサーリンク
モジュールのインポート
from __future__ import print_function import boto3 import json import logging
冒頭のこれらの部分は、このLambda関数に必要なモジュールをインポートしている。Pythonは必要なモジュールはこうやっていちいち書く(個別の説明は割愛)
ログの準備
logger = logging.getLogger() logger.setLevel(logging.INFO)
これらは、ログの準備。lambda_handler関数の中で logger.info() を使ってログ出力しているが、それを使うための準備。ログなのでSMS送信のプログラムには直接関係はしない。なので、ログ関連は省略する。
SMSサービス連携の準備
sns = boto3.client('sns')
Lambda関数AWS SNSサービスを使うための準備。boto3というモジュールを使うことで、あっさり連携できる。Pythonって便利。(boto3の中身は知らんけど、ドキュメント見ながら使えばそうなるんだから)
ハンドラ関数
def lambda_handler(event, context): ...
次はこちらの関数内を見ていく。「AWS IoT 1-Click」からこの関数が呼ばれ、実行される。その時引数としてeventが渡される。(コードを見ると、contenxtは使われていないから、eventのみの情報があるんだろうな)
eventの中身
attributes = event['placementInfo']['attributes'] phone_number = attributes['phoneNumber'] message = attributes['message']
「AWS IoT 1-Click」(のtest-projectのsend-smsというテンプレート)から渡された情報を関数に入れている。
電話番号とメッセージということがわかる。
プレイスメント属性の値をメッセージに使う
for key in attributes.keys(): message = message.replace('{{%s}}' % (key), attributes[key]) message = message.replace('{{*}}', json.dumps(attributes))
ここはsend-smsというテンプレート内で設定したプレイスメントの属性の各内容を、message内の{{ナントカ}}という文字の部分に置換している。
例えば
message : テストメールです。{{key1}}は{{key2}}です。
key1 : AWS
key2 : 最高
となっていたら、message変数に入るのは、
「テストメールです。AWSは最高です。」
となる。
SMS送信
dsn = event['deviceInfo']['deviceId'] click_type = event['deviceEvent']['buttonClicked']['clickType'] message += '\n(DSN: {}, {})'.format(dsn, click_type) sns.publish(PhoneNumber=phone_number, Message=message)
最後の部分。ここもわかりやすい。
デバイスのDSN(登録しているボタンのID)とクリックタイプ(シングル or ダブル or 長押し)を受け取り、メッセージに追記している。
最後は冒頭にboto3を使って準備していたsnsオブジェクトを使ってSMS送信。引数には電話番号とメッセージ。
これによって以下のようなメッセージがケータイのSMSに送信される。
3. Lambda関数を編集してみる。
実際にコードを編集してみて、どんなメッセージが送信されるか確かめてみる。それによって理解も深まる。
終盤のこの部分だけ編集してみる。
dsn = event['deviceInfo']['deviceId'] click_type = event['deviceEvent']['buttonClicked']['clickType'] message += '\n(DSN: {}, {})'.format(dsn, click_type)
繰り返しだが、ここはデバイスのDSNとクリックタイプをメッセージに追記している。
ここを以下のように修正してみる。
dsn = event['deviceInfo']['deviceId'] click_type = event['deviceEvent']['buttonClicked']['clickType'] message += '\n(ClickType: {})'.format(click_type) # <- ここだけちょっと変えた
メッセージにはクリックタイプだけを追記するようにした。
右上の「保存」を押して、
実際にボタンを押すと、ばっちり変更が反映されいる!
実際にクリックタイプによって、SINGLE、DOUBLE、LONGとなるので、if文使って、
if click_type == 'SINGLE': message += '1回押したぞい!' elif click_type == 'DOUBLE': message += '2回も押しちゃった' elif click_type == 'LONG': message += '長押しっす!'
とやってもよい。
これで、IoTボタンを押されたとき、どのようにSMS送信されているか、その仕組みと実装コードが理解できた。1からこの仕組を作るのは大変だけど、ある程度自動で作られて、そこを修正するくらいならそこまでハードルは高くない。
やはり動くものができて、それをカスタマイズできると楽しいな。
スポンサーリンク