• Stars
    star
    673
  • Rank 64,902 (Top 2 %)
  • Language
    Elixir
  • License
    MIT License
  • Created over 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Slack real time messaging and web API client in Elixir

Elixir-Slack

Elixir CI Module Version Hex Docs Total Download License Last Updated

This is a Slack Real Time Messaging API client for Elixir. You'll need a Slack API token which can be retrieved by following the Token Generation Instructions or by creating a new bot integration.

Installing

Add :slack to your mix.exs dependencies function:

def application do
  [
    extra_applications: [:logger]
  ]
end

def deps do
  [
    {:slack, "~> 0.23.6"}
  ]
end

Upgrading from 0.x to 0.20+

The newest version of the Slack client introduces breaking changes with regards to starting and connecting to the Real Time Messaging API. rtm.start is now deprecated and has since been replaced with rtm.connect. This has removed the list of bots, channels, groups, users, and ims that are normally returned from rtm.start. Additionally, these lists are now rate-limited. In order to achieve relative parity to the old way of doing things, you'll need to make one change in your code:

Make additional calls to the Slack API to fetch bots, channels, groups, users, and IMs

Wherever you grab the passed in slack state, add in additional calls to populate these lists:

slack
|> Map.put(:bots, Slack.Web.Bots.info(%{token: token}) |> Map.get("bot"))
|> Map.put(:channels, Slack.Web.Channels.list(%{token: token}) |> Map.get("channels"))
|> Map.put(:groups, Slack.Web.Groups.list(%{token: token}) |> Map.get("groups"))
|> Map.put(:ims, Slack.Web.Im.list(%{token: token}) |> Map.get("ims"))
|> Map.put(:users, Slack.Web.Users.list(%{token: token}) |> Map.get("members"))

Real Time Messaging (RTM) Bot Usage

Define a module that uses the Slack behaviour and defines the appropriate callback methods.

defmodule SlackRtm do
  use Slack

  def handle_connect(slack, state) do
    IO.puts "Connected as #{slack.me.name}"
    {:ok, state}
  end

  def handle_event(message = %{type: "message"}, slack, state) do
    send_message("I got a message!", message.channel, slack)
    {:ok, state}
  end
  def handle_event(_, _, state), do: {:ok, state}

  def handle_info({:message, text, channel}, slack, state) do
    IO.puts "Sending your message, captain!"

    send_message(text, channel, slack)

    {:ok, state}
  end
  def handle_info(_, _, state), do: {:ok, state}
end

To run this example, you'll want to call Slack.Bot.start_link(SlackRtm, [], "TOKEN_HERE") and run the project with mix run --no-halt.

You can send messages to channels using send_message/3 which takes the message as the first argument, channel/user as the second, and the passed in slack state as the third.

The passed in slack state holds the current user properties as me, team properties as team, and the current websocket connection as socket.

If you want to do things like trigger the sending of messages outside of your Slack handlers, you can leverage the handle_info/3 callback to implement an external API.

This allows you to both respond to Slack RTM events and programmatically control your bot from external events.

{:ok, rtm} = Slack.Bot.start_link(SlackRtm, [], "token")
send rtm, {:message, "External message", "#general"}
#=> {:message, "External message", "#general"}
#==> Sending your message, captain!

Slack has a lot of message types so it's a good idea to define a callback like above where unhandled message types don't crash your application. You can find a list of message types and examples on the RTM API page.

You can find more detailed documentation on the Slack hexdocs page.

Web API Usage

The complete Slack Web API is implemented by generating modules/functions from the JSON documentation. You can view this project's documentation for more details.

There are two ways to authenticate your API calls. You can configure api_token on slack that will authenticate all calls to the API automatically.

config :slack, api_token: "VALUE"

Alternatively you can pass in %{token: "VALUE"} to any API call in optional_params. This also allows you to override the configured api_token value if desired.

Quick example, getting the names of everyone on your team:

names = Slack.Web.Users.list(%{token: "TOKEN_HERE"})
|> Map.get("members")
|> Enum.map(fn(member) ->
  member["real_name"]
end)

Web Client Configuration

A custom client callback module can be configured for cases in which you need extra control over how calls to the web API are performed. This can be used to control timeouts, or to add additional custom error handling as needed.

config :slack, :web_http_client, YourApp.CustomClient

All Web API calls from documentation-generated modules/functions will call post!/2 with the generated url and body passed as arguments.

In the case where you only need to control the options passed to HTTPoison/hackney, the default client accepts a keyword list as an additional configuration parameter. Note that this is ignored if configuring a custom client.

See HTTPoison docs for a list of available options.

config :slack, :web_http_client_opts, [timeout: 10_000, recv_timeout: 10_000]

Testing

For integration tests, you can change the default Slack URL to your fake Slack server:

config :slack, url: "http://localhost:8000"

Copyright and License

Copyright (c) 2014 Blake Williams

Source code is released under the MIT license.

More Repositories

1

doorman

Tools to make Plug, and Phoenix authentication simple and flexible.
Elixir
119
star
2

rails-plug

An Elixir plug to make your application performance more in line with Rails.
Elixir
90
star
3

pact

Better dependency injection in Elixir
Elixir
76
star
4

envy

dotenv like easy loading of environment variables in Elixir
Elixir
70
star
5

remote-development-manager

tooling that makes development easier in remote environments like ssh and codespaces
Go
34
star
6

dotfiles

My dotfiles. Decently documented.
Vim Script
28
star
7

ember-phoenix-adapter

An Ember / Ember-CLI adapter for websockets via Phoenix channels.
JavaScript
24
star
8

b-r-o-w-s-e

multiple browsers made simple through complexity
Go
17
star
9

viewproxy

Experimental Go service for parallelizing application code
Go
12
star
10

vim-pry

Quickly insert debugger statements into your buffer based on filetype.
Vim Script
10
star
11

slack_markov

Make a markov chain bot using a person's Slack history
Rust
7
star
12

bat

Intuitive templating engine for Go
Go
6
star
13

Straws

PHP framework based on Sinatra.
PHP
6
star
14

backbone_handlebars

Backbone + Handlebars for Rails with template precompilation
Ruby
6
star
15

lull

slack client but chill
TypeScript
5
star
16

prettyrb

Experimental Ruby code formatter
Ruby
5
star
17

medium

Experimental Go code for writing web apps.
Go
4
star
18

vim-tbro

A plugin for vim's bro, tmux.
Vim Script
4
star
19

coin-tracker

Hacky Electron project for viewing cryptocurrency prices in your menu bar
JavaScript
4
star
20

CleverSlack

A Slack <-> Cleverbot bridge, technically a clever Slack bot?
Elixir
4
star
21

newred

An open source reddit client for iOS built with React native.
JavaScript
3
star
22

triplet

Simple, experimental HTML DSL for Ruby
Ruby
3
star
23

straw

WIP progress Rust -> HTML largely as a learning exercise
Rust
3
star
24

Elixir-Cleverbot

Simple implementation of the Cleverbot API in Elixir
Elixir
3
star
25

numetal.vim

a color scheme for people who like numetal, or don't. idk
Vim Script
3
star
26

OSHA

Occupational Safety and Health Automation
Ruby
3
star
27

Elixir-Stripe

A work in progress wrapper around the Stripe API in Elixir.
Elixir
3
star
28

Minican

Miniature authorization for Rails inspired by Cancan and Pundit.
Ruby
3
star
29

MoonBot

IRC Bot Framework that runs entirely via plugins.
Ruby
2
star
30

markov-slack

a go slack bot for mimicking a target user
Go
2
star
31

nsa

Sketchy words on the command line.
Rust
2
star
32

rust-brainfuck

Work in progress brainfuck interpreter written in Rust. It's not the best code, but it's getting there!
Rust
2
star
33

noop

challenges from https://noopschallenge.com/
Vim Script
2
star
34

fernet

Simple Go web framework that uses generics for safer data sharing between middleware, router, and handlers
Go
2
star
35

octodomain

Mapping between ActiveRecord models to domain objects.
Ruby
2
star
36

Construction-Page

A construction page using only HTML that works on all devices.
2
star
37

Bendy

Bendy CSS framework for making your site work flawlessly with any mobile device.
2
star
38

go-reloader

A simple live-reloader package for Go.
Go
2
star
39

emojify

Emojify text in Go
Go
2
star
40

statuslight

Vim plugin for light weight statuslines.
Vim Script
1
star
41

JustBot

A Slack bot that asks the most important questions.
Elixir
1
star
42

UPS

UPS Shipping Label gem.
Ruby
1
star
43

component_embedded_ruby

Strict Ruby templates with component support
Ruby
1
star
44

exec_trace

C
1
star
45

clint-eastwood

A very work in progress Pokerbot
Elixir
1
star
46

easyslog

EasySlog is an easier way to implement formatters for Go slog handlers
Go
1
star
47

go-base36

A base36 encoder/decoder for int64 values in Go
Go
1
star
48

Headquarters

Lean project management powered by Rails and Ember.js
Ruby
1
star
49

HQ

Headquarters project management app used to learn/play/experiment with Ember.js
Ruby
1
star
50

cursed

typescript web framework ecosystem
TypeScript
1
star
51

advent-of-code-2017

http://adventofcode.com/2017
Ruby
1
star
52

view_proxy_demo

Demo application for view proxy
Ruby
1
star
53

Clojure-Brainfuck

My first attempt at a brainfuck interpreter and used it to learn a bit more about Clojure.
Clojure
1
star
54

view_component-rails-test

Testing ground for view_component + Rails
Ruby
1
star
55

delivery

Quick and simple app to create email groups that match an email address then forward the email to all email addresses in that group.
Ruby
1
star