### Clone and Run Quarkus Example
Source: https://github.com/slackapi/java-slack-sdk/blob/main/bolt-quarkus-examples/README.md
Steps to clone the repository, install dependencies, and run the Quarkus example in development mode. Includes setting up ngrok for external access.
```bash
git clone git@github.com:slackapi/java-slack-sdk.git
cd java-slack-sdk/
mvn install -Dmaven.test.skip=true
mvn -pl bolt-quarkus-examples compile quarkus:dev
ngrok http 3000
```
--------------------------------
### Maven Command to Run Example
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-client-setup.md
Execute this command in your terminal to compile and run the Example.main method, verifying your installation.
```bash
mvn compile exec:java \
-Dexec.cleanupDaemonThreads=false \
-Dexec.mainClass="Example"
```
--------------------------------
### Initialize and Start Socket Mode App with Java-WebSocket
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/socket-mode.md
This example demonstrates how to initialize a SocketModeApp using the Java-WebSocket backend and start the connection. Ensure the Java-WebSocket library is added as a dependency.
```java
String appToken = "xapp-";
App app = new App();
SocketModeApp socketModeApp = new SocketModeApp(
appToken,
SocketModeClient.Backend.JavaWebSocket,
app
);
socketModeApp.start();
```
--------------------------------
### Install and Run Slack API Client Tests
Source: https://github.com/slackapi/java-slack-sdk/blob/main/AGENTS.md
Installs all modules locally and then runs specific tests for the slack-api-client module. Note that failures in unrelated modules during installation are acceptable.
```bash
./scripts/install_local.sh
```
```bash
./mvnw test -pl slack-api-client '-Dtest=test_locally.api.methods.AppsTest,test_locally.api.MethodsTest'
```
--------------------------------
### Helidon App Startup Output
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
Example output from the `stdout` when the Helidon SE Bolt app starts successfully, indicating the server and Bolt app are running.
```bash
[main] io.helidon.webserver.NettyWebServer Version: helidonVersion
[nioEventLoopGroup-2-1] io.helidon.webserver.NettyWebServer Channel '@default' started: [id: 0x9fcf416d, L:/0:0:0:0:0:0:0:0:3000]
[nioEventLoopGroup-2-1] com.slack.api.bolt.helidon.SlackAppServer ⚡️ Bolt app is running!
```
--------------------------------
### Build Quarkus Example JAR
Source: https://github.com/slackapi/java-slack-sdk/blob/main/bolt-quarkus-examples/README.md
Instructions to package the Quarkus Bolt example into an executable JAR file and run it.
```bash
mvn -pl bolt-quarkus-examples package
java -jar bolt-quarkus-examples/target/bolt-quarkus-examples-*-runner.jar
```
--------------------------------
### Configure Custom Installation and OAuth Services
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/app-distribution.md
Implement custom `InstallationService` and `OAuthStateService` using Spring Beans, for example, by leveraging Amazon S3 for storage. This allows for more control over how installation data and OAuth states are managed.
```java
public class SlackApp {
// Please be careful about the security policies on this bucket.
private static final String S3_BUCKET_NAME = "your-s3-bucket-name";
@Bean
public InstallationService initInstallationService() {
InstallationService installationService = new AmazonS3InstallationService(S3_BUCKET_NAME);
installationService.setHistoricalDataEnabled(true);
return installationService;
}
@Bean
public OAuthStateService initStateService() {
return new AmazonS3OAuthStateService(S3_BUCKET_NAME);
}
@Bean
public App initSlackApp(InstallationService installationService, OAuthStateService stateService) {
App app = new App().asOAuthApp(true);
app.service(installationService);
app.service(stateService);
return app;
}
}
```
--------------------------------
### Logback configuration example
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/bolt-basics.md
Example XML configuration for logback-classic to set up logging appenders and root level.
```xml
%date %level [%thread] %logger{64} %msg%n
```
--------------------------------
### Bolt App with API and OAuth Handlers
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/app-distribution.md
This example demonstrates setting up a Bolt app to handle both standard Slack API requests (like commands) and the OAuth flow for app installation. Ensure all required environment variables are set for each app instance.
```java
import com.slack.api.bolt.App;
import com.slack.api.bolt.jetty.SlackAppServer;
import java.util.HashMap;
import java.util.Map;
import static java.util.Map.entry;
// API Request Handler App
// expected env variables:
// SLACK_SIGNING_SECRET
App apiApp = new App();
apiApp.command("/hi", (req, ctx) -> {
return ctx.ack("Hi there!");
});
// OAuth Flow Handler App
// expected env variables:
// SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, SLACK_REDIRECT_URI, SLACK_SCOPES,
// SLACK_INSTALL_PATH, SLACK_REDIRECT_URI_PATH
// SLACK_OAUTH_COMPLETION_URL, SLACK_OAUTH_CANCELLATION_URL
App oauthApp = new App().asOAuthApp(true);
// Mount the two apps with their root path
SlackAppServer server = new SlackAppServer(new HashMap<>(Map.ofEntries(
entry("/slack/events", apiApp), // POST /slack/events (incoming API requests from the Slack Platform)
entry("/slack/oauth", oauthApp) // GET /slack/oauth/start, /slack/oauth/callback (user access)
)));
server.start(); // http://localhost:3000
```
--------------------------------
### Install Slack API Client Modules Locally
Source: https://github.com/slackapi/java-slack-sdk/blob/main/AGENTS.md
Before running tests, install all modules locally using `mvn install` to ensure dependencies are met, especially when `slack-api-client` depends on `slack-api-model`.
```bash
mvn install
```
--------------------------------
### Java RTM Client Example
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/rtm.md
This example demonstrates initializing the RTM client, connecting to Slack, handling events, sending messages, and managing the WebSocket connection. It requires a `SLACK_BOT_TOKEN` environment variable.
```java
import com.slack.api.Slack;
import com.slack.api.model.event.UserTypingEvent;
import com.slack.api.rtm.*;
import com.slack.api.rtm.message.*;
// Dispatches incoming message events from RTM API
RTMEventsDispatcher dispatcher = RTMEventsDispatcherFactory.getInstance();
// Register a event handler runtime
RTMEventHandler userTyping = new RTMEventHandler() {
@Override
public void handle(UserTypingEvent event) {
// do something here
}
};
dispatcher.register(userTyping);
String botToken = System.getenv("SLACK_BOT_TOKEN");
Slack slack = Slack.getInstance();
// Initialize the client with a valid WSS URL
RTMClient rtm = slack.rtmConnect(botToken);
// Establish a WebSocket connection and start subscribing Slack events
rtm.connect();
// Enable an event dispatcher
rtm.addMessageHandler(dispatcher.toMessageHandler());
// Deregister a event handler runtime
dispatcher.deregister(userTyping);
// Send messages over a WebSocket connection
String channelId = "C1234567";
String message = Message.builder().id(1234567L).channel(channelId).text(":wave: Hi there!").build().toJSONString();
rtm.sendMessage(message);
// To subscribe "presence_change" events
String userId = "U1234567";
String presenceQuery = PresenceQuery.builder().ids(Arrays.asList(userId)).build().toJSONString();
rtm.sendMessage(presenceQuery);
String presenceSub = PresenceSub.builder().ids(Arrays.asList(userId)).build().toJSONString();
rtm.sendMessage(presenceSub);
// A bit heavy-weight operation to re-establish a WS connection for sure
// Don't call this method frequently - it will result in a rate-limited error
rtm.reconnect();
// Disconnect from Slack - #close() method does the same
rtm.disconnect();
```
--------------------------------
### Install all modules locally
Source: https://github.com/slackapi/java-slack-sdk/blob/main/AGENTS.md
Install all project modules into the local Maven repository, skipping tests.
```bash
# Install all modules locally (skips tests)
./scripts/install_local.sh
```
--------------------------------
### Initialize Slack SDK
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-basics.md
Instantiate the Slack SDK with default configuration. This is the starting point for all SDK operations.
```java
import com.slack.api.Slack;
import com.slack.api.SlackConfig;
SlackConfig config = new SlackConfig();
Slack slack = Slack.getInstance(config);
```
--------------------------------
### Start Micronaut Application
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
Command to start your Micronaut application using Maven.
```bash
[main] INFO io.micronaut.runtime.Micronaut - Startup completed in 1321ms. Server Running: http://localhost:3000
```
--------------------------------
### Configure App and Handle Slash Command
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/bolt-basics.md
Initialize the `App` class and register a handler for a slash command. This is a basic setup for responding to user commands.
```java
import com.slack.api.bolt.App;
App app = new App();
app.command("/echo", (req, ctx) -> {
return ctx.ack(req.getText());
});
```
--------------------------------
### Quarkus Development Mode Output
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
Example stdout output when a Quarkus application starts in development mode, indicating successful startup and enabled features.
```text
[INFO] --- quarkus-maven-plugin:quarkusVersion:dev (default-cli) @ code-with-quarkus ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /path-to-projet/target/classes
Listening for transport dt_socket at address: 5005
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
INFO [io.quarkus] (main) code-with-quarkus 1.0.0-SNAPSHOT (powered by Quarkus quarkusVersion)) started in 0.846s. Listening on: http://0.0.0.0:3000
INFO [io.quarkus] (main) Profile dev activated. Live Coding activated.
INFO [io.quarkus] (main) Installed features: [cdi, servlet]
```
--------------------------------
### Initialize Slack App with Spring Boot
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/app-distribution.md
Configure and initialize the Slack App within a Spring Boot application. Ensure you call `asOAuthApp(true)` to enable OAuth functionality. This setup includes defining servlets for Slack events, installation, and OAuth redirects.
```java
package hello;
// export SLACK_SIGNING_SECRET=xxx
// export SLACK_CLIENT_ID=111.222
// export SLACK_CLIENT_SECRET=xxx
// export SLACK_SCOPES=commands,chat:write.public,chat:write
// export SLACK_USER_SCOPES=
// export SLACK_INSTALL_PATH=/slack/install
// export SLACK_REDIRECT_URI_PATH=/slack/oauth_redirect
// export SLACK_OAUTH_COMPLETION_URL=https://www.example.com/completion
// export SLACK_OAUTH_CANCELLATION_URL=https://www.example.com/cancellation
import com.slack.api.bolt.App;
import javax.servlet.annotation.WebServlet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SlackApp {
@Bean
public App initSlackApp() {
App app = new App().asOAuthApp(true); // Do not forget calling `asOAuthApp(true)` here
app.command("/hello-oauth-app", (req, ctx) -> {
return ctx.ack("What's up?");
});
return app;
}
}
import com.slack.api.bolt.servlet.SlackAppServlet;
import com.slack.api.bolt.servlet.SlackOAuthAppServlet;
@WebServlet("/slack/events")
public class SlackEventsController extends SlackAppServlet {
public SlackEventsController(App app) { super(app); }
}
@WebServlet("/slack/install")
public class SlackOAuthInstallController extends SlackOAuthAppServlet {
public SlackOAuthInstallController(App app) { super(app); }
}
@WebServlet("/slack/oauth_redirect")
public class SlackOAuthRedirectController extends SlackOAuthAppServlet {
public SlackOAuthRedirectController(App app) { super(app); }
}
```
--------------------------------
### Java Example for Maven Verification
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-client-setup.md
Create this Java class with a main method to verify your Maven build settings. Run it using the provided Maven command.
```java
import com.slack.api.Slack;
import com.slack.api.methods.response.api.ApiTestResponse;
public class Example {
public static void main(String[] args) throws Exception {
Slack slack = Slack.getInstance();
ApiTestResponse response = slack.methods().apiTest(r -> r.foo("bar"));
System.out.println(response);
}
}
```
--------------------------------
### Start Bolt App with HTTP in Kotlin
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/getting-started-with-bolt.md
This is a minimal Kotlin `main` function to start a Bolt app using HTTP with the embedded Jetty server. Replace `// Write some code here` with your app's event listeners and middleware.
```kotlin
import com.slack.api.bolt.App
import com.slack.api.bolt.jetty.SlackAppServer
fun main() {
val app = App()
// Write some code here
val server = SlackAppServer(app)
server.start() // http://localhost:3000/slack/events
}
```
--------------------------------
### Initialize and Start Slack App with Helidon
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
This Java code initializes a Slack Bolt App and starts it using the Helidon web server. It includes configuration for metrics and health checks.
```java
package hello;
import com.slack.api.bolt.App;
import com.slack.api.bolt.helidon.SlackAppServer;
import com.slack.api.model.event.AppMentionEvent;
import io.helidon.health.HealthSupport;
import io.helidon.health.checks.HealthChecks;
import io.helidon.metrics.MetricsSupport;
public final class Main {
public static void main(final String[] args) { startServer(); }
public static SlackAppServer startServer() {
SlackAppServer server = new SlackAppServer(apiApp(), oauthApp());
// If you add more settings to Routing, overwrite this configurator
server.setAdditionalRoutingConfigurator(builder -> builder
.register(MetricsSupport.create())
.register(HealthSupport.builder().addLiveness(HealthChecks.healthChecks()).build()));
server.start();
return server;
}
// POST /slack/events - this path is configurable with bolt.apiPath in application.yaml
public static App apiApp() {
App app = new App();
app.event(AppMentionEvent.class, (event, ctx) -> {
ctx.say("May I help you?");
return ctx.ack();
});
return app;
}
}
```
--------------------------------
### Boot Spring Boot Application
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
Command to start your Spring Boot application using Gradle.
```bash
$ gradle bootRun
```
--------------------------------
### Initialize Slack Object
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-basics.md
Instantiate the main Slack client object. This is the starting point for accessing all other API clients.
```java
import com.slack.api.Slack;
Slack slack = Slack.getInstance();
```
--------------------------------
### Manage Users with SCIM API in Java
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/scim-api.md
Provides examples for common user management operations: searching, reading, creating, filtering, and deleting users. Ensure you have the necessary scopes and user IDs.
```java
import com.slack.api.Slack;
import com.slack.api.scim.*;
import com.slack.api.scim.model.*;
import com.slack.api.scim.response.*;
// Search Users
UsersSearchResponse users = slack.scim(token).searchUsers(req -> req.count(1000));
// Read a User
final String userId = users.getResources().get(0).getId();
UsersReadResponse read = slack.scim(token).readUser(req -> req.id(userId));
// Pagination for Users
UsersSearchResponse users = slack.scim(token).searchUsers(req -> req.count(1).startIndex(2));
users.getItemsPerPage(); // 1
users.getResources().size(); // 1
users.getStartIndex(); // 2
// Create a new User
User newUser = new User();
newUser.setName(new User.Name());
newUser.getName().setGivenName("Kazuhiro");
newUser.getName().setFamilyName("Sera");
// set other fields as well...
UsersCreateResponse creation = slack.scim(token).createUser(req -> req.user(newUser));
// Run a filter query for user search
// /admins/scim-api
UsersSearchResponse searchResp = slack.scim(token).searchUsers(req -> req
.count(1)
.filter("userName eq \"" + userName + "\"")
);
// Delete a User
UsersDeleteResponse deletion = slack.scim(token).deleteUser(req -> req.id(userId));
```
--------------------------------
### Assistant Simple App Java Example
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/ai-apps.md
This Java code sets up a Slack Bolt application with Assistant middleware to handle user messages, file uploads, and thread interactions. It requires SLACK_BOT_TOKEN and SLACK_APP_TOKEN environment variables.
```java
package samples;
import com.slack.api.bolt.App;
import com.slack.api.bolt.AppConfig;
import com.slack.api.bolt.middleware.builtin.Assistant;
import com.slack.api.bolt.socket_mode.SocketModeApp;
import com.slack.api.model.assistant.SuggestedPrompt;
import com.slack.api.model.event.AppMentionEvent;
import com.slack.api.model.event.MessageEvent;
import java.util.Arrays;
import java.util.Collections;
public class AssistantSimpleApp {
public static void main(String[] args) throws Exception {
String botToken = System.getenv("SLACK_BOT_TOKEN");
String appToken = System.getenv("SLACK_APP_TOKEN");
App app = new App(AppConfig.builder().singleTeamBotToken(botToken).build());
Assistant assistant = new Assistant(app.executorService());
assistant.threadStarted((req, ctx) -> {
try {
ctx.say("Hi, how can I help you today?");
ctx.setSuggestedPrompts(r -> r
.title("Select one of the following:") // optional
.prompts(Collections.singletonList(SuggestedPrompt.create("What does SLACK stand for?")))
);
} catch (Exception e) {
ctx.logger.error("Failed to handle assistant thread started event: {e}", e);
}
});
assistant.userMessage((req, ctx) -> {
try {
// ctx.setStatus(r -> r.status("is typing...")); works too
ctx.setStatus("is typing...");
Thread.sleep(500L);
if (ctx.getThreadContext() != null && ctx.getThreadContext().getChannelId() != null) {
String contextChannel = ctx.getThreadContext().getChannelId();
ctx.say("I am aware of the channel context: <#" + contextChannel + ">");
} else {
ctx.say("Here you are!");
}
} catch (Exception e) {
ctx.logger.error("Failed to handle assistant user message event: {e}", e);
try {
ctx.say(":warning: Sorry, something went wrong during processing your request!");
} catch (Exception ee) {
ctx.logger.error("Failed to inform the error to the end-user: {ee}", ee);
}
}
});
assistant.userMessageWithFiles((req, ctx) -> {
try {
ctx.setStatus("is downloading the files...");
Thread.sleep(500L);
ctx.setStatus("is analyzing the files...", Arrays.asList("Reading bytes...", "Confirming hashes..."));
Thread.sleep(500L);
ctx.say("Your files do not have any issues!");
} catch (Exception e) {
ctx.logger.error("Failed to handle assistant user message event: {e}", e);
try {
ctx.say(":warning: Sorry, something went wrong during processing your request!");
} catch (Exception ee) {
ctx.logger.error("Failed to inform the error to the end-user: {ee}", ee);
}
}
});
app.use(assistant);
app.event(MessageEvent.class, (req, ctx) -> {
return ctx.ack();
});
app.event(AppMentionEvent.class, (req, ctx) -> {
ctx.say("I can help you at our 1:1 DM!");
return ctx.ack();
});
new SocketModeApp(appToken, app).start();
}
}
```
--------------------------------
### HTTP Java App Entry Point
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/getting-started-with-bolt.md
This Java code sets up a Bolt app to run with an HTTP server using bolt-jetty. It initializes the App, registers a command handler, and starts the SlackAppServer, which listens on port 3000 by default. It requires SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET environment variables.
```java
package hello;
import com.slack.api.bolt.App;
// If you use bolt-jakarta-jetty, you can import `com.slack.api.bolt.jakarta_jetty.SlackAppServer` instead
import com.slack.api.bolt.jetty.SlackAppServer;
public class MyApp {
public static void main(String[] args) throws Exception {
// App expects env variables (SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET)
App app = new App();
app.command("/hello", (req, ctx) -> {
return ctx.ack(":wave: Hello!");
});
SlackAppServer server = new SlackAppServer(app);
server.start(); // http://localhost:3000/slack/events
}
}
```
--------------------------------
### Example Section Block with External Select Menu
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/interactive-components.md
Shows the JSON structure for a 'section' block featuring an 'multi_external_select' accessory, used for selecting topics.
```json
{
"block_id": "topics",
"type": "section",
"text": { "type": "mrkdwn", "text": "Select the meeting topics" },
"accessory": {
"action_id": "topics-action",
"type": "multi_external_select",
"min_query_length": 1,
"placeholder": { "type": "plain_text", "text": "Select", "emoji": true }
}
}
```
--------------------------------
### Initialize Bolt App and Register Event Listener
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/socket-mode.md
Initialize an App instance and register listeners for events. This setup is the same for both HTTP and Socket Mode. Ensure the SLACK_BOT_TOKEN environment variable is set.
```java
import com.slack.api.bolt.App;
import com.slack.api.bolt.AppConfig;
import com.slack.api.model.event.AppMentionEvent;
// The bot token that starts with xoxb- is NOT the app-level token.
// The token here is the one you got by installing the app into a workspace
String botToken = System.getenv("SLACK_BOT_TOKEN");
AppConfig appConfig = AppConfig.builder().singleTeamBotToken(botToken).build();
// If you go with the default constructor, the App initialization requires an env variable named SLACK_BOT_TOKEN.
App app = new App(appConfig);
app.event(AppMentionEvent.class, (req, ctx) -> {
ctx.say("Hi there!");
return ctx.ack();
});
```
--------------------------------
### Publish App Home Tab View (Kotlin)
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/app-home.md
This Kotlin code achieves the same functionality as the Java example, publishing an App Home tab view upon receiving the `app_home_opened` event. It utilizes Kotlin's syntax for building views and includes race condition protection using the view's hash.
```kotlin
// static imports
import com.slack.api.model.block.Blocks.*
import com.slack.api.model.block.composition.BlockCompositions.*
import com.slack.api.model.view.Views.*
import com.slack.api.model.event.AppHomeOpenedEvent
import java.time.ZonedDateTime
// /reference/events/app_home_opened
app.event(AppHomeOpenedEvent::class.java) { event, ctx ->
// Build a Home tab view
val now = ZonedDateTime.now()
val appHomeView = view {
it.type("home")
.blocks(asBlocks(
section { section -> section.text(markdownText { mt -> mt.text(":wave: Hello, App Home! (Last updated: ${now})") }) },
image { img -> img.imageUrl("https://www.example.com/foo.png").altText("alt text for image") }
))
}
// Update the App Home for the given user
val res = ctx.client().viewsPublish {
it.userId(event.event.user)
.hash(event.event.view?.hash) // To protect against possible race conditions
.view(appHomeView)
}
ctx.ack()
}
```
--------------------------------
### Configure Redis Metrics Datastore
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-basics.md
Use this snippet to configure a Redis-backed datastore for collecting metrics across nodes. Ensure Redis is installed and running.
```java
import com.slack.api.Slack;
import com.slack.api.SlackConfig;
import com.slack.api.methods.metrics.RedisMetricsDatastore;
import redis.clients.jedis.JedisPool;
SlackConfig config = new SlackConfig();
// brew install redis
// redis-server /usr/local/etc/redis.conf --loglevel verbose
JedisPool jedis = new JedisPool("localhost");
config.getMethodsConfig().setMetricsDatastore(new RedisMetricsDatastore("test", jedis));
Slack slack = Slack.getInstance(config);
```
--------------------------------
### Configure Amazon S3 Storage for Bolt Apps
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/app-distribution.md
Demonstrates setting up Amazon S3 for both installation and OAuth state services in a Bolt application. Ensure AWS credentials and bucket name are correctly configured.
```java
import com.slack.api.bolt.App;
import com.slack.api.bolt.jetty.SlackAppServer;
import com.slack.api.bolt.service.InstallationService;
import com.slack.api.bolt.service.OAuthStateService;
import com.slack.api.bolt.service.builtin.AmazonS3InstallationService;
import com.slack.api.bolt.service.builtin.AmazonS3OAuthStateService;
import java.util.HashMap;
import java.util.Map;
import static java.util.Map.entry;
// The standard AWS env variables are expected
// export AWS_REGION=us-east-1
// export AWS_ACCESS_KEY_ID=AAAA*************
// export AWS_SECRET_ACCESS_KEY=4o7***********************
// Please be careful about the security policies on this bucket.
String awsS3BucketName = "YOUR_OWN_BUCKET_NAME_HERE";
InstallationService installationService = new AmazonS3InstallationService(awsS3BucketName);
// Set true if you'd like to store every single installation as a different record
installationService.setHistoricalDataEnabled(true);
// apiApp uses only InstallationService to access stored tokens
App apiApp = new App();
apiApp.command("/hi", (req, ctx) -> {
return ctx.ack("Hi there!");
});
apiApp.service(installationService);
// Needless to say, oauthApp uses InstallationService
// In addition, it uses OAuthStateService to create/read/delete state parameters
App oauthApp = new App().asOAuthApp(true);
oauthApp.service(installationService);
// Store valid state parameter values in Amazon S3 storage
OAuthStateService stateService = new AmazonS3OAuthStateService(awsS3BucketName);
// This service is necessary only for OAuth flow apps
oauthApp.service(stateService);
// Mount the two apps with their root path
SlackAppServer server = new SlackAppServer(new HashMap<>(Map.ofEntries(
entry("/slack/events", apiApp), // POST /slack/events (incoming API requests from the Slack Platform)
entry("/slack/oauth", oauthApp) // GET /slack/oauth/start, /slack/oauth/callback (user access)
)));
server.start(); // http://localhost:3000
```
--------------------------------
### Initialize SocketModeApp Adapter
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/socket-mode.md
Initialize the SocketModeApp adapter using an app-level token and your configured Bolt app. The `start()` method establishes a WebSocket connection and blocks the current thread.
```java
import com.slack.api.bolt.socket_mode.SocketModeApp;
// Note: If you use bolt-jakarta-socket-mode instead, the import would be:
// import com.slack.api.bolt.jakarta_socket_mode.SocketModeApp;
// the app-level token with `connections:write` scope
String appToken = System.getenv("SLACK_APP_TOKEN");
// Initialize the adapter for Socket Mode
// with an app-level token and your Bolt app with listeners.
SocketModeApp socketModeApp = new SocketModeApp(appToken, app);
// #start() method establishes a new WebSocket connection and then blocks the current thread.
// If you do not want to block this thread, use #startAsync() instead.
socketModeApp.start();
```
--------------------------------
### Publish App Home Tab View (Java)
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/app-home.md
Call `views.publish` to update a user's Home tab when the `app_home_opened` event is received. This example builds a simple view with a welcome message and an image. It includes logic to use the view's hash for race condition protection if a view already exists.
```java
import com.slack.api.methods.response.views.ViewsPublishResponse;
import com.slack.api.model.event.AppHomeOpenedEvent;
import com.slack.api.model.view.View;
import java.time.ZonedDateTime;
import static com.slack.api.model.block.Blocks.*;
import static com.slack.api.model.block.composition.BlockCompositions.*;
import static com.slack.api.model.view.Views.*;
// /reference/events/app_home_opened
app.event(AppHomeOpenedEvent.class, (payload, ctx) -> {
// Build a Home tab view
ZonedDateTime now = ZonedDateTime.now();
View appHomeView = view(view -> view
.type("home")
.blocks(asBlocks(
section(section -> section.text(markdownText(mt -> mt.text(":wave: Hello, App Home! (Last updated: " + now + ")")))),
image(img -> img.imageUrl("https://www.example.com/foo.png").altText("alt text for image"))
))
);
// Update the App Home for the given user
if (payload.getEvent().getView() == null) {
ViewsPublishResponse res = ctx.client().viewsPublish(r -> r
.userId(payload.getEvent().getUser())
.view(appHomeView)
);
} else {
ViewsPublishResponse res = ctx.client().viewsPublish(r -> r
.userId(payload.getEvent().getUser())
.hash(payload.getEvent().getView().getHash()) // To safeguard against potential race conditions
.view(appHomeView)
);
}
return ctx.ack();
});
```
--------------------------------
### Helidon SE Application Configuration
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
Configure Helidon SE applications using `application.yml`. This example sets the server port and host, and defines the API path for Slack events.
```yaml
server:
port: 3000
host: 0.0.0.0
bolt:
apiPath: /slack/events
```
--------------------------------
### Handle Block Kit Interactions in Assistant
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/ai-apps.md
Configure an app to handle Block Kit button clicks within an assistant thread. This example demonstrates setting up the Assistant middleware to ignore self-messages and respond to button actions with metadata.
```java
App app = new App(AppConfig.builder()
.singleTeamBotToken(System.getenv("SLACK_BOT_TOKEN"))
.ignoringSelfAssistantMessageEventsEnabled(false)
.build());
Assistant assistant = new Assistant(app.executorService());
assistant.threadStarted((req, ctx) -> {
try {
ctx.say(r -> r
.text("Hi, how can I help you today?")
.blocks(Arrays.asList(
section(s -> s.text(plainText("Hi, how can I help you today?"))),
actions(a -> a.elements(Collections.singletonList(
button(b -> b.actionId("assistant-generate-numbers").text(plainText("Generate numbers")))
)))
))
);
} catch (Exception e) {
ctx.logger.error("Failed to handle assistant thread started event: {e}", e);
}
});
app.blockAction("assistant-generate-numbers", (req, ctx) -> {
app.executorService().submit(() -> {
Map eventPayload = new HashMap<>();
eventPayload.put("num", 20);
try {
ctx.client().chatPostMessage(r -> r
.channel(req.getPayload().getChannel().getId())
.threadTs(req.getPayload().getMessage().getThreadTs())
.text("OK, I will generate numbers for you!")
.metadata(new Message.Metadata("assistant-generate-numbers", eventPayload))
);
} catch (Exception e) {
ctx.logger.error("Failed to post a bot message: {e}", e);
}
});
return ctx.ack();
});
assistant.botMessage((req, ctx) -> {
if (req.getEvent().getMetadata() != null
&& req.getEvent().getMetadata().getEventType().equals("assistant-generate-numbers")) {
try {
ctx.setStatus("is typing...");
Double num = (Double) req.getEvent().getMetadata().getEventPayload().get("num");
Set numbers = new HashSet<>();
SecureRandom random = new SecureRandom();
while (numbers.size() < num) {
numbers.add(String.valueOf(random.nextInt(100)));
}
Thread.sleep(1000L);
ctx.say(r -> r.text("Her you are: " + String.join(", ", numbers)));
} catch (Exception e) {
ctx.logger.error("Failed to handle assistant bot message event: {e}", e);
}
}
});
assistant.userMessage((req, ctx) -> {
try {
ctx.setStatus("is typing...");
ctx.say(r -> r.text("Sorry, I couldn't understand your comment."));
} catch (Exception e) {
ctx.logger.error("Failed to handle assistant user message event: {e}", e);
try {
ctx.say(r -> r.text(":warning: Sorry, something went wrong during processing your request!"));
} catch (Exception ee) {
ctx.logger.error("Failed to inform the error to the end-user: {ee}", ee);
}
}
});
app.assistant(assistant);
```
--------------------------------
### Initialize SCIM Client in Java
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/scim-api.md
Demonstrates how to create an SCIM client instance using the slack-api-client library. Requires an admin access token with the 'admin' scope.
```java
import com.slack.api.Slack;
import com.slack.api.scim.*;
Slack slack = Slack.getInstance();
String token = System.getenv("SLACK_ADMIN_ACCESS_TOKN"); // `admin` scope required
SCIMClient scim = slack.scim(token);
```
--------------------------------
### Import jSlack Classes and Initialize Slack Instance
Source: https://github.com/slackapi/java-slack-sdk/wiki/Getting-Started-with-groovysh
After resolving dependencies, import necessary jSlack classes and create an instance of the Slack client.
```groovy
:i com.github.seratch.jslack.*
slack = Slack.getInstance()
```
--------------------------------
### Start Bolt App with Socket Mode in Kotlin
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/getting-started-with-bolt.md
This is a minimal Kotlin `main` function to start a Bolt app using Socket Mode. Replace `// Write some code here` with your app's event listeners and middleware.
```kotlin
import com.slack.api.bolt.App
import com.slack.api.bolt.socket_mode.SocketModeApp
fun main() {
val app = App()
// Write some code here
SocketModeApp(app).start()
}
```
--------------------------------
### Initialize Audit Client in Java
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/audit-logs-api.md
Instantiate the Slack client and obtain an AuditClient instance using an admin access token. Ensure the token has the `auditlogs:read` scope.
```java
import com.slack.api.Slack;
import com.slack.api.audit.*;
Slack slack = Slack.getInstance();
String token = System.getenv("SLACK_ADMIN_ACCESS_TOKN"); // `auditlogs:read` scope required
AuditClient audit = slack.audit(token);
```
--------------------------------
### Start Embedded Jetty Web Server for OAuth
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/socket-mode.md
Start an embedded Jetty web server to handle OAuth flows for a distributed Slack application. This server runs in the current process and can be used alongside Socket Mode.
```java
import com.slack.api.bolt.jetty.SlackAppServer;
import java.util.HashMap;
import java.util.Map;
Map apps = new HashMap<>();
apps.put("/slack/", new App(appConfig).asOAuthApp(true));
SlackAppServer oauthSever = new SlackAppServer(apps);
// Block the current thread
oauthSever.start();
// Access the OAuth URL - https://{your public domain}/slack/install
```
--------------------------------
### Start Socket Mode App Asynchronously
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/socket-mode.md
Start the Socket Mode app in a new thread without blocking the main thread. This is useful for distributed applications where other processes, like a web server, need to run concurrently.
```java
import com.slack.api.bolt.socket_mode.SocketModeApp;
// Note: If you use bolt-jakarta-socket-mode instead, the import would be:
// import com.slack.api.bolt.jakarta_socket_mode.SocketModeApp;
String appToken = "xapp-1-A111-111-xxx";
SocketModeApp socketModeApp = new SocketModeApp(appToken, app);
// This does not block the current thread
socketModeApp.startAsync();
```
--------------------------------
### Build App Home View with Block Kit Kotlin DSL
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/app-home.md
Demonstrates how to construct an App Home view using the Block Kit Kotlin DSL. This provides a more concise and idiomatic way to define Block Kit UI elements in Kotlin.
```kotlin
// These imports are necessary for this code
import com.slack.api.model.kotlin_extension.view.blocks
import com.slack.api.model.view.Views.view
val appHomeView = view { it
.type("home")
.blocks {
section {
markdownText(":wave: Hello, App Home! (Last updated: ${now}")
}
image {
imageUrl("https://www.example.com/foo.png")
}
}
}
```
--------------------------------
### Search Users with AsyncSCIMClient
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/scim-api.md
Demonstrates how to use the `AsyncSCIMClient` to search for users, respecting rate limits. Ensure you have an organization admin user token.
```java
import com.slack.api.Slack;
import com.slack.api.scim.response.*;
import java.util.concurrent.CompletableFuture;
Slack slack = Slack.getInstance();
String token = "xoxp-***"; // Org admin user token
CompletableFuture users = slack.scimAsync(token).searchUsers(req -> req
.startIndex(1)
.count(100)
.filter("userName Eq \"Carly\"")
);
```
--------------------------------
### Start groovysh Shell
Source: https://github.com/slackapi/java-slack-sdk/wiki/Getting-Started-with-groovysh
Invoke the groovysh interactive shell. The JVM option for logging is optional but helpful for debugging.
```bash
$ groovysh -Dorg.slf4j.simpleLogger.defaultLogLevel=debug
Groovy Shell (2.4.7, JVM: 1.8.0_71)
Type ':help' or ':h' for help.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
groovy:000>
```
--------------------------------
### Example Actions Block Payload
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/interactive-components.md
Illustrates the JSON payload structure for an 'actions' block containing a button element.
```json
{
"type": "actions",
"elements": [{
"type": "button",
"action_id": "button-action",
"text": { "type": "plain_text", "text": "Button", "emoji": true },
"value": "button's value"
}]
}
```
--------------------------------
### Run Simple App with Gradle
Source: https://github.com/slackapi/java-slack-sdk/blob/main/bolt-spring-boot-examples/spring-boot-2/README.md
Use Gradle to build and run your simple Bolt application after setting the necessary environment variables.
```bash
./gradlew bootRun
```
--------------------------------
### Quarkus Hot Reload Output
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
Example stdout output during hot-reloading in Quarkus development mode, showing recompilation and restart messages.
```text
INFO [io.qua.dev] (vert.x-worker-thread-0) Changed source files detected, recompiling [/path-to-project/src/main/java/hello/SlackApp.java]
INFO [io.quarkus] (vert.x-worker-thread-0) Quarkus stopped in 0.001s
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
INFO [io.quarkus] (vert.x-worker-thread-0) code-with-quarkus 1.0.0-SNAPSHOT (powered by Quarkus quarkusVersion) started in 0.021s. Listening on: http://0.0.0.0:3000
INFO [io.quarkus] (vert.x-worker-thread-0) Profile dev activated. Live Coding activated.
INFO [io.quarkus] (vert.x-worker-thread-0) Installed features: [cdi, servlet]
INFO [io.qua.dev] (vert.x-worker-thread-0) Hot replace total time: 0.232s
```
--------------------------------
### Acknowledge a Command Request
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/bolt-basics.md
Always acknowledge incoming requests using `ctx.ack()`. This example shows a basic acknowledgment for a slash command.
```java
app.command("/hello", (req, ctx) -> {
// ctx: Context
return ctx.ack(); // empty body, that means your bot won't post a reply this time
});
```
--------------------------------
### Build Slack SDK from Source (Bash)
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-client-setup.md
Clone the Slack Java SDK repository and build it using Maven. This makes the SDK modules available in your local Maven repository.
```bash
git clone git@github.com:slackapi/java-slack-sdk.git
cd java-slack-sdk
mvn install -Dmaven.test.skip=true
```
--------------------------------
### Disable Traffic Metrics Globally
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-basics.md
Configure the Slack SDK to disable all traffic metrics collection. This can be done during the initial `SlackConfig` setup.
```java
SlackConfig config = new SlackConfig();
config.setStatsEnabled(false);
Slack slack = Slack.getInstance(config);
```
--------------------------------
### Deploy Bolt App to Google Cloud Run
Source: https://github.com/slackapi/java-slack-sdk/blob/main/bolt-docker-examples/echo-command-app/README.md
Set up Google Cloud project and Slack environment variables. Build and upload the Docker image to Google Container Registry, then deploy it to Cloud Run with specified environment variables and region.
```bash
export GCLOUD_PROJECT_ID={something-great-12345}
export SLACK_SIGNING_SECRET={abcabcabcabcabcbabc}
export SLACK_BOT_TOKEN={xoxb-1234123412-123412341212-abcabcabc}
# Build and upload a Docker image
gcloud config set project ${GCLOUD_PROJECT_ID}
gcloud builds submit --tag gcr.io/${GCLOUD_PROJECT_ID}/hello-bolt
# Deploy the image to Cloud Run
gcloud config set run/region asia-northeast1 # set your region here
gcloud beta run deploy hello-bolt \
--image gcr.io/${GCLOUD_PROJECT_ID}/hello-bolt \
--platform managed \
--allow-unauthenticated \
--update-env-vars \
SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET},\nSLACK_BOT_TOKEN=${SLACK_BOT_TOKEN}
```
--------------------------------
### Run No-Prep CI Tests for Java Slack SDK
Source: https://github.com/slackapi/java-slack-sdk/blob/main/AGENTS.md
Executes CI tests without requiring any preparation steps. This is the recommended approach for development.
```bash
./scripts/run_no_prep_tests.sh
```
--------------------------------
### Slack Web API Success Response Example
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-basics.md
A typical JSON response from a successful Slack Web API call, indicating 'ok: true'.
```json
{
"ok": true,
"stuff": "This is good"
}
```
--------------------------------
### Construct Modal View with Kotlin DSL
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/modals.md
Demonstrates building a modal view using the Block Kit Kotlin DSL for a more type-safe and fluent API. This approach leverages extension functions for constructing Slack UI components.
```kotlin
import com.slack.api.model.kotlin_extension.view.blocks
import com.slack.api.model.view.Views.*
fun buildView(): View {
return view { thisView -> thisView
.callbackId("meeting-arrangement")
.type("modal")
.notifyOnClose(true)
.title(viewTitle { it.type("plain_text").text("Meeting Arrangement").emoji(true) })
.submit(viewSubmit { it.type("plain_text").text("Submit").emoji(true) })
.close(viewClose { it.type("plain_text").text("Cancel").emoji(true) })
.privateMetadata("{\"response_url\":\"https://hooks.slack.com/actions/T1ABCD2E12/330361579271/0dAEyLY19ofpLwxqozy3firz\"}")
.blocks {
// You can leverage Kotlin DSL here
section {
blockId("category-block")
markdownText("Select a category of the meeting!")
staticSelect {
actionId("category-selection-action")
placeholder("Select a category")
options {
option {
description("Customer")
value("customer")
}
option {
description("Partner")
value("partner")
}
option {
description("Internal")
value("internal")
}
}
}
}
input {
blockId("agenda-block")
plainTextInput {
actionId("agenda-action")
multiline(true)
}
label("Detailed Agenda", emoji = true)
}
}
}
}
```
--------------------------------
### Gradle Repository Configuration for Local Maven
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-client-setup.md
Add `mavenLocal()` to your `build.gradle` repositories block if you are building the SDK from source and want to use locally installed modules.
```groovy
repositories {
mavenLocal()
}
```
--------------------------------
### Handle Chat Post Message Response in Java
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-basics.md
Example of calling the chat.postMessage API method and checking the response for success or failure using the isOk() method.
```java
import com.slack.api.model.Message;
ChatPostMessageResponse response = slack.methods(token).chatPostMessage(req -> req
.channel("C1234567")
.text("Write one, post anywhere"));
if (response.isOk()) {
Message postedMessage = response.getMessage();
} else {
String errorCode = response.getError(); // e.g., "invalid_auth", "channel_not_found"
}
```
--------------------------------
### Kotlin Slack App Servlet with Quarkus
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/supported-web-frameworks.md
Example of a Kotlin Slack Bolt application integrated with Quarkus using a Servlet. It defines a command handler for '/ping'.
```kotlin
package hello
import com.slack.api.bolt.App
import com.slack.api.bolt.servlet.SlackAppServlet
import javax.servlet.annotation.WebServlet
@WebServlet("/slack/events")
class SlackApp : SlackAppServlet(initSlackApp()) {
companion object {
fun initSlackApp(): App {
val app = App()
app.command("/ping") { req, ctx ->
ctx.ack("<@${req.payload.userId}> pong!")
}
return app
}
}
}
```
--------------------------------
### Slack Web API Error Response Example
Source: https://github.com/slackapi/java-slack-sdk/blob/main/docs/english/guides/web-api-basics.md
A typical JSON response from a failed Slack Web API call, indicating 'ok: false' with an error code.
```json
{
"ok": false,
"error": "something_bad"
}
```