LoginSignup
4

More than 5 years have passed since last update.

【elixir】slackbotをつくり定期的にコメントさせる

Posted at

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って書いてて楽しい!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4