Skip to content

A scala library for interacting with the slack api and real time messaging interface

License

Notifications You must be signed in to change notification settings

qualiton/slack-scala-client

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

slack-scala-client

Build Status

A Scala library for interacting with the Slack API and real time messaging interface

Installation

⚠️ Starting from version 0.2.4 (released on Nov 9 2018) there's a new Maven group id - update your build file configurations (pom.xml etc.). Also the project homepage has been moved to a new Github organization - thus is available at a new URL (as you can see).

SBT

Add SBT dependency:

libraryDependencies += "com.github.slack-scala-client" %% "slack-scala-client" % "0.2.4"

Maven

Scala 2.12:

    <dependency>
        <groupId>com.github.slack-scala-client</groupId>
        <artifactId>slack-scala-client_2.12</artifactId>
        <version>0.2.4</version>
    </dependency>

Scala 2.11:

    <dependency>
        <groupId>com.github.slack-scala-client</groupId>
        <artifactId>slack-scala-client_2.11</artifactId>
        <version>0.2.4</version>
    </dependency>

Scaladoc

API Client Usage

There are two different API clients, one exposing an asynchronous interface and the other exposing a synchronous interface. They can be imported from the slack.api package:

import slack.api.SlackApiClient          // Async
import slack.api.BlockingSlackApiClient  // Blocking

Creating an instance of either client simply requires passing in a Slack api token:

val token = "<Your Token Here>"
val client = SlackApiClient(token)

Calling any api functions requires an implicit ActorSystem... one can be created simply:

implicit val system = ActorSystem("slack")

The async client returns futures as the result of each of its API functions:

val client = SlackApiClient(token)
val res = client.listChannels() // => Future[Seq[Channel]]

res.onComplete {
    case Success(channels) =>  //...
    case Failure(err) => // ...
}

...while the blocking client will block the current thread until the API response has been received:

val client = BlockingSlackApiClient(token)  // Default timeout of 5 seconds
val channels = client.listChannels()  // => Seq[Channel]

The API clients implement the full Slack API. A full list of the available endpoints can be found directly on the classes: SlackApiClient and BlockingSlackApiClient

RTM Client Usage

The real time messaging client is implemented using akka and requires having an implicit ActorSystem in scope. Either an ActorSystem or ActorContext will work:

import slack.rtm.SlackRtmClient
import akka.actor.ActorSystem

implicit val system = ActorSystem("slack")

Creating an instance of the RTM client requires an API token, just like the API clients:

val token = "<Your Token Here>"
val client = SlackRtmClient(token)

Based on the stream of events coming in, the client maintains active state that contains things like channels and users. It can also be used to look up the ID of a user or channel by name:

val state = client.state
val selfId = state.self.id
val chanId = state.getChannelIdForName("general") // => Option[String]

Sending a message is pretty simple:

val generalChanId = state.getChannelIdForName("general").get
client.sendMessage(generalChanId, "Hello!")

Messages can be received very simply as well:

client.onMessage { message =>
    println(s"User: ${message.user}, Message: ${message.text}")
}

Additionally, the client can be used to receive any event sent from Slack:

client.onEvent {
    case e: Message => ...
    case e: UserTyping => ...
    case e: ChannelDeleted => ...
}

A full list of events can be found in Events.scala. One thing to note is the two above functions return an ActorRef which is a handle to the underlying actor running the above handler function. This can be used to terminate the handler by terminating the actor: system.stop(handler), or unregistering it as a listener: client.removeEventListener(handler)

An Akka actor can be manually registered as an event listener and all events will be sent to that actor:

val actor = system.actorOf(Props[SlackEventHandler])
client.addEventListener(actor)
// Time Passes...
client.removeEventListener(actor)

Finally, an RTM client can easily be terminated and cleaned up by calling close:

client.close()

Simple Bot Example

This is a full implementation of a Slack bot that will listen for anyone mentioning it in a message and will respond to that user.

val token = "..."
implicit val system = ActorSystem("slack")
implicit val ec = system.dispatcher

val client = SlackRtmClient(token)
val selfId = client.state.self.id

client.onMessage { message =>
  val mentionedIds = SlackUtil.extractMentionedIds(message.text)

  if(mentionedIds.contains(selfId)) {
    client.sendMessage(message.channel, s"<@${message.user}>: Hey!")
  }
}

WebSocket Re-Connection Behavior

Since 0.2.4 the library sends a ping message to Slack every minute. Pong message is received (but not checked upon). That is to sustain a Slack websocket connection even if idle - see Slack doc for ping and pong.

Previously the library caused the client to reconnect every 1 or 2 minute with the following messages:

[WebSocketClientActor] WebSocket disconnected.
[SlackRtmConnectionActor] WebSocket Client disconnected, reconnecting
[SlackRtmConnectionActor] Starting web socket client

Caveat Emptor

  • The Slack API contains a lot methods and not every implemented API method has been executed (i.e. some may not work; pull requests accepted!)
  • Responses to RTM messages sent out are not currently checked to verify they were successfully received (Coming Soon!)
  • Investigate a way to ensure all missed messages are received during a disconnection
  • A small number of response types have yet to be fleshed out

Changelog

Changelog can be found here

About

A scala library for interacting with the slack api and real time messaging interface

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Scala 100.0%