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

  • 36
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

この記事は 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ください。

この投稿は Go Advent Calendar 201513日目の記事です。