# Getting Started
This guide walks you through creating a Slack bot from scratch—configuring a Slack App, obtaining tokens, and running your first handler.
## Prerequisites
- Elixir 1.17 or later
- A Slack workspace where you have permission to install apps
- Access to [api.slack.com](https://api.slack.com/apps)
## 1. Create a Slack App
1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App**.
2. Choose **From scratch**, give it a name (e.g., "MyBot"), and select your workspace.
3. You'll land on the app's **Basic Information** page.
## 2. Enable Socket Mode
Socket Mode lets your bot receive events over a WebSocket instead of exposing a public HTTP endpoint.
1. In the left sidebar, click **Socket Mode**.
2. Toggle **Enable Socket Mode** on.
3. You'll be prompted to generate an **App-Level Token**. Give it a name like `socket-token` and add the `connections:write` scope.
4. Copy the token (it starts with `xapp-`). This is your `SLACK_APP_TOKEN`.
## 3. Add Bot Scopes
1. In the sidebar, go to **OAuth & Permissions**.
2. Scroll to **Scopes** → **Bot Token Scopes** and add the scopes your bot needs. At minimum:
- `chat:write` — send messages
- `commands` — receive slash commands (if you plan to use them)
- `channels:read` — read channel metadata (for the cache sync)
3. If you want your bot to respond to messages or mentions, add `app_mentions:read` and/or `channels:history`.
## 4. Install the App
1. Still on **OAuth & Permissions**, scroll up and click **Install to Workspace**.
2. Authorize the app.
3. Copy the **Bot User OAuth Token** (starts with `xoxb-`). This is your `SLACK_BOT_TOKEN`.
## 5. Subscribe to Events
If your bot needs to react to messages, mentions, or other events:
1. Go to **Event Subscriptions** in the sidebar.
2. Toggle **Enable Events** on. (Socket Mode handles delivery, so you won't need a Request URL.)
3. Under **Subscribe to bot events**, add events like:
- `message.channels` — messages in public channels the bot is in
- `app_mention` — when someone @mentions your bot
4. Save changes.
## 6. Create a Slash Command (optional)
1. Go to **Slash Commands** in the sidebar.
2. Click **Create New Command**.
3. Fill in the command (e.g., `/demo`), a short description, and usage hint.
4. Save. Slack will deliver slash-command payloads over the Socket Mode connection.
## 7. Add SlackBot to Your Project
In your `mix.exs`:
```elixir
def deps do
[
{:slack_bot_ws, "~> 0.1.0"}
]
end
```
Run:
```bash
mix deps.get
```
## 8. Scaffold with Igniter (optional)
If you have [Igniter](https://hexdocs.pm/igniter) in your project:
```bash
mix slack_bot_ws.install
```
This creates a bot module, config stub, and supervision wiring. Skip to step 11 if you use this.
## 9. Define Your Bot Module
Create `lib/my_app/slack_bot.ex`:
```elixir
defmodule MyApp.SlackBot do
use SlackBot, otp_app: :my_app
# Respond to @mentions
handle_event "app_mention", event, _ctx do
MyApp.SlackBot.push({"chat.postMessage", %{
"channel" => event["channel"],
"text" => "Hi <@#{event["user"]}>! I heard you."
}})
end
end
```
The `use SlackBot, otp_app: :my_app` macro:
- Injects the DSL (`handle_event`, `slash`, `middleware`)
- Tells SlackBot to read configuration from `:my_app` application env
## 10. Configure Tokens
In `config/config.exs`:
```elixir
config :my_app, MyApp.SlackBot,
app_token: System.fetch_env!("SLACK_APP_TOKEN"),
bot_token: System.fetch_env!("SLACK_BOT_TOKEN")
```
Or in `config/runtime.exs` if you prefer runtime configuration.
## 11. Supervise the Bot
In your application supervisor (`lib/my_app/application.ex`):
```elixir
def start(_type, _args) do
children = [
MyApp.SlackBot
]
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
end
```
## 12. Run
Set your environment variables and start:
```bash
export SLACK_APP_TOKEN="xapp-..."
export SLACK_BOT_TOKEN="xoxb-..."
iex -S mix
```
Invite your bot to a channel (`/invite @MyBot`) and mention it. You should see a reply.
## Adding a Slash Command Handler
If you created a `/demo` command in step 6, add a handler:
```elixir
defmodule MyApp.SlackBot do
use SlackBot, otp_app: :my_app
slash "/demo" do
value :action
handle payload, _ctx do
action = payload["parsed"][:action] || "nothing"
MyApp.SlackBot.push({"chat.postMessage", %{
"channel" => payload["channel_id"],
"text" => "You asked me to: #{action}"
}})
end
end
handle_event "app_mention", event, _ctx do
MyApp.SlackBot.push({"chat.postMessage", %{
"channel" => event["channel"],
"text" => "Hi <@#{event["user"]}>!"
}})
end
end
```
Try `/demo deploy` in Slack. The handler receives `%{action: "deploy"}` in `payload["parsed"]`.
## What's Running Under the Hood
When your supervisor starts `MyApp.SlackBot`, SlackBot:
1. Reads configuration from `:my_app` app env and validates tokens
2. Starts an HTTP pool for Web API requests
3. Starts the ETS-backed cache and event buffer
4. Calls `apps.connections.open` to get a WebSocket URL
5. Opens the Socket Mode connection
6. Spawns supervised tasks for each incoming event
If the connection drops, SlackBot reconnects with exponential backoff. If Slack returns rate-limit headers, the rate limiter pauses outbound requests until the window passes.
## Next Steps
- [Slash Grammar Guide](slash_grammar.md) — build complex command parsers
- [Rate Limiting Guide](rate_limiting.md) — understand how tier-aware limiting works
- [Diagnostics Guide](diagnostics.md) — capture and replay events
- [Telemetry Guide](telemetry_dashboard.md) — integrate with LiveDashboard
The `examples/basic_bot/` directory contains a full working bot demonstrating middleware, advanced grammars, and diagnostics replay.