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

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ください。

kyokomi
VRでGo書いてます。最近はUnityも少々。 脱、エターナルしたい。
http://kyokomi.hatenablog.com/
cluster-inc
clusterは、誰でも手軽にバーチャルイベントに参加したり、開催したりすることができるサービスを運営するスタートアップです。利用用途はあなた次第。音楽ライブやミーティングなど、様々な「集まるシチュエーション」に活用可能です。
https://cluster.mu
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