elixirを使ってslackのbotを作り、定期的にコメントできるようになるまでです。
slackのapi_tokenの取得などは割愛してます。
BOTを作成
ライブラリは下記を使いました。
elixirでslackbot作るようのライブラリ
slack
Cronっぽく実行できるライブラリ
quantum
サンプル用のプロジェクトを作成
mix new bot
mix.exs
の修正
mix.exs
defmodule Bot.Mixfile do
use Mix.Project
def project do
[app: :bot,
version: "0.1.0",
elixir: "~> 1.4",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps()]
end
def application do
[applications: [:logger, :slack, :quantum],
mod: {Bot, []}]
end
defp deps do
[
{:slack, "~> 0.11.0"},
{:quantum, "~> 1.9"}
]
end
end
次にconfig.exs
に追記
config.exs
use Mix.Config
config :quantum, :bot,
cron: [
"* * * * *": {Bot.ScheduleAction, :hello} # 実行させたいタスク
]
config :quantum,
timezone: "Asia/Tokyo" # デフォルトUTCなので設定ここで変更する
config :slack,
api_token: "{API_TOKEN}" # slackのトークン
プログラム作成
lib/bot.ex
defmodule Bot do
use Application
def start(_type, _args) do
Bot.Supervisor.start_link
end
end
slackのチャンネルIDを保持させるためにRegistryを使用してます。
lib/bot/supervisor.ex
defmodule Bot.Supervisor do
use Supervisor
def start_link(opts \\ []) do
Supervisor.start_link(__MODULE__, :ok, opts)
end
def init(:ok) do
api_key = Application.get_env(:slack, :api_token)
children = [
worker(Slack.Bot, [Bot.SlackBot, [], api_key]),
supervisor(Registry, Bot.Registry.opts())
]
supervise(children, strategy: :one_for_one)
end
end
lib/bot/slack_bot.ex
defmodule Bot.SlackBot do
use Slack
alias Bot.Registry
def handle_connect(slack, state) do
Registry.set_channel_id(lookup_channel_id("#general", slack))
Registry.set_slack(slack)
send_message("参上!", Registry.get_id(), slack) #成功したら参上!ってgeneralにつぶやく
{:ok, state}
end
end
lib/bot/registry.ex
defmodule Bot.Registry do
@key :slack_registry
def opts(), do: [:unique, @key]
def set_channel_id(channel_id), do: Registry.register(@key, :id, channel_id)
def set_slack(slack), do: Registry.register(@key, :slack, slack)
def update_slack(slack), do: Registry.update_value(@key, :slack, fn(_) -> slack end)
def get_id() do
case Registry.lookup(@key, :id) do
[{_pid, channel_id}] -> channel_id
_ -> nil
end
end
def get_slack() do
case Registry.lookup(@key, :slack) do
[{_pid, slack}] -> slack
_ -> nil
end
end
end
quantumに登録するようのアクション
lib/bot/actions/schedule_action.ex
defmodule Bot.ScheduleAction do
alias Bot.Registry
alias Slack.Sends
def hello() do
Sends.send_message("こんにちは", Registry.get_id(), Registry.get_slack())
end
end
実行してみる
mix deps.get
mix run --no-halt
うまくいくとgeneralに「参上!」とでて毎分「こんにちは」してきます
GitHubに今回のソース置いておきました。
elixirって書いてて楽しい!