1. About
The Spring Slack applies Spring conventions to Slack’s Bolt API library. This enables applications to quickly bootstrap Slack integrations with Spring Boot. Instead of defining a single bean for a Slack app configuration with all functionality contained within it, Bolt handler classes may instead be created as beans for better separation of concerns with all the power that the Spring framework provides.
The Spring Slack library is primarily concerned with configuring and bootstrapping Slack integrations and utilizes as much of the underlying Bolt classes and interfaces as possible. Therefore, it not the goal of this document to describe the specifics or usage of the Slack Java/Bolt SDK itself.
| You can find the Slack Java SDK guide at https://slack.dev/java-slack-sdk/. |
Likewise, as a Spring Boot library, it is assumed that users of this library are familiar with the concepts of Spring and Spring Boot.
2. Core
The core library contains all the necessary logic to bootstrap a Slack App object.
The App object is responsible for receiving events from the Slack service and handing them off to a handler object, if one has been configured for that type of event.
The App object is itself not responsible for connecting to or listening for events from the Slack service, and other libraries are available that implement the sever components of a completed Slack integration.
| See the Server section for details on how to implement the server aspects of Slack integration. |
2.1. Installing
The core library may be added to a project’s build through the use of Gradle or Maven as noted below.
implementation('com.heb:spring-slack-core:2.0.0')
<dependency>
<groupId>com.heb</groupId>
<artifactId>spring-slack-core</artifactId>
<version>2.0.0</version>
</dependency>
2.2. Configuring
Configuration of the Slack library follows Spring conventions, and may be configured in any manner that Spring supports to ingest configuration data.
Most configuration properties for the core Slack library are prefixed under the slack top-level key.
The following core configuration properties are available.
Property |
Required |
Default |
Description |
|
Yes |
N/A |
The Bot User OAuth Token generated for the Slack app when it is added to the workspace. |
|
No |
|
Maximum number of threads to allocate to incoming Slack events. |
2.3. Defining Handlers
Handler classes are provided by Slack’s Bolt API for various types of incoming events that Slack integrations rely on to provide custom handling of actions taken within Slack.
The Spring Slack library utilizes these same handler classes, just as if the application was registering handlers with the App object directly.
Defining a Slack handler is as simple as creating a Spring bean of the appropriate handler type, and supported handler types are discovered when the application is bootstrapped and automatically registered with the App instance.
2.3.1. Registration
Handlers typically require some criteria when being registered with the App.
Handler interface types themselves do not provide this criteria.
Instead, this library sources the registration criteria from Slack handler beans via annotations that provide the registration metadata.
The type of annotation required from a handler depends on the type of the handler.
All Slack registration annotations also mark the class as a @Component.
|
String Registration
Certain handlers may be registered with a string criteria.
In these cases, the @SlackStringRegistration annotation may be used with the handler implementation.
The annotation requires a string value, which is the string that will be used to register the handler with the Slack App instance.
2.3.2. Supported Handlers
The following handler types are supported, and the registration requirements are listed for each type.
| Only one registration type is required, and applications may choose which is desired if multiple are supported. |
Handler Type |
String |
Pattern |
Event |
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
||
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
|||
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
|
|
✔ |
✔ |
| More information about these handlers and their uses cases may be found in the Bolt guide. |
2.3.3. Example Handler
The following example implements an event handler specific to Slack app mention events. The logic contained within it is simplistic. However, as Spring beans, handlers may use any of the functionality provided by Spring ecosystem to service Slack events.
@SlackEventRegistration(AppMentionEvent.class)
public class ExampleMentionHandler implements BoltEventHandler<AppMentionEvent> {
public Response apply(EventsApiPayload<AppMentionEvent> event, EventContext context) {
return context.ack("Hello!");
}
}
2.4. Custom Configuration
The central responsibility of the core library is to configure and expose a Slack App object as a Spring bean.
While handlers and middleware are auto-discovered and applied, additional configuration of the App may be desired.
The library configures App instances via special beans that implement the SlackAppConfigurer interface.
Instances of this interface are provided an App instance to be configured as applications require.
In fact, all functionality to auto-discover Slack handler objects, middleware, and even configuration from the application’s configuration properties are applied through bundled implementations of SlackAppConfigurer.
As an example, to disable the SSL check, a configurer may be created as follows:
@Component
public class SslDisableConfigurer implements SlackAppConfigurer {
public void configure(App app) {
app.config().setSslCheckEnabled(false);
}
}
Additionally, the SlackAppConfigurer interface is functional.
The above example might look like the following if the configurer is defined in a Spring @Configuration class as a @Bean method.
@Configuration
public class ExampleConfiguration {
@Bean
SlackAppConfigurer sslDisableConfigurer() {
return app -> app.config().setSslCheckEnabled(false);
}
2.5. Manual Configuration
The SlackAppProvider bean is the core component responsible for creating and configuring a Slack App instance.
The default implementation provided by the library aggregates all instances of SlackAppConfigurer beans to configure the App instance, and is responsible for applying each configurer when the application starts.
The SlackAppProvider bean may be replaced by applications with custom implementations of the interface.
Authors may use this functionality to gain full control over the creation and configuration of an App instance.
Unless custom SlackAppProvider implementations explicitly include functionality to utilize SlackAppConfigurer beans, auto-discovery of handlers will not occur.
|
As an example, the following provider sets up the App object with a single slash command handler.
@Component
public class CustomAppProvider {
public App get() {
App app = new App();
app.command("hello", (req, ctx) -> {
return ctx.ack("Hello!");
});
return app;
}
}
While overriding this bean loses much of the benefit of using this library, the web and socket-mode libraries may still be used to manage the service lifecycle and the API clients are still available as beans for use in the rest of the application.
3. Server
While the Slack App object handles routing requests from the Slack service to handlers that process those requests, it does not dictate a server implementation that actually receives requests over a network.
There are two server implementations available, and the library extensions provided by this library make it trivial to set up the server.
3.1. Web
The web library enables a Slack integration to ingest requests from Slack over an HTTP connection.
Using incoming HTTP requests has the benefit of making the application less stateful.
The web library is very lightweight, and merely exposes Bolt’s SlackAppServlet as a servlet under the /slack/events context path.
| To use the web library, applications must be able to accept connections from Slack over the internet. If the application cannot be reached from the internet, use the Socket server library instead. |
No configuration of the library is required, and simply including this library enables the Slack app to be served as an HTTP app that is able to receive incoming Slack events over the web.
| This library includes the core library as a transitive dependency, and the core library does not need to be explicitly added to your project. |
3.1.1. Installing
The web library may be added to a project’s build through the use of Gradle or Maven as noted below.
implementation('com.heb:spring-slack-web:2.0.0')
<dependency>
<groupId>com.heb</groupId>
<artifactId>spring-slack-web</artifactId>
<version>2.0.0</version>
</dependency>
3.2. Socket
Applications that live behind a firewall or are otherwise inaccessible from the internet (and Slack services) may instead opt to interact with the Slack service through the use of a socket. Instead of Slack making HTTP calls to applications, events will be sent over this persistent socket connection.
The socket mode library configures the Spring app to create the socket connection when the application starts. As with the web library, this library is very lightweight. However, there is a minimum of configuration required for socket mode to function.
3.2.1. Installing
The socket mode library may be added to a project’s build through the use of Gradle or Maven as noted below.
implementation('com.heb:spring-slack-socket:2.0.0')
<dependency>
<groupId>com.heb</groupId>
<artifactId>spring-slack-socket</artifactId>
<version>2.0.0</version>
</dependency>
| This library includes the core library as a transitive dependency, and the core library does not need to be explicitly added to your project. |
3.2.2. Configuring
A Slack app that wishes to use a socket connection must be configured through the Slack API web console as a socket mode application. When the application is enabled as a socket mode app, Slack generates an app token, which is used to authenticate socket connections.
In order to create the socket connection when the Spring application starts, the app token must be configured under the slack.single-team-token configuration property.
Once configured with the app token, no other setup or configuration is required.
4. API Client
Slack has a rich API available to perform actions within Slack, such as posting messages to a channel, uploading files, etc.
The Slack Java SDK contains API bindings that make it much simpler to interact with this API.
The MethodsClient class exposes these bindings and is available as a Spring bean.
The Spring Slack library also contains a SlackClientHelper bean with several methods available for common use cases.
While the MethodsClient uses a very straight-forward builder syntax to build requests, the helper methods provide a much more concise syntax for operations where high granularity is not required.
Slack also offers an asynchronous API binding called AsyncMethodsClient.
This version contains the same API methods and is called the same way as its synchronous counterpart.
However, instead of returning response objects, Java Future objects that will provide response objects are returned.
To support the helper functionality provided by SlackClientHelper, an asynchronous version with type AsyncSlackClientHelper also exists.
Both the AsyncMethodsClient and AsyncSlackClientHelper are exposed as beans.
| The asynchronous implementations of the API clients are useful in scenarios where non-blocking I/O is desired. |
5. Spring Security
While the bulk of the Spring Slack library focuses on providing glue between Spring Boot and the Slack Java/Bolt SDK, some amount of Spring Security integration is also provided in the core library.
Security configuration needs are very specific to the concrete application and this library makes no attempt to impose a security configuration or assumptions on applications. It does, however, provide a couple of beans that may be used in a Spring Security configuration if desired to ease authentication of Slack users.
To enable Spring Security support provided by the core library, applications must include the Spring Security libraries on the classpath.
If Spring Security is present but the Slack-specific beans are not required, the configuration property slack.security.enabled property may be set to false.
|
5.1. Auth Provider
If the conditions for the security beans are met, an instance of SlackAuthProvider will be available as a bean.
This auth provider may be used when configuring the authentication manager.
The Slack auth provider accepts any Authentication token type, and assumes that the principal of the token is a user’s Slack ID.
If the provider is able to successfully authenticate a Slack user, a SlackAuthentication will represent the authenticated user, and the token’s principal will be an instance of SlackUser.
If the auth provider is unable to authenticate the user, it will instead return an AnonymousAuthenticationToken.
5.2. User Details Service
The SlackAuthProvider utilizes a SlackUserDetailsService bean that implements the logic of lookup up users by their Slack ID.
5.2.1. Config-Based User Lookup
The default implementation of SlackUserDetailsService utilizes application configuration properties to map Slack user IDs to a set of authorities.
Users are configured under the slack.security.users key.
This is a mapped key, where the next key is the Slack ID of a user, and additional properties underneath the users pertain to that user.
The following examples should illustrate how to configure users who will be authenticated.
slack.security.users.U12345.authorities=ROLE_FOO,ROLE_BAR (1) (2)
| 1 | U12345 is an example Slack user ID. |
| 2 | The authorities list is formatted as comma separated values. |
slack:
security:
users:
U12345: (1)
authorities: (2)
- ROLE_FOO
- ROLE_BAR
external-user-id: cool.joe (3)
| 1 | U12345 is an example Slack user ID.
The ID may be retrieved through Slack. |
| 2 | A list of Spring Security roles to assign to the user. |
| 3 | An optional user ID that maps to some external repository, like an LDAP server. |
5.2.2. Custom User Lookup
If an application requires the security scheme provided by the library, but needs to look users up by some means other than a configuration file (e.g. database, etc), applications may provide their own implementations of SlackUserDetailsService.
Custom implementations of this interface will take precedence over the bundled, config-based implementation.
6. Changelog
- 2.0.0
-
-
Migrated project to be compatible with Spring Boot 3.x. This breaks compatibility with previous versions of Spring Boot.
-
Migrated project to JDK 17. Note that since
javaxpackages have been migrated tojakarta, older versions of Java are no longer supported. -
Updated several underlying libraries.
-
- 1.1.0
-
-
Add external-user-id property to slack user config.
-
- 1.0.3
-
-
Update Spring Boot to version 2.6.9 to remediate Spring4Shell vulnerability.
-
- 1.0.2
-
-
Fix another issue with build/deploy CI that prevented automatic Git tags from working.
-
- 1.0.1
-
-
Fix an issue with the build/deploy CI pipeline that prevented automatic Git tags from working.
-
- 1.0.0
-
-
Initial version of the Spring Slack library collection.
-