4
4

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 1 year has passed since last update.

SlackのEvents APIのリクエストをGASで処理するときに複数回実行される問題(3秒のタイムアウト)の対策

Posted at

複数回実行とは?

SlackBotに各人毎のGoogle MeetのURLを出してもらう で作ったSlackbotが
1回だけレスポンスを返す想定のはずがたまに2〜4回レスポンスを返してくることがありました

スクリーンショット 2023-04-30 21.54.33.png

実害はなかったので無視していたんですが
最近新しく作ったbotでは深刻な問題だったので調査した結果解消することができました

原因

Slackからのリクエストに対してレスポンスを返すのに3秒以上かかるとリトライされる仕様を考慮できていなかったためでした
スプシ内での行の探索する処理が行数増えると遅くなるような実装になっていて
開発時やリリース当初は気付けず、しばらくしてから問題が起きていました

ちゃんと公式ドキュメントを見れば書いてあるし
ググればSlack Events APIの再送仕様と回避方法まとめ といった記事も出てくる

迷宮入りするような問題でもないのに2年以上放置するなんて怠惰ですね〜(自戒)

対処方法

処理の先頭でリクエストに含まれる client_msg_id をキーにしてキャッシュに値を入れて
2回目以降のりトライされたリクエストの場合(キャッシュヒットした場合)は処理をせずレスポンスを返すようにしました

function doPost(e) {
  const contents = JSON.parse(e.postData.contents);
  
  // slackの3秒タイムアウトリトライ対策
  let cache = CacheService.getScriptCache();
  if (cache.get(contents.event.client_msg_id) == 'done') {
    return ContentService.createTextOutput();
  } else {
    cache.put(contents.event.client_msg_id, 'done', 600);
  }

  // 時間かかる処理
  .
  .
  .

  return ContentService.createTextOutput();

なぜキャッシュなのか

  • キューイングしてすぐにレスポンスを返すことをSlackは推奨しているが、GASでキューイングはめんどくさい
  • リトライされたリクエストの場合ヘッダに X-Slack-Retry-Num がついてくるがGASではヘッダ検証できない

からです

以上!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?