概要
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に表示されてしまうといった現象が起こりました…
解決策
以下のようにヘッダーにリトライ情報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)