Help us understand the problem. What is going on with this article?

ぼくのさいきょうのslack bot

この記事は東京理科大学 Advent Calendar 2019の12/2の記事です。
昨日は@piffettによるapt-getとaptの使い分けでした。

こんにちは。にっし〜です。
ここではGoでslack botを作る話を書きます。

はじめに

ここでは主にgoでの実装についてだけ書いて、slackへの導入だったり諸々は前提として話を進めます。
また、AWS Lambdaでの実装はここに追記するか別途記事にする予定です。

経緯

バイト先で勉強会を運営しているのですが、参加登録だったり、終了後のアンケートを全てGoogle formを使って集計していました。
Google App Scriptを使って諸々自動化するなどの涙ぐましい努力()をしてきたのですが、流石に辛くなってきました。
AWSの社用アカウントをいただいたのをきっかけにGoで書き直して、slack内で全て完結する構成にしようと考えました。
ただ、これに割ける時間はそこまで多くはなく、先人の実装例があれば嬉しいなぁと思っていた矢先、shiimaxxさんのこちらを見つけました。
https://github.com/shiimaxx/slack-coffeebot
これをforkして機能を足していけば最速で欲しいものが完成させられるだろうということで、自分がforkして諸々実装したものがこちらです。
https://github.com/nisshii0313/slack-coffeebot

やったこと

欲しかった機能は次の2つです。
- message_actionへの対応
- Datepickerの実装

1つずつ見ていきます

1, message_actionへの対応

自分がslack botを狂ったように作っていた1年前は主に2つの選択肢がありました。
slash commandかbotとの対話か、です。しかしながらworkspaceが大きい場合、slash commandもたくさんあるし、botもたくさん入ってるし、で自分で作ったものでも使い方・botの名前を忘れるということが発生していました。
そこで、今回はactionsを使用することにしました。
actions_ui_preview.png
actionsであれば、勉強会の開催告知スレから直接開いてもらうこともできるし、この方法が最善だと考えました。
shiimaxxさんのものではbotとの対話に反応するように実装されていたので、次のようなコードを追記することでactionsに対応させました。

main.go
else if message.Type == "message_action" {
...
}

簡単にactionsに対応させることができました。
スクリーンショット 2019-12-02 9.20.48.png

2, Datepickerの実装

Datepickerの実装には新しい(2019/2~)UI フレームワークであるBlock Kitが必要です。
公式がドキュメントを用意してくれている他、使っているライブラリ(https://github.com/nlopes/slack) もv0.6.0からblock-kitに対応してくれています。優しい世界!!
ということでこれらに従って実装していきます。
まずは

Gopkg.toml
[[constraint]]
  name = "github.com/nlopes/slack"
  version = "v0.6.0"

と書いてdep ensureします。
これでblock-kitに対応したライブラリが使えるようになりました。

あとは
https://github.com/nlopes/slack/blob/445280bcb9c1b02b4a88b1ee9aa7afd735b2dc55/examples/blocks/blocks.go
あたりでも見ながらblockmessageを構築していきます。
blockを組み合わせる感じがコンポーネントを組み合わせてwebページを作る感じと似てるなって思いました。

以下Datepickerのblockの作り方です。
NewDatePickerBlockElementしたものをNewSectionBlockのAccessoryに設定してあげます。

main.go
func datepicker(userID string) slack.MsgOption {
    dateText := slack.NewTextBlockObject("plain_text", "date_sample", false, false)
    datePick := slack.NewDatePickerBlockElement("sample")
    dateSection := slack.NewSectionBlock(dateText, nil, slack.NewAccessory(datePick))

    return slack.MsgOptionBlocks(
        dateSection,
    )
}

最後にblock-kitのslackへの投稿方法です。
上でMsgOptionで返したものを第二引数にして、PostMessageメソッド(nlopes/slack)を使って表示させることができます。

main.go
picker := datepicker(message.User.ID)
if _, _, err := s.slackClient.PostMessage(message.Channel.ID, picker); err != nil {
    log.Print("[ERROR] Failed to post message")
}

はいできた!!
スクリーンショット 2019-12-03 2.59.19.png

以上です。ちょうど12月3日午前3時になりました。あらかたの投稿は2日のうちに済ませてたから許してね!

<<追記>> 2019/12/10
google calendarと紐付ける実装を追記しました。
これからも小規模な改善はするかもしれませんが、一旦はこれで完成です!!

shinonomeinc
東京理科大学発ベンチャー。提携大学内にソフトウェア研究所を組織し、学生向けのTech教育を提供しています。
http://shinonome.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした