[Python] Slack APIを使用してチャンネル内のメッセージを一件だけ残して一括削除してみた


はじめに

社内で使用している#generalチャンネルの運用を変更することになったため、メッセージを一括で削除してほしいと依頼されました。一件だけ残したいメッセージがあるとのことだったので、一件残しで削除するコードを作成しました。

環境

Visual Studio Code
Python3.9.1

準備

  • python-slackclientのインストール
    ターミナルで以下のコマンドを実行します。

    pip install slackclient
    
  • ユーザートークンの取得方法
    ユーザートークンを取得するには、アプリを作成する必要があります。
    アプリ作成は下記の記事を参考にしました。
    Slack API 推奨Tokenについて

    アプリ作成後、ユーザートークンを取得できるようになります。

    xoxpから始まるユーザートークンを使用します。

  • チャンネルID・タイムスタンプの取得方法
    対象チャンネルのメッセージのリンクからチャンネルIDとタイムスタンプを取得できます。

    例:https://xxxxxx.slack.com/archives/AAAAAAAAA/p1111111111000000
    "AAAAAAAAA"がチャンネルID、pを除いた"1111111111000000"がメッセージのタイムスタンプになります。
    ※APIで取得するタイムスタンプのフォーマットは"1111111111.000000"なので合わせる必要があります。

使用APIの説明

ソースコード

import time 
from slack import WebClient 

# slackのユーザートークン  
SLACK_CLIENT = WebClient('xoxpから始まるユーザートークン') 
# メッセージ削除対象のチャンネル名  
CHANNEL_ID ="AAAAAAAAA" 
# 削除したくないメッセージのタイムスタンプ  
NOT_DELETE_TS = "1111111111.000000" 

def main():
    while True: 
        # 最新のメッセージ100件を取得する
        channel_history = SLACK_CLIENT.conversations_history(channel=CHANNEL_ID)
        print('メッセ-ジ取得件数: {}'.format(len(channel_history['messages'])))
        if len(channel_history['messages']) <= 1:
            print('メッセ-ジが1件になったので終了')
            break
        for messages in channel_history['messages']:
            print(f'対象メッセ-ジ: {messages}')
            if messages['ts'] == NOT_DELETE_TS:
                print(f'スキップ対象メッセ-ジ: {messages}')
                continue
            SLACK_CLIENT.chat_delete(channel=CHANNEL_ID, ts=messages['ts'])
            time.sleep(0.5) # 連続実行をさける

            if 'thread_ts' in messages:
                thread_replies = SLACK_CLIENT.conversations_replies(channel=CHANNEL_ID, ts=messages['ts'])
                for thread in thread_replies['messages']:
                    # メッセージのタイムスタンプは削除済みのためスキップする
                    if messages['ts'] == thread['ts']:
                        continue
                    SLACK_CLIENT.chat_delete(channel=CHANNEL_ID, ts=thread['ts'])
                    time.sleep(0.5) # 連続実行をさける

if __name__ == '__main__':
    main()

苦労した点

"conversations.history"だけではメッセージのタイムスタンプしか取得できなかったので、スレッドの削除に苦労しました。API一覧からスレッドのタイムスタンプを取得できるものはないかなと探していたら"conversations.replies"を見つけて解決できました。

終わりに

今回初めてPythonとSlack APIを使用してコードを書いてみました。Pythonに興味はあったのですが業務では使う機会がなかったので書いてて楽しかったです。

参考資料

APIメソッド一覧