LoginSignup
1
0

slackbot 3秒ルール対策

Last updated at Posted at 2023-08-17

概要
ChatGPT用にslackbot(lambda)作成のお手伝いをする機会があり、その時出た問題点となります。(slackbot作成についてはコチラ:https://www.beex-inc.com/blog/slackbot-aws-lambda)

[slackbotの流れ]
slack画面 ⇔ slackAPI(サーバ) ⇔ APIGateway ⇔ lambda ⇔ ChatGPT

問題
ChatGPTの返答にはそれなりに時間がかかる(3秒以上)のですが、slackAPIは3秒以内に応答が返ってこなければ再リクエストを数回送り直す仕様となっているため、結果1つの質問メンションに対して複数同じ回答がslackに表示されてしまうといった現象が起こりました…

[slackbotイメージ]
111.png

解決策
以下のようにヘッダーにリトライ情報X-Slack-Retry-Numがある場合は以降の処理を行わないようにすると解決できました🎉

[サンプルコード]

import os
import re
from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler
from slackbot_backend import get_message

app = App(
  token=os.environ.get("SLACK_BOT_TOKEN"),
  signing_secret=os.environ.get("SLACK_SIGNING_SECRET"),
  process_before_response=True,
)
receiver = SlackRequestHandler(app)

# slackメンション時実行
@app.event("app_mention")
def onAppMention(event, say):
    textWithoutMention = re.sub(r"^<@(.+?)>", "", event["text"]).strip()
    # ChatGPTへの質問
    text = get_message(textWithoutMention)
    say(
        channel=event["channel"],
        thread_ts=event["event_ts"],  # 返信先スレッドを識別するための文字列
        text=text,
    )


def lambda_handler(event, context):
    # X-Slack-Retry-Numキーが存在する=リトライなので以降処理せずリターン
    headers = [v for k, v in event.items() if k == 'headers']
    if len(headers) > 0:
        slack_retry_num = [v for k, v in headers[0].items() if k == 'X-Slack-Retry-Num']
        if len(slack_retry_num) > 0:
            print(f'this event is slack retry. retry num is {slack_retry_num[0]}.No further processing.')
            return

    return receiver.handle(event, context)

[slackbotイメージ]
222.png

1
0
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
1
0