Current section
Files
Jump to
Current section
Files
lib/slack.ex
defmodule Slack do
@moduledoc """
A behaviour module for implementing Slack realt time messaging through a
websocket connection.
To use this module you will need a valid Slack API token. You can find your
token on the [Slack Web API] page.
[Slack Web API]: https://api.slack.com/web
## Example
```
defmodule SlackRtm do
use Slack
def start_link(initial_state) do
Slack.start_link(__MODULE__, "token_value", initial_state)
end
def init(state, _socket) do
{:ok, state}
end
def handle_message({:type, "message", response}, socket, state) do
Slack.send_message("Received message!", response.channel, socket)
state = state ++ [response.text]
{:ok, state}
end
def handle_message({:type, type, _response}, _socket, state) do
IO.puts "No callback for #\{type}"
{:ok, state}
end
end
```
Slack has a large variety of types it can send you, so it's wise ot have a
catch all handle like above to avoid crashing.
## Callbacks
* `init(state, socket)` - Called when the websocket connection starts
It must return:
- `{:ok, state}`
* `handle_message({:type, type, json_map}, socket, state)`
It must return:
- `{:ok, state}`
You can find every type Slack will respond with and examples of each on
the [Slack RTM API](https://api.slack.com/rtm) page.
"""
defmacro __using__(_) do
quote do
@behaviour Slack.Handler
def init(_, state) do
{:ok, state}
end
def handle_message({:type, type, _response}, _socket, state) do
{:stop, {:unhandled_type, type}, state}
end
defoverridable [init: 2, handle_message: 3]
end
end
@doc """
Starts a websocket connection to the Slack real time messaging API using the
given token.
Once started it calls the `init/1` function on the given module passing in the
websocket connection as its argument.
"""
def start_link(module, token, state, options \\ %{}) do
options = Map.merge(default_options, options)
websocket = options.websocket
url = start_rtm(token, options.rtm)
websocket.start_link(url, Slack.Socket, %{handler: module, state: state})
end
@doc """
Sends `text` as a message to the the channel with id of `channel_id`
eg: `Slack.send_message("Morning everyone!", "CA1B2C3D4", sock)`
"""
def send_message(text, channel_id, socket, websocket \\ :websocket_client) do
message = %{type: "message", text: text, channel: channel_id}
|> JSX.encode!
websocket.send({:text, message}, socket)
end
defp default_options do
%{
rtm: Slack.Rtm,
websocket: :websocket_client
}
end
defp start_rtm(token, rtm) do
{:ok, response} = rtm.start(token)
response.url |> String.to_char_list
end
end