はじめに
SlackでBotを書きたいけど、Hubotは使いたくないし、なによりJavascriptを書きたくない。
でも直にReal Time Messaging APIを叩きに行くのはしんどい。
Hackageにいい感じのライブラリないかな…→ありました
https://hackage.haskell.org/package/slack-api
ということで、覚えたてのHaskell stackを使って、RTM APIを叩きに行くサンプルを作りました。
今回はgithubに載ってたEchoBotを動かすとこまで。
Slack bot
まずはbotのtokenを発行します。
https://slack.com/apps/A0F7YS25R-bots
(無料プランだとintegrationは10個までなので気をつけてください)
適当にUsernameを決めると謎の文字列(token)が手に入ります。魔法の呪文なので公開しないように。
もうこの時点でAPI documentのやつが使えるので、適当に
$ curl "https://slack.com/api/api.test" -X POST -d "token=xxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"
とかやるとjsonが帰ってきます。
{"ok":true,"args":{"token":"xxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"}}
お手軽ですね。
chat.postMessageとかもあります。一通り遊んでみましょう。
Haskell stack
stackが神すぎて泣いてます。
How to installに書いてある一行でインストールできるので今すぐ入れましょう。
適当な作業directoryで
$ stack new my-bot && cd my-bot
するといい感じのtemplateができます。
slack-apiはStackageには入ってないようなので、extra-depsに書きます。
diff --git a/stack.yaml b/stack.yaml
index 45ed1cb..754e7ac 100644
--- a/stack.yaml
+++ b/stack.yaml
@@ -39,7 +39,8 @@ packages:
- '.'
# Dependency packages to be pulled from upstream that are not in the resolver
# (e.g., acme-missiles-0.3)
-extra-deps: []
+extra-deps:
+- slack-api-0.11
そしてmy-bot.cabalに依存関係を書きます。
diff --git a/slackbot.cabal b/slackbot.cabal
index 75da504..041d58c 100644
--- a/slackbot.cabal
+++ b/slackbot.cabal
@@ -25,6 +25,7 @@ executable slackbot
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, slackbot
+ , slack-api
default-language: Haskell2010
test-suite slackbot-test
いったんbuildしてみます。結構時間がかかると思います。
$ stack build
これだけでslack-apiが使えるようになりました。
サンプルコードを動かす
slack-apiのgithubにあるExampleを動かしてみます。
app/Main.hsをまるっと以下で書き換えます。
module EchoBot where
import Web.Slack
import Web.Slack.Message
import System.Environment (lookupEnv)
import Data.Maybe (fromMaybe)
import Control.Applicative
myConfig :: String -> SlackConfig
myConfig apiToken = SlackConfig
{ _slackApiToken = apiToken -- Specify your API token here
}
echoBot :: SlackBot ()
echoBot (Message cid _ msg _ _ _) = sendMessage cid msg
echoBot _ = return ()
main :: IO ()
main = do
apiToken <- fromMaybe (error "SLACK_API_TOKEN not set")
<$> lookupEnv "SLACK_API_TOKEN"
runBot (myConfig apiToken) echoBot ()
そしてbuild。
$ stack build
起動。
$ env SLACK_API_TOKEN=xxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx stack exec my-bot-exe
botがオンライン状態になると思います。DMを送ってみましょう。
OK. オウム返しBOTの完成です。
まとめ
Haskell Stackを使ってSlackのRTM APIを叩くライブラリを扱えました。
stack.yamlとmy-bot.cabalの連携が最初よくわからなかったんですが、stackがここにこう書けばいいよ~って教えてくれたりしてすごかったです。
stack便利だなぁ
今回はデプロイまでは扱いませんでしたが、サーバって感じでもない(外部にポート晒したりしない)のでローカルで動かしておけばいいのでは?って感じもします。
どうでもいいけどslackとstackをよく見間違えます。