Building AI-powered assistants and agents in Slack with AWS Bedrock

Share

Last December, I had the incredible opportunity to speak at AWS re:Invent in Las Vegas. My talk focused on building AI-powered agents and assistants in Slack using AWS services—specifically Amazon Bedrock with Claude. I explored the challenges of information overload and the need for AI-driven solutions in the workplace, demonstrating how adding AI to automations can make them more powerful and productive.

 

In today’s fast-paced digital workplace, time is our most precious resource. Yet, surprisingly, most knowledge workers find themselves trapped in a productivity paradox. Did you know that the average worker spends 20% of their workweek—that’s an entire day—just searching for information? This staggering statistic highlights a major problem: information overload and fragmentation.

 

In this post, I’ll walk you through how I built an AI assistant using the Slack Bolt framework and Amazon Bedrock, then transformed it into an agent capable of performing actions using Slack features. You’ll see how it can help automate tasks directly within Slack.

Photo credits: Kurtis Kemple

The problem: Too much information, not enough time

Time is our most valuable asset, yet we spend an alarming portion of our workweek searching for information—whether it’s catching up on missed conversations, finding customer data, or tracking project updates. This inefficiency leads to delays, lost productivity, and frustration.

 

Enter Slack as the WorkOS. With 700 million messages sent per day, Slack holds a vast amount of organizational knowledge. But manually searching through that data isn’t scalable. That’s where AI-powered assistants come in—to help teams surface critical information and automate actions in real time.

Building a Slack assistant with Bolt and Bedrock

To get started, first identify a use case. There’s always a repetitive task that could be automated, saving you valuable time for higher-impact work.

 

In my case, I wanted an assistant to help with my daily routines, such as consuming information to generate content—whether internally or externally. I built a Slack app using BoltJS and Slack’s Assistant Sample App template.

 

This template made getting started incredibly fast by handling all the necessary configurations. It’s available for Bolt for JS and Bolt for Python if you want to try it yourself.

1. Setting Up the App

I started by creating a Slack app with Bolt and configuring it via the manifest file. The manifest defines the app’s capabilities, including permissions, event subscriptions, outgoing domains, and interactivity settings.

 

2. Connecting to AWS Bedrock

 The core functionality of the app lives in the app.js file (if you’re following the template I mentioned). Here, we initialize and run the app.

 

To integrate AI capabilities, I used Amazon Bedrock, but you can use any LLM of your choice. By default, the sample template is configured with OpenAI, but I customized it for Claude with Bedrock using the AWS SDK.

 

Before integrating Amazon Bedrock, you’ll need to configure which LLM(s) you want to use directly in the AWS console. This setup ensures that your assistant can access the right model for your use case.

				
					const { BedrockRuntimeClient, InvokeModelCommand } = require('@aws-sdk/client-bedrock-runtime');

const bedrockClient = new BedrockRuntimeClient({
  region: process.env.AWS_REGION || "us-east-1",
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
});
				
			

With this setup, I could send user queries to Claude and retrieve responses, making the assistant more conversational and context-aware.

 

With the connection in place, I needed a way to interact with Bedrock dynamically. To achieve this, I added a helper function that sends queries to Bedrock and retrieves responses whenever needed in my code.

				
					const modelId = "anthropic.claude-v2"; // Specify your model ID

const callBedrock = async (prompt) => {
  const request = {
    prompt: `\\n\\nHuman: ${prompt}\\n\\nAssistant:`,
    max_tokens_to_sample: 2000,
  };

  const input = {
    body: JSON.stringify(request),
    contentType: "application/json",
    accept: "application/json",
    modelId: modelId,
  };

  const command = new InvokeModelCommand(input);
  const response = await bedrockClient.send(command);
  const completionData = JSON.parse(Buffer.from(response.body).toString('utf8'));
  return completionData.completion.trim();
};

				
			

3. Handling Conversations in Slack

 Using the Bolt framework, I created an AI assistant that listens to user messages and responds contextually. It also provides suggested prompts to guide users in getting relevant insights.

 

This is powered by the Assistant class, developed by our amazing Open Source & Developer Experience team, making the process much simpler.

 

Some core methods in the Assistant class include:

  1. threadStarted – Triggers when a user opens the assistant in Slack, allowing the app to initialize conversations and provide suggested prompts.
  2. threadContextChanged – Fires when a user switches context within Slack, enabling the assistant to adjust responses dynamically.
  3. userMessage – Activates when a user sends a message, prompting the assistant to process and respond using an LLM.
				
					const assistant = new Assistant({
  threadStarted: async ({ event, say, saveThreadContext }) => {
    await say('Hi, how can I help?');
    await saveThreadContext();
  },

  userMessage: async ({ client, message, say }) => {
    const response = await callBedrock(message.text);
    await say(response);
  },
});

				
			

This setup enables users to interact naturally with the assistant, receiving AI-driven responses within Slack.

 

4. Automating Actions in Slack

 Beyond answering questions, I wanted my assistant to take action. By analyzing user prompts, it identified possible actions—such as inviting users to a channel, creating new channels, or generating a Slack Canvas document.

 

I used Slack WebAPI methods to enable these capabilities. The assistant matches user requests with available actions, making interactions seamless.

 

For example, if a user asked to summarize a conversation and store it, the assistant would generate a summary and create a Canvas document automatically:

				
					// capabilities.js
const capabilities = {};

capabilities.addToCanvas = async ({ title, content, client }) => {
console.log("Canvas Title:", title);
  console.log("Canvas Content:", content);
  try {
    // Step 1: Create the Canvas
    const createResponse = await client.canvases.create({
      title,
      document_content: JSON.stringify({
        type: "markdown",
        markdown: content, // Ensure content is formatted as Markdown
      }),
    });

    // Log the Canvas creation response
    console.log("Canvas Create Response:", createResponse);

    if (!createResponse.ok || !createResponse.canvas_id) {
      throw new Error("Failed to create Canvas.");
    }

    // Step 2: Retrieve Canvas permalink using files.info
    const infoResponse = await client.files.info({
      file: createResponse.canvas_id, // Use the canvas_id from the creation response
    });

    // Log the file info response
    console.log("Canvas Info Response:", infoResponse);

    if (infoResponse.ok && infoResponse.file.permalink) {
      return `Canvas created: ${infoResponse.file.permalink}`;
    } else {
      return "Canvas created, but could not retrieve the permalink.";
    }
  } catch (error) {
console.error("Error creating or retrieving Canvas:", error);
    throw new Error("Failed to create and retrieve Canvas permalink.");
  }
};

// Export the capabilities object
module.exports = capabilities;

				
			

By leveraging Slack’s WebAPI, you can create as many methods as needed—the possibilities are endless.

 

This is just one way to build an AI-powered assistant or agent, but you can tailor the approach to fit your specific needs and workflows. I’d love to hear how you apply the assistant class in your projects!

 

Going further with Agentforce

 

For those looking to deploy AI agents without building from scratch, Agentforce provides a powerful alternative. It enables the creation of proactive, autonomous AI agents that can execute tasks based on business knowledge. Developers can extend these agents with custom Slack actions, making them even more adaptable to specific workflows.

Using the Agent Builder you can start customizing your agent, adding prompts and tailor it for your use case. The best part, you can make it available in Slack so people at your organization can interact with it.

It ships with many Slack actions like creating a channel, or updating it. But you can create your custom Slack actions by using any method of our WebAPI.

 

Build your own AI-powered Slack app

 

LLMs and Slack provide a powerful combination for building AI-driven assistants that enhance workplace productivity. Whether you build a custom solution with Bolt.js or leverage Agentforce for a plug-and-play experience, AI-powered agents are transforming how teams interact with information and take action in Slack.

If you’re looking to build your own Slack AI assistant, I highly recommend exploring the Assistant Sample App, available for both JavaScript and Python.

It’s a great starting point, handling much of the setup for you so you can focus on customizing and expanding its capabilities. The possibilities are endless, and the future of work is more intelligent and automated than ever before.

Photo credits: Kurtis Kemple

If you build something cool, I’d love to see it and feature it in our developer newsletter! Subscribe here, and submit your content at technewsletter@slack-corp.com

Happy building! 🚀

More Reads