Edited at
GoDay 13

GAE/GoでSlackの'/'(スラッシュ)コマンドサーバーを立てる

More than 3 years have passed since last update.

この記事は Go Advent Calendar 2015 の13日目の記事です。


はじめに

WebSocketを使ったhubotが圧倒的に流行っていますが、何かしらチャットでbotに話しかけてサーバー側で処理してSlackに結果を返すケースであれば、SlashCommandsのIntegrationで十分こと足ります。

https://api.slack.com/slash-commands

GAE/Goで、このSlashCommandsのサーバーを無料枠内でサクッと作れてしまうのでオススメです。


事前準備済み


  • Googleアカウント、GCP登録済み

  • Slack登録済み

  • Go環境構築済み

  • GAE/Go開発環境構築済み


環境準備


GoogleCloudPlatformでプロジェクトを作成する

スクリーンショット 2015-12-09 17.34.14.png

※プロジェクト名はご自由に設定ください


Project用意してdeployする


github.com/kyokomi/slack-slash-commandsをチェックアウトする。

$ git clone https://github.com/kyokomi/slack-slash-commands.git


app.yamlにプロジェクト名を設定


src/app.yaml

application: <自分で用意したプロジェクト名>

version: 1
runtime: go
api_version: go1

handlers:
- url: /.*
script: _go_app

- url: /favicon\.ico
static_files: assets/favicon.ico
upload: web/favicon\.ico
expiration: "14d"



GoogleAppEngineにdeployする

$ cd ./slack-slash-commands

$ make install
$ make deploy


SlackのIntegrationでSlashCommandsを追加

Integrationsを開いて Slash Commandsを選択する。

スクリーンショット 2015-12-09 17.31.44.png

ひとまずSlack上のスラッシュ呼び出しのコマンドを /hogecmdにする。

(これはご自由に設定ください)

スクリーンショット 2015-12-09 17.32.16.png


Autocomplete help textを設定する


  • Show this command in the autocomplete listにチェックを入れる

  • Descriptionに概要を入れる

  • Usage hintに追加する予定のコマンドを入れる(最初は無しでも良い)

スクリーンショット 2015-12-09 18.25.10.png


SlackのIntegration側の設定してSaveする

URLに https://<プロジェクト名>.appspot.com/v1/cmdを設定する。

(以下は例)

スクリーンショット 2015-12-09 17.46.00.png


Slackで動作を確認してみる

Slash Commandsに設定したコマンドを入力する。(例だと /hogecmd echo ふむふむ

aaaaaaaa.png

スクリーンショット 2015-12-13 0.08.51.png


自分でコマンドを追加する

基本的には、github.com/kyokomi/goslash/plugins/echoパッケージを参考にして実装してもらえばOKです。


AppEngineサーバーの現在時刻を返すプラグインを作る例


src/plugins/time.go

package time

import (
"time"

"github.com/kyokomi/goslash/goslash"
"github.com/kyokomi/goslash/plugins"
)

type plugin struct {
}

func New() plugins.Plugin {
return &plugin{}
}

func (p *plugin) Do(_ goslash.SlashCommandRequest) goslash.SlashCommandMessage {
return goslash.NewInChannelMessage(
time.Now().Format(time.RFC3339),
)
}




  • goslash.NewMessageだと自分以外のユーザーには見えないメッセージになる


  • goslash.NewInChannelMessageが自分以外のユーザーにも見えるメッセージになる


src/main.go

package app


import (
"net/http"

"github.com/kyokomi/goslash/goslash"
"github.com/kyokomi/goslash/plugins"
"github.com/kyokomi/goslash/plugins/echo"

+ "plugins/time"

"github.com/unrolled/render"
"google.golang.org/appengine"
"google.golang.org/appengine/urlfetch"
)

func init() {
renderer := render.New(render.Options{})

slashPlugins := map[string]plugins.Plugin{
"echo": echo.New(),
+ "time": time.New(),
}

http.HandleFunc("/v1/cmd", func(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)

req, err := goslash.ParseFormSlashCommandRequest(r)
if err != nil {
renderer.JSON(w, http.StatusInternalServerError, err.Error())
return
}

slashCmd := plugins.New(urlfetch.Client(ctx), slashPlugins)

renderer.Text(w, http.StatusOK, slashCmd.Execute(req))
})
}


上記の改修を行いdeployして、 /hogecmd timeとSlackに入力してみる。

スクリーンショット 2015-12-12 20.14.35.png

現在時刻を返してくれる。

スクリーンショット 2015-12-13 0.09.12.png

※上記の例は、GAE/Goに限定した実装になってますが、github.com/kyokomi/goslash/plugins/echoのように普通のGoライブラリとして実装すれば、GAE/Go以外でも使えます。


おわり

ちなみにAWSのEC2等(いま動いているAPIサーバー等)でも同様に、SlashCommands用のAPIを生やしてあげれば、サーバーの情報やDBに問い合わせた結果などをSlackのチャットで簡単にとることが可能になりますので、ぜひお試しください。

今回作ったgithub.com/kyokomi/goslashですが、かなり突貫工事で作ったのでおかしい所や追加したいプラグイン等あれば、お気軽にPRください。