8
7

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] Slack Botがタイムアウトで何度もレスポンスするのを防ぐ

Last updated at Posted at 2019-03-11

何度もレスポンスする事例

前の記事で、slack botをAWS lambdaを使って作成しましたが、それの最後に述べたように、何度か同じレスポンスをしてしまう場合があります。
これはslackのタイムアウト時間が3秒しかなく、3秒以内にレスポンスできないとエラーと見なされ、何度か同じイベントを送ってくるため、それに対してlambda関数が何度か呼ばれてしまうことが原因です。
samplebot2.gif

解決方法

新しいlambda関数を作成し、そこから非同期でslackにpostするlambda関数を呼び出すことにする!
このようにすれば、slack APIへのレスポンスは新しいlambda関数からすぐに行うことができ、そのあとでゆっくりとワークスペースにpostMessageすることができます。

新しいlambda関数の作成

IAMロールの作成

前回の記事と同じ手順でロールを作成します。
今回はロールの名前をinvokeBotRoleとしました。
前回と異なるのは、Permissions PoliciesにAWSLambdaBasicExecutionRoleの他にAWSLambdaRoleを追加してください。これによって他のlambda関数を呼び出すことが可能になります。
image.png

lambda関数の作成

前回の記事ではJava縛りで作成しましたが、今回はサクッとPython3.7で作っていきます。
lambdaのページで以下のように設定して、invokeBotというlambda関数を作成しました。
image.png

API Gatewayの作成

これも前回の記事と同様に作成していきます。
今回は、invokeBotAPIという名前のAPIGatewayにして、デプロイ時のステージ名はinvokeBotStageとしました。
デプロイ時に表示されるURLをメモしておくのを忘れないでください。

lambda関数の編集

再びlambda関数のページに戻って編集していきます。
API Gatewayから入って、他のlambda関数に接続できるようになっていることが確認できると思います。
image.png

lambda関数を以下のように編集します。

  • FunctionName='sampleBot'の部分で呼び出すlambda関数の名前を設定しています
  • InvocationType='Event'とすることで非同期の実行が可能になります
  • Slack Event APIの認証にも対応できるようにしています
import json
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event: dict, context):
    
    logging.info(json.dumps(event))
    if "challenge" in event:
        return event.get("challenge")
        
    client = boto3.client('lambda')
    response = client.invoke(
        FunctionName='sampleBot',
        InvocationType='Event',
        LogType='Tail',
        Payload= json.dumps(event)
    )
    
    return {
        'statusCode': 200,
        'body': json.dumps('OK')
    }

また、一応念の為lambda関数のtimeout時間も3秒に設定しておくと、確実に3秒以内にslack APIにレスポンスが送られるため安全です。
image.png

イベントのRequest URLに設定

slack APIが呼び出すURLを新しいURLに変更しましょう
先ほどのAPIのデプロイ時にメモしておいたURLを設定し直します
image.png

動作確認

タイムアウトすることなく実行できています!
sampleBot3.gif

参考

AWS LambdaからLambda呼んでハマった話。
AccessDeniedException: User is not authorized to perform: lambda:InvokeFunction

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?