たそらぼ

日頃思ったこととかメモとか。

lambda(Python)からlambda(Javascript)にデータを渡す

lambdaからlambdaを呼びたい!
でも調べるとJavaScriptの例しかなかった...。
Pythonで呼びたいのに!ということでやってみた。

lambdaからlambdaを呼ぶとどんないいことがあるの?

lambdaからlambdaを呼べると、例えばこんなことができるようになる。
f:id:tasotasoso:20181128224315p:plain
あとで説明するが、最初のLambdaの前にKinesis streamなどを置いておくと、データをバッファしつつ、lambdaの実行数を抑えられるMessagingパターンなどが使えるようになる。
データ数が多く流れるフローでlambdaの処理が溢れないよう制御できるようになる。
dev.classmethod.jp

というわけで、
・lambdaからlambdaを呼ぶのってどうすんの?
・lambdaからlambdaに渡ったデータの扱いってどんな感じでやったらいいの?
というのを確かめるため、勉強用にlambdaからJSONデータを渡して、中身をtweetする機能を作成した。

呼び出し元の実装

こっちはPythonで実装する。

import os
import boto3
import json
 
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
 
LAMBDA = boto3.client('lambda')
function_name = "tweet"
 
def lambda_handler(event, context):
  LAMBDA.invoke(
    FunctionName=function_name,
    InvocationType='Event',
    Payload=json.dumps(event)
  )
  message = f'Finished: dispatch message to function_name:{function_name}. '
  logger.info(message)
  return message

まずboto3でlambdaインスタンスを作成する。
インスタンスinvokeメソッドで呼び出し先のlambdaにデータを渡す。
ここで、
FunctionNameに呼び出し先のlambdaの名前を、
Payloadにeventを渡す。
eventはハンドラが呼び出される際に引数として渡されているJSONデータで、
lambdaのテスト機能を使う場合は、テストを設定する際に設定したJSONが含まれる。

呼び出し先の実装

eventからメッセージを取り出してツイートする。
こっちは今回JavaScriptで実装したものがあるので流用した。

npmでtwitter moduleを落としてきて、下のスクリプトと一緒にzipで固めてLambdaにおいておく。
認証情報は、あらかじめtwitter APIに登録して取得しておく。

var twitter = require('twitter');

var tweetbot = new twitter({
    consumer_key        : 'CUSTOMER_KEY',
    consumer_secret     : 'CUSTOMER_SECRET',
    access_token_key    : 'ACCESS_TOKEN_KEY',
    access_token_secret : 'ACCESS_TOKEN_SECRET'
});

exports.handler = function (event, context) {
  var params = {status: event.message};
  bot.post('statuses/update', params,  function(error, tweet, response){
    if(error) throw error;
    context.succeed(params.status);
  });
}

実行結果

呼び出し元のLambdaのテストを以下のように設定して実行する。
f:id:tasotasoso:20190210131156p:plain

tweet結果はこんな感じ。
ちゃんとテストのjsonの中身がツイートできていることが確認できる。
f:id:tasotasoso:20190210131214p:plain