Building an LLM-Powered Slack Bot with Java: A Step-by-Step Guide
Introduction
Slack has become the central hub for team communication in countless organizations. But what if your Slack workspace could have an AI-powered assistant that answers questions, drafts messages, and helps with daily tasks? In this guide, I’ll walk you through building a Slack bot that leverages a large language model (LLM) using Java. We’ll use Spring Boot for the backend, the Slack API for messaging, and an LLM provider like OpenAI or Anthropic for intelligence.
By the end of this tutorial, you’ll have a working bot that can:
- Respond to direct messages and mentions
- Maintain conversation context
- Handle asynchronous events
- Be deployed to the cloud or on-premises
Let’s dive in!
Prerequisites
Before we start, make sure you have:
- Java 17 or later
- Maven or Gradle
- A Slack workspace (free tier is fine)
- An API key from an LLM provider (e.g., OpenAI, Anthropic, or a local model via Ollama)
- Basic familiarity with Spring Boot and REST APIs
Architecture Overview
Our bot will consist of three main components:
- Slack Event Adapter: Receives events from Slack (via WebSocket or HTTP) and normalizes them.
- LLM Service: Calls the LLM API with conversation history and returns a response.
- Response Handler: Sends the response back to Slack.
We’ll use the official Slack SDK for Java, which simplifies both WebSocket and HTTP integrations. For the LLM, we’ll use a simple REST client to call the API, keeping the implementation provider-agnostic.
Setting Up the Project
Create a new Spring Boot project using Spring Initializr with dependencies: Web, WebSocket, and Lombok. Then, add the Slack SDK and an HTTP client (we’ll use WebClient from Spring WebFlux).
Here’s a snippet of our pom.xml:
1 | <dependencies> |
Slack App Configuration
- Go to api.slack.com/apps and create a new app.
- Choose “From scratch” and give it a name.
- Under Event Subscriptions, enable events and set the request URL to
https://your-domain.com/slack/events(we’ll implement this endpoint later). - Subscribe to the following bot events:
message.channels(messages in public channels)message.im(direct messages)app_mention(when the bot is mentioned)
- Add the
chat:writeandapp_mentions:readOAuth scopes. - Install the app to your workspace and copy the Bot User OAuth Token.
Implementing the Slack Event Adapter
We’ll create a controller that receives HTTP POST requests from Slack. Slack sends a URL verification challenge when you first set up the endpoint, so we need to handle that.
1 |
|
To avoid blocking Slack’s retry logic, we return an empty 200 response immediately and process the event asynchronously. We’ll use a @Async method or a message queue for that.
Connecting to Slack via WebSocket
While HTTP is fine for most cases, WebSocket is more efficient for real-time interactions. The Slack SDK provides a SocketModeClient that handles the connection automatically.
1 |
|
To use Socket Mode, you need to enable it in your Slack app settings and generate an App-Level Token with connections:write scope.
Integrating the LLM
Now for the core logic. We’ll create an LLMService that takes a list of messages and returns a response. For flexibility, we’ll support multiple providers via an interface.
1 | public interface LLMService { |
Here’s an implementation using OpenAI’s API with WebClient:
1 |
|
We can similarly implement an Anthropic service or a local Ollama service. The key is to keep the interface clean so we can swap providers easily.
Maintaining Conversation Context
To have meaningful conversations, we need to keep track of context. We’ll store conversation history per user or channel in memory (for simplicity) or in a database for production.
1 |
|
When a new message arrives, we append it to the history and send the last N messages to the LLM (to avoid token limits). We can also include a system prompt to set the bot’s behavior.
Sending Responses Back to Slack
After getting the LLM response, we send it back using Slack’s chat.postMessage method. We’ll use the MethodsClient from the SDK.
1 |
|
Handling Different Event Types
We need to handle various scenarios:
- Direct messages: The bot should respond to any DM.
- Mentions in channels: The bot should respond when mentioned.
- Message edits or deletes: We can ignore those for simplicity.
We’ll create an EventProcessor class that parses the event and routes it accordingly.
1 |
|
Adding a System Prompt
To make the bot more useful, we can prepend a system message that defines its persona. For example:
1 | ChatMessage systemMessage = new ChatMessage("system", "You are a helpful assistant for a software development team. Answer questions about code, debugging, and best practices. Keep responses concise."); |
We’ll include this as the first message in the history when calling the LLM.
Deployment Considerations
Configuration
Store sensitive data like API keys and tokens in environment variables or a secrets manager. In Spring Boot, use application.yml with placeholders:
1 | slack: |
Scalability
If your bot gains popularity, you’ll want to:
- Move conversation history to Redis or a database.
- Use a message queue (e.g., RabbitMQ) to decouple event processing.
- Implement rate limiting to avoid hitting LLM API limits.
Error Handling
Implement retry logic for transient errors (e.g., network timeouts). Use Spring Retry or a simple loop with exponential backoff.
Testing the Bot
Before deploying, test locally using Slack’s Socket Mode. Run your Spring Boot app, and in your Slack workspace, send a DM to your bot. You should see a response after a few seconds (depending on LLM latency).
Full Example: Putting It All Together
Here’s a simplified version of the main application class:
1 |
|
And the application.yml:
1 | server: |
Conclusion
Building an LLM-powered Slack bot in Java is a rewarding project that combines modern AI with a popular communication platform. With the steps above, you can create a bot that answers questions, assists with tasks, and integrates seamlessly into your team’s workflow. The same pattern can be extended to other platforms like Microsoft Teams or Discord.
Remember to start small—get a basic bot responding to mentions—then add features like conversation memory, multi-provider support, and advanced commands. The possibilities are endless!
Key Takeaways
- Use the official Slack SDK for Java to handle events and messaging.
- Choose Socket Mode for development simplicity and HTTP endpoints for production if you need public URLs.
- Abstract the LLM provider behind an interface to allow swapping between OpenAI, Anthropic, or local models.
- Manage conversation context carefully to avoid token limits and maintain coherent interactions.
- Secure your tokens and API keys using environment variables or a secrets manager.
- Plan for scalability by using external storage for conversation history and async processing for events.
Happy coding! Now go build something amazing for your team.