26
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWSのLambdaからLambdaを呼んで、Slackにメッセージを送信する

Last updated at Posted at 2017-11-20

今回のお題

機能単位でLambdaを作成し、Lambda内からLambdaを実行する。
また、Requestで必要なデータを送信し、Responseで結果を得る。
本来はAWSのサービスのStep FunctionsやSNS使うことを考える必要があるのだろうけど、
チュートリアルなので次の課題とさせていただきます。

Requestで受けた情報を元にSlackへメッセージを送信するLambdaの作成

LambdaからWebHookを使用してSlackにメッセージを送信してみる

こちらを元に、下記のように定義しました。
少しずつ最終形に近づいています。

slack.py
# coding: UTF-8
import requests
import json
import os
from base64 import b64decode
import boto3
from datetime import datetime

def lambda_handler(event, context):
    # 時間を設定
    now = datetime.now()
    msg = now.strftime("%Y/%m/%d %H:%M:%S")
    
    # メンションを設定
    if event['user_id'] != None:
        msg += "\r\n<@%s>" % event['user_id']

    # メッセージを設定
    msg += u"\r\n%s" % event["message"]
    # 実行
    send_slack(u'カイジ', u':kaiji:', event['channel'], msg)
    
    return {"ret": True}

# slack送信、仮メソッド
def send_slack(user_name, icon, channel, msg):
    # WEBHOOK URLを複合化
    kms = boto3.client('kms')
    webhook = kms.decrypt(CiphertextBlob=b64decode(os.environ['WEBHOOK_URL']))['Plaintext']

    requests.post(webhook, data = json.dumps({
        'text': msg, # 投稿するテキスト
        'username': user_name, # 投稿のユーザー名
        'link_names': 1, # メンションを有効にする
        'channel': channel, # チャンネル
        'icon_emoji': icon, # アイコン
    }))

ポイント

  1. eventの中にはRequest内のパラメータが入っていますので、そこからSlackに使用する情報を取得しました。
    1. user_id : メンションするユーザID(Slackで自動で振られるMemberIDを使用)
    2. message : 本文
    3. channel : 送信先のチャンネル
  2. WebhookのURLを環境変数に入れて暗号化しました。使用する際に複合化してます。
    3. Lambdaの環境変数をKMSで暗号化して、Pythonで複合化する
    を元に実施しました。定数にしたり、DynamoDBに入れたりとかが正かもしれませんが、今回は環境変数にしました。

テスト実行。

テストイベントで、Requestパラメータを下記のように設定します。
スクリーンショット 2017-11-21 0.08.48.png

この状態でテストを実行します。
スクリーンショット 2017-11-21 0.14.23.png
チャンネルやちゃんとした名前はボカしてますが、無事にRequestから取得した内容でSlack通信できました。
(テストデータにゴミが入ってますね・・・失礼しました・・・)

別のLambdaから実行する

AWSでPythonを使用したLambdaを作ってみる
を元に、新規で1つLambdaを作成し、下記のようなソースを記載します。

lambda.py
# -*- coding: utf-8 -*-
import boto3
import json

def lambda_handler(event, context):
    clientLambda = boto3.client("lambda")
    # 引数
    params = {
        "user_id": "1234567890",
        "message": "lambdaからlambdaを実行する",
        "channel": "test"
    }
    res = clientLambda.invoke(
        FunctionName="呼び出すLambdaの関数名",
        InvocationType="RequestResponse",
        Payload=json.dumps(params)
    )

    # ResponseをJson形式に変換    
    pay=json.loads(res['Payload'].read())
    # 表示
    print(pay["ret"])

ポイント

  1. boto3.client("lambda")を使用して、lambdaをソースから実行できるようにしてます。
  2. RequestパラメータはJSON形式をエンコードして渡します。
  3. Response情報は、clientLambda.invokeでの結果を受け取り、Payloadの中に入ります。そちらを読み取り、JSON形式に変換してます。

テスト実行するとエラーに・・・

こちらで一度実行して見ました。
するとエラーになり、下記の文言が出てきました。

 is not authorized to perform

どうやら、デフォルトで用意されているロールの「lambda_basic_execution」を設定している場合は、他のLambdaを実行する権限が無いようです。

ロールを作成する

IAM>ロール>ロールの作成ボタンを押下します。
スクリーンショット 2017-11-21 0.25.01.png

ロールの作成

  1. AWSを選択します。
スクリーンショット 2017-11-21 0.26.15.png 2. Lambdaを選択し、次のステップへ スクリーンショット 2017-11-21 0.27.00.png

ポリシーの選択

画面上部でlambdaと入力し、必要なものを絞り込みます。
スクリーンショット 2017-11-21 0.27.48.png

  1. Lambdaでは、Cloud Watchが必要なようなので、「AWSLambdaBasicExecutionRole」を選択します。
スクリーンショット 2017-11-21 0.28.49.png 2. 他のLambdaを呼ぶために、「AWSLambdaRole」も追加します。 スクリーンショット 2017-11-21 0.29.58.png **おそらく、Resourceも指定して設定するのが本来の用途だと思いますが、今回は割愛します** 他にも必要に応じて、DynamoDBやRDSなど、必要なものを追加します。

ロール名と説明を入力して、完了

スクリーンショット 2017-11-21 0.32.12.png 説明は空でも構いません。

作成が完了すると、一覧に表示されます。

スクリーンショット 2017-11-21 0.33.07.png

Lambdaに戻って、ロールの設定をする。

先ほどのエラーになったLambdaに戻り、ロールを選択して保存します。
スクリーンショット 2017-11-21 0.34.42.png

テスト実行

テスト成功(returnを書いてないためnullになっている)
スクリーンショット 2017-11-21 0.35.39.png

ログにも、retの値のTrueが出る
スクリーンショット 2017-11-21 0.35.31.png

Slackにも送信結果が出力される。
スクリーンショット 2017-11-21 0.38.04.png

以上で、LambdaからLambdaを呼ぶことができました。

boto3については下記を参照願います。
http://boto3.readthedocs.io/en/latest/reference/services/lambda.html

26
26
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
26
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?