lib/slack/supervisor.ex

defmodule Slack.Supervisor do
  @moduledoc """
  Supervisor that starts the stuff that needs to run.
  """
  use Supervisor

  require Logger

  @doc """
  Start the Slack bot supervisor.
  See `README` for instructions.
  """
  @spec start_link(config :: keyword()) :: Supervisor.on_start()
  def start_link(bot_config) do
    Supervisor.start_link(__MODULE__, bot_config)
  end

  @impl true
  def init(bot_config) do
    {app_token, bot_config} = Keyword.pop!(bot_config, :app_token)
    {bot_token, bot_config} = Keyword.pop!(bot_config, :bot_token)
    {bot_module, bot_config} = Keyword.pop!(bot_config, :bot)
    {channel_config, _bot_config} = Keyword.pop(bot_config, :channels, [])

    bot = fetch_identity!(bot_token, bot_module)

    children = [
      {Registry, keys: :unique, name: Slack.ChannelServerRegistry},
      {Registry, keys: :unique, name: Slack.MessageServerRegistry},
      {DynamicSupervisor, strategy: :one_for_one, name: Slack.DynamicSupervisor},
      {PartitionSupervisor, child_spec: Task.Supervisor, name: Slack.TaskSupervisors},
      {Slack.ChannelServer, {bot, channel_config}},
      {Slack.Socket, {app_token, bot}}
    ]

    Supervisor.init(children, strategy: :one_for_one)
  end

  defp fetch_identity!(bot_token, bot_module) do
    case Slack.API.get("auth.test", bot_token) do
      {:ok, %{"ok" => true, "bot_id" => _} = body} ->
        Slack.Bot.from_string_params(bot_module, bot_token, body)

      {_, result} ->
        Logger.error("[Slack.Supervisor] Error fetching user ID: #{inspect(result)}")
        raise "Unable to fetch bot user ID"
    end
  end
end