2
1

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.

[Go] slack-go/slackによるメッセージ一括削除

Posted at

普段からGoogle CalendarとSlackを連携して使っていて、新規予定作成時にSlack通知がくるように設定しています。ところが、この通知が溜まってくると全体のメッセージ数を圧迫してきます。

そこでSlackAPIを用いて、指定したチャンネル・タイトルの投稿を一括削除することにしました。折角なので、楽にPythonではなく、勉強がてらGoを用いて実行してみることに。Slack APIの仕様変更もあり、あまり情報がなかったので、まとめてみました。

0.環境

  • Go: 1.16.3
  • slack-go/slack: 0.10.1

1.APIトークンの取得

以前使われていたトークンは「レガシートークン」と呼ばれているようです。新しいトークンはアプリを作成した上で、必要な権限を設定する必要があります。1

今回は、このように設定しました。
権限設定

2.slack-go/slackのインポート

タイトルにもあるようにslack-go/slackを使用しました。GoでのslackAPI操作を効率的に行うことができます。

今回は、下記パッケージをインポートしました。そして、案の定パッケージインポートでつまづきました。

import (
	"flag"
	"fmt"
	"strings"
	"time"

	"github.com/slack-go/slack"
)

下記、サイトにて問題点を解決できました。問題点はモジュールモードとGOPATHモードでの扱い方を区別せずに取り組んでしまってことのようでした。

Golangのパッケージ完全に理解した - くろのて

2.クライアントの生成

slack-go/slackでは、Client構造体をトークンを用いて生成し、そこから操作を始めます。

今回は実行引数でトークンを渡すようにしました。

// Get access token from args
flag.Parse()
tkn := flag.Arg(0)
api := slack.New(tkn)

3.ChannelIDの取得

まずは、削除したい投稿があるChannelIDをチャンネル名称から見つけ出します。引数として独自の構造体を渡しますが、この渡し方がスマートな方法なのかどうかは分かりません。

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func get_calendar_channel(api *slack.Client) string {
	var result string
	calender_name := "calendar" // Target name of channel

	prm := slack.GetConversationsParameters{}
	channels, _, err := api.GetConversations(&prm)
	check(err)

	// Find channel
	for _, c := range channels {
		if strings.Contains(c.Name, calender_name) {
			result = c.ID
		}
	}
	return result
}

4.メッセージの特定と削除

最後に、該当のChannelIDに対して該当するメッセージを特定し、DeleteAPIを呼びます。APIの呼び出し上限を超えてしまわないように1秒間のSleepを入れています。

chn_id := get_calendar_channel(api) // Get target channel id

// Get message list
prm := slack.GetConversationHistoryParameters{ChannelID: chn_id, Limit: 1000}
res, err := api.GetConversationHistory(&prm)
check(err)

delete_title := "hogehoge" // Target title name to delete
var cnt int

for _, m := range res.Messages {
	for _, att := range m.Attachments {
		if att.Title == delete_title {
			_, _, err := api.DeleteMessage(chn_id, m.Timestamp)
			check(err)
			time.Sleep(1 * time.Second) // To escape the api limit
			cnt++
		}
	}
}
fmt.Println(cnt, "messages were deleted")

処理プロセスとしては以上です。

躓いたポイント

  • slack-go/slackのドキュメントには、各メソッドの説明がほぼない
    • ver0.10なので仕方ない点ではありますが、今回用いた各メソッドの説明は最低限のみでした
    • それぞれの引数の意味を知るためには、公式SlackAPIドキュメントから、slack-go/slackが呼ぶ先のAPI仕様を確認する必要がりました
  • GetConversationHistoryParametersメソッドの上限は1000件
    • 1000より大きい数値を実行すると、デフォルトの100件に戻されます

以上となります。Goは勝手にシンプルなコードにならざるを得ない点が気持ち良いですね。全体コードはこちらに公開しています。

  1. 参考: https://risaki-masa.com/how-to-get-api-token-in-slack/

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?