Packages
Slack Web API wrapper library that automatically throttles all requests according to API rate limits.
Current section
Files
Jump to
Current section
Files
lib/slack/api.ex
defmodule SlackThrottle.API do
@moduledoc """
This library provides wrapper functions for the Slack Web API and
automatically throttles all requests to it according to API rate limits.
## Usage
Look up the API method you want to use in the
[Slack documentation](https://api.slack.com/methods). Function names are
method names with dots replaced by underscores:
# method: channels.info
iex> SlackThrottle.API.channels_info("some token", %{channel: "C123456"})
%{"ok" => true, "channel" => %{"id" => "C123456", ...}}
If you don't care about the response, e.g. when broadcasting a message,
use `:cast` as the third argument:
# method: chat.postMessage
iex> SlackThrottle.API.chat_postMessage("some token", params, :cast)
:ok
Broadcasts are executed asynchronously and return `:ok` immediately.
## Rate Limits
The Slack Web API is subject to
[rate limiting](https://api.slack.com/docs/rate-limits). Requests are only
allowed at a rate of one per second on a per-access-token basis.
To comply with these restrictions, the library queues all function calls
(grouped by access token) and executes them at the given rate. These queues
are priority queues: Regular blocking function calls have higher priority than
asynchronous broadcasts (the `:cast` ones).
## Configuration
The API throttle rate `:api_throttle` can be configured as well as the
timeout for blocking function calls `:enqueue_sync_timeout`:
config :slack_throttle,
api_throttle: 1000, # in milliseconds
enqueue_sync_timeout: 20000 # in milliseconds
"""
alias SlackThrottle.HTTP
[
"auth.revoke",
"auth.test",
"bots.info",
"channels.archive",
"channels.close",
"channels.create",
"channels.createChild",
"channels.history",
"channels.info",
"channels.invite",
"channels.kick",
"channels.leave",
"channels.list",
"channels.mark",
"channels.open",
"channels.rename",
"channels.replies",
"channels.setPurpose",
"channels.setTopic",
"channels.unarchive",
"chat.delete",
"chat.meMessage",
"chat.postMessage",
"chat.update",
"dnd.info",
"dnd.teamInfo",
"emoji.list",
"files.comments.add",
"files.comments.delete",
"files.comments.edit",
"files.delete",
"files.info",
"files.list",
"files.revokePublicURL",
"files.sharedPublicURL",
"files.upload",
"groups.archive",
"groups.close",
"groups.create",
"groups.createChild",
"groups.history",
"groups.info",
"groups.invite",
"groups.kick",
"groups.leave",
"groups.list",
"groups.mark",
"groups.open",
"groups.rename",
"groups.replies",
"groups.setPurpose",
"groups.setTopic",
"groups.unarchive",
"im.close",
"im.history",
"im.list",
"im.mark",
"im.open",
"im.replies",
"mpim.close",
"mpim.history",
"mpim.list",
"mpim.mark",
"mpim.open",
"mpim.replies",
"pins.add",
"pins.list",
"pins.remove",
"reactions.add",
"reactions.get",
"reactions.list",
"reactions.remove",
"reminders.add",
"reminders.complete",
"reminders.delete",
"reminders.info",
"reminders.list",
"rtm.start",
"search.all",
"search.files",
"search.messages",
"stars.add",
"stars.list",
"stars.remove",
"team.accessLogs",
"team.billableInfo",
"team.info",
"team.integrationLogs",
"team.profile.get",
"usergroups.create",
"usergroups.disable",
"usergroups.enable",
"usergroups.list",
"usergroups.update",
"usergroups.users.list",
"usergroups.users.update",
"users.deletePhoto",
"users.getPresence",
"users.identity",
"users.info",
"users.list",
"users.setActive",
"users.setPhoto",
"users.setPresence",
"users.profile.get",
"users.profile.set",
]
|> Enum.each(fn method ->
fun = method |> String.replace(".", "_") |> String.to_atom
@doc """
[#{method}](https://api.slack.com/methods/#{method})
"""
@spec unquote(fun)(binary, %{atom => any}, :call | :cast) ::
%{binary => any} | :ok
def unquote(fun)(token, params \\ %{}, type \\ :call) do
HTTP.fetch(token, unquote(method), params, type)
end
end)
[
"api.test",
"oauth.access"
]
|> Enum.each(fn method ->
fun = method |> String.replace(".", "_") |> String.to_atom
@doc """
[#{method}](https://api.slack.com/methods/#{method})
"""
@spec unquote(fun)(%{atom => any}) :: %{binary => any}
def unquote(fun)(params \\ %{}) do
params = Map.to_list(params)
res = HTTP.get!(unquote(method), HTTP.headers, [params: params])
res.body
end
end)
end