質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Slack

Slackは、Tiny Speckという企業からリリースされたコミュニケーションツールです。GoogleDriveやGitHubなど、さまざまな外部サービスと連携することができます。

Q&A

解決済

1回答

2487閲覧

Slackbotの無限投稿が止まない

ninba

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Slack

Slackは、Tiny Speckという企業からリリースされたコミュニケーションツールです。GoogleDriveやGitHubなど、さまざまな外部サービスと連携することができます。

0グッド

1クリップ

投稿2020/08/02 01:58

前提・実現したいこと

AWS初心者でもわかる! ブラウザ上で完結! AWS+Slack Event APIを使ったSlackボット超入門を参考にして作成したslackbotの無限投稿を防ぎたい。

発生している問題・エラーメッセージ

以下の図のように、作成したslackbotが無限投稿をしてしまう。
botの無限投稿の様子

該当のソースコード

python

1# -*- coding: utf-8 -*- 2import os 3import json 4import logging 5import urllib.request 6 7# ログ設定 8logger = logging.getLogger() 9logger.setLevel(logging.INFO) 10 11def handle_slack_event(slack_event: dict, context) -> str: 12 13 # 受け取ったイベント情報をCloud Watchログに出力 14 logging.info(json.dumps(slack_event)) 15 16 # Event APIの認証 17 if "challenge" in slack_event: 18 return slack_event.get("challenge") 19 # ボットによるイベントまたはメッセージ投稿イベント以外の場合 20 21 22 # 反応させないためにそのままリターンする 23 # Slackには何かしらのレスポンスを返す必要があるのでOKと返す 24 # (返さない場合、失敗とみなされて同じリクエストが何度か送られてくる) 25 if is_bot(slack_event) or not is_message_event(slack_event): 26 return "OK" 27 28 if slack_event.get("event").get("type") != "message": 29 return "OK" 30 31 if slack_event.get("event").get("subtype") == "bot_message": 32 return "OK" 33 34 # Slackにメッセージを投稿する 35 post_message_to_slack_channel("Hello, Slack Bot!", slack_event.get("event").get("channel")) 36 37 # メッセージの投稿とは別に、Event APIによるリクエストの結果として 38 # Slackに何かしらのレスポンスを返す必要があるのでOKと返す 39 # (返さない場合、失敗とみなされて同じリクエストが何度か送られてくる) 40 return "OK" 41 42def is_bot(slack_event: dict) -> bool: 43 return slack_event.get("event").get("subtype") == "bot_message" 44 45def is_message_event(slack_event: dict) -> bool: 46 return slack_event.get("event").get("type") == "message" 47 48def post_message_to_slack_channel(message: str, channel: str): 49 # Slackのchat.postMessage APIを利用して投稿する 50 # ヘッダーにはコンテンツタイプとボット認証トークンを付与する 51 url = "https://slack.com/api/chat.postMessage" 52 headers = { 53 "Content-Type": "application/json; charset=UTF-8", 54 "Authorization": "Bearer {0}".format(os.environ["SLACK_BOT_USER_ACCESS_TOKEN"]) 55 } 56 data = { 57 "token": os.environ["SLACK_APP_AUTH_TOKEN"], 58 "channel": channel, 59 "text": message, 60 "username": "Bot-Sample" 61 } 62 req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), method="POST", headers=headers) 63 urllib.request.urlopen(req) 64 return 65

試したこと

以下のようにbotの無限投稿を防げるであろう関数を取り入れた。

def is_bot(slack_event: dict) -> bool: return slack_event.get("event").get("subtype") == "bot_message" def is_message_event(slack_event: dict) -> bool: return slack_event.get("event").get("type") == "message"

###補足

バックエンドの知識が乏しく右も左も理解しておりません…知識のある方のお力を借りたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

どういうイベントが起きた時にHelloと言わせたいのでしょうか?
このコードだと、なんらかのイベントが起きるたびに、Helloと言ってしまうので無限にメッセージを送るのは想定できます。
具体的にはif文で自分の発言したいイベントが起きたかどうか確認してから、発言させるようにします。

Python3 + AWS LambdaでSlackbotをつくる(自分用メモ)
のページを参考にしたのだと思いますが、ここのページでもイベントをキャッチしてから発言するように作られています。

投稿2020/08/02 02:24

Penpen7

総合スコア698

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ninba

2020/08/02 02:34

回答ありがとうございます、説明不足で申し訳ございません。今回は私が貼ったリンク先にあるような、該当するチャンネルで発言する度にリプライを返してくれるbotを作成しようと試みています。penpen7様の資料にもあるような、botか否かを判断する関数、messageイベントか否かを判断する関数は、一応「試したこと」の欄にあるような形で実装はしています。しかし、なんの影響もないというのが現状です。お力添えいただければ幸いです。
Penpen7

2020/08/02 03:02 編集

if slack_event.get("event").get("type") != "message": return "OK" if slack_event.get("event").get("subtype") == "bot_message": return "OK" の部分は必要ないですね... 一度どういうイベントがきてるかprintして確認した方がいいと思います。 (qiitaの方の参考URLでも無限ループしているように見えますが...) もしくは、 is_bot(slack_event) or not is_message_event(slack_event) の中身の処理を間違っている可能性もあります。
ninba

2020/08/02 03:22

申し訳ございません。 if slack_event.get("event").get("type") != "message": return "OK" if slack_event.get("event").get("subtype") == "bot_message": return "OK" の部分は関数が上手く呼ばれているか確認しようとしたときに作成したもので、削除しておくべきでした。 is_bot(slack_event) or not is_message_event(slack_event)に何か問題があることは理解していますが、それが何なのか分かっていないというのが現状です。。。
Penpen7

2020/08/02 11:18

何れにせよ、どのようなイベントが飛んできているのか調査した方がいいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問