CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-slack--bolt

A framework for building Slack apps, fast.

Pending
Overview
Eval results
Files

advanced-features.mddocs/

Advanced Features

Slack Bolt provides advanced functionality for AI Assistant integration, workflow steps, custom functions, and conversation state management for complex Slack application scenarios.

Capabilities

AI Assistant Integration

Build AI-powered Slack assistants with thread context management and user interaction handling.

/**
 * AI Assistant class for building intelligent Slack applications
 * @param config - Assistant configuration with event handlers
 */
class Assistant {
  constructor(config: AssistantConfig);
}

interface AssistantConfig {
  /** Custom thread context store (defaults to in-memory store) */
  threadContextStore?: AssistantThreadContextStore;
  /** Handler(s) for when assistant threads are started */
  threadStarted: AssistantThreadStartedMiddleware | AssistantThreadStartedMiddleware[];
  /** Handler(s) for when thread context changes (optional) */
  threadContextChanged?: AssistantThreadContextChangedMiddleware | AssistantThreadContextChangedMiddleware[];
  /** Handler(s) for user messages in assistant threads */
  userMessage: AssistantUserMessageMiddleware | AssistantUserMessageMiddleware[];
}

type AssistantThreadStartedMiddleware = (
  args: AssistantUtilityArgs & AllMiddlewareArgs
) => Promise<void>;

type AssistantThreadContextChangedMiddleware = (
  args: AssistantUtilityArgs & AllMiddlewareArgs & {
    previousThreadContext?: AssistantThreadContext;
  }
) => Promise<void>;

type AssistantUserMessageMiddleware = (
  args: AssistantUtilityArgs & SlackEventMiddlewareArgs<'message'> & {
    message: AssistantMessage;
  }
) => Promise<void>;

Usage Examples:

import { App, Assistant } from "@slack/bolt";

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

// Configure assistant
const assistant = new Assistant({
  threadStarted: async ({ say, setStatus, setSuggestedPrompts }) => {
    await say("Hello! I'm your AI assistant. How can I help you today?");
    
    await setStatus("Ready to assist");
    
    await setSuggestedPrompts({
      prompts: [
        { title: "Help me write code", message: "Can you help me write some code?" },
        { title: "Explain a concept", message: "Can you explain how webhooks work?" },
        { title: "Review my work", message: "Can you review this document?" }
      ],
      title: "Popular requests"
    });
  },
  
  userMessage: async ({ 
    message, 
    say, 
    getThreadContext, 
    saveThreadContext,
    setStatus 
  }) => {
    await setStatus("Thinking...");
    
    // Get conversation context
    const context = await getThreadContext();
    
    // Process user message with AI
    const response = await processWithAI(message.text, context);
    
    // Update context with new information
    context.conversationHistory.push({
      user: message.text,
      assistant: response
    });
    
    // Save updated context
    await saveThreadContext();
    
    await say(response);
    await setStatus("Ready");
  }
});

// Register assistant with app
app.assistant(assistant);

Assistant Thread Context

Manage conversation state and context across assistant interactions.

interface AssistantThreadContext {
  /** Channel ID where the thread exists */
  channelId: string;
  /** Thread timestamp identifier */
  threadTs: string;
  /** Custom context data */
  [key: string]: any;
}

interface AssistantThreadContextStore {
  /** Retrieve context for a specific thread */
  get(channelId: string, threadTs: string): Promise<AssistantThreadContext>;
  /** Save context for a specific thread */
  save(context: AssistantThreadContext): Promise<void>;
  /** Remove context for a specific thread */
  remove(channelId: string, threadTs: string): Promise<void>;
}

class DefaultThreadContextStore implements AssistantThreadContextStore {
  constructor();
  
  async get(channelId: string, threadTs: string): Promise<AssistantThreadContext>;
  async save(context: AssistantThreadContext): Promise<void>;
  async remove(channelId: string, threadTs: string): Promise<void>;
}

Assistant Utilities

Utility functions available to assistant middleware for managing thread state and interactions.

interface AssistantUtilityArgs {
  /** Get current thread context */
  getThreadContext: GetThreadContextUtilFn;
  /** Save current thread context */
  saveThreadContext: SaveThreadContextUtilFn;
  /** Send message in current thread */
  say: SayFn;
  /** Set assistant status */
  setStatus: SetStatusFn;
  /** Set suggested prompts for the thread */
  setSuggestedPrompts: SetSuggestedPromptsFn;
  /** Set thread title */
  setTitle: SetTitleFn;
}

type GetThreadContextUtilFn = () => Promise<AssistantThreadContext>;
type SaveThreadContextUtilFn = () => Promise<void>;
type SetStatusFn = (status: string) => Promise<AssistantThreadsSetStatusResponse>;
type SetSuggestedPromptsFn = (
  params: SetSuggestedPromptsArguments
) => Promise<AssistantThreadsSetSuggestedPromptsResponse>;
type SetTitleFn = (title: string) => Promise<AssistantThreadsSetTitleResponse>;

interface SetSuggestedPromptsArguments {
  /** Prompt suggestions that appear when opening assistant thread */
  prompts: [AssistantPrompt, ...AssistantPrompt[]];
  /** Title for the prompts */
  title: string;
}

interface AssistantPrompt {
  /** Display title for the prompt */
  title: string;
  /** Message text when prompt is selected */  
  message: string;
}

Workflow Steps (Deprecated)

Legacy workflow step functionality for workflow apps (deprecated in favor of custom functions).

/**
 * @deprecated Steps from Apps are no longer supported and support will be removed in next major version
 * Workflow step builder for creating custom workflow steps
 */
class WorkflowStep {
  constructor(config: WorkflowStepConfig);
}

/**
 * @deprecated Configuration for workflow steps
 */
interface WorkflowStepConfig {
  /** Callback ID for the workflow step */
  callback_id: string;
  /** Handler for step edit action */
  edit: WorkflowStepEditMiddleware | WorkflowStepEditMiddleware[];
  /** Handler for step save action */
  save: WorkflowStepSaveMiddleware | WorkflowStepSaveMiddleware[];
  /** Handler for step execution */
  execute: WorkflowStepExecuteMiddleware | WorkflowStepExecuteMiddleware[];
}

type WorkflowStepEditMiddleware = (
  args: SlackActionMiddlewareArgs<WorkflowStepEdit> & {
    step: WorkflowStepEdit;
    configure: (config: StepConfigureArguments) => Promise<ViewsOpenResponse>;
  }
) => Promise<void>;

type WorkflowStepSaveMiddleware = (
  args: SlackViewMiddlewareArgs & {
    step: WorkflowStepEdit;
    update: (config: StepUpdateArguments) => Promise<WorkflowsUpdateStepResponse>;
  }
) => Promise<void>;

type WorkflowStepExecuteMiddleware = (
  args: SlackEventMiddlewareArgs<'workflow_step_execute'> & {
    step: WorkflowStepExecuteEvent;
    complete: (outputs?: StepCompletionArguments) => Promise<WorkflowsStepCompletedResponse>;
    fail: (error: StepFailureArguments) => Promise<WorkflowsStepFailedResponse>;
  }
) => Promise<void>;

Custom Functions

Create custom functions for Slack workflows with input validation and execution handling.

/**
 * Custom function builder for Slack workflows
 */
class CustomFunction {
  constructor(callbackId: string, config: CustomFunctionConfig);
}

interface CustomFunctionConfig {
  /** Handler for function execution */
  execute: CustomFunctionExecuteMiddleware | CustomFunctionExecuteMiddleware[];
}

type CustomFunctionExecuteMiddleware = (
  args: SlackCustomFunctionMiddlewareArgs & {
    inputs: FunctionInputs;
    complete: FunctionCompleteFn;
    fail: FunctionFailFn;
  }
) => Promise<void>;

type FunctionCompleteFn = (outputs: { [key: string]: any }) => Promise<void>;
type FunctionFailFn = (error: string) => Promise<void>;

interface SlackCustomFunctionMiddlewareArgs extends AllMiddlewareArgs {
  /** Function execution payload */
  payload: {
    type: 'function_executed';
    function: {
      callback_id: string;
      type: 'app';
    };
    inputs: FunctionInputs;
    function_execution_id: string;
    workflow: {
      id: string;
    };
    event: {
      type: 'function_executed';
    };
  };
}

Usage Examples:

import { App, CustomFunction } from "@slack/bolt";

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

// Define custom function
const processDataFunction = new CustomFunction("process_data", {
  execute: async ({ inputs, complete, fail, client }) => {
    try {
      const { data_source, format } = inputs;
      
      // Validate inputs
      if (!data_source) {
        await fail("data_source is required");
        return;
      }
      
      // Process the data
      const result = await processData(data_source, format);
      
      // Return outputs
      await complete({
        processed_data: result.data,
        record_count: result.count,
        status: "success"
      });
      
    } catch (error) {
      await fail(`Processing failed: ${error.message}`);
    }
  }
});

// Register function with app
app.function("process_data", processDataFunction);

Conversation Store

Manage conversation state and context across multiple interactions.

/**
 * Interface for storing conversation state
 */
interface ConversationStore {
  /** Store conversation data */
  set(conversationId: string, value: any, expiresAt?: number): Promise<void>;
  /** Retrieve conversation data */
  get<T = any>(conversationId: string): Promise<T | undefined>;
  /** Remove conversation data */
  delete(conversationId: string): Promise<void>;
}

/**
 * In-memory implementation of ConversationStore
 */
class MemoryStore implements ConversationStore {
  constructor();
  
  async set(conversationId: string, value: any, expiresAt?: number): Promise<void>;
  async get<T = any>(conversationId: string): Promise<T | undefined>;
  async delete(conversationId: string): Promise<void>;
}

/**
 * Middleware for adding conversation context to requests
 * @param store - Conversation store instance
 * @param options - Context options
 */
function conversationContext(
  store: ConversationStore,
  options?: ConversationContextOptions
): Middleware<AnyMiddlewareArgs>;

interface ConversationContextOptions {
  /** Custom function to extract conversation ID */
  getConversationId?: (args: AnyMiddlewareArgs) => string | undefined;
  /** Context property name (defaults to 'conversation') */
  contextKey?: string;
}

Usage Examples:

import { App, MemoryStore, conversationContext } from "@slack/bolt";

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

// Create conversation store
const convoStore = new MemoryStore();

// Add conversation context middleware
app.use(conversationContext(convoStore));

// Use conversation context in listeners
app.message("start survey", async ({ message, context, say }) => {
  // Initialize conversation state
  await context.conversation.set("survey_step", 1);
  await context.conversation.set("responses", {});
  
  await say("Let's start the survey! What's your name?");
});

app.message(async ({ message, context, say }) => {
  const step = await context.conversation.get("survey_step");
  const responses = await context.conversation.get("responses") || {};
  
  if (step === 1) {
    responses.name = message.text;
    await context.conversation.set("survey_step", 2);
    await context.conversation.set("responses", responses);
    
    await say("Thanks! What's your favorite color?");
  } else if (step === 2) {
    responses.color = message.text;
    await context.conversation.set("survey_step", 3);
    await context.conversation.set("responses", responses);
    
    await say(`Great! So your name is ${responses.name} and your favorite color is ${responses.color}. Survey complete!`);
    
    // Clear conversation state
    await context.conversation.delete("survey_step");
    await context.conversation.delete("responses");
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-slack--bolt

docs

advanced-features.md

core-application.md

index.md

middleware.md

receivers.md

request-verification.md

tile.json