slackbot

package
v1.498.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CreateSlackBotRequest

type CreateSlackBotRequest struct {
	Name   string                 `json:"name"`
	Scope  entities.ResourceScope `json:"scope,omitempty"`
	TeamID string                 `json:"team_id,omitempty"`
	// Teams is an explicit list of team IDs (e.g. ["org/team-slug"]) whose settings
	// (MCP servers, env vars, Bedrock config, etc.) will be merged into sessions
	// created by this bot. When omitted, the server falls back to the authenticated
	// user's team memberships at creation time.
	Teams               []string `json:"teams,omitempty"`
	BotTokenSecretName  string   `json:"bot_token_secret_name,omitempty"`
	BotTokenSecretKey   string   `json:"bot_token_secret_key,omitempty"`
	AllowedEventTypes   []string `json:"allowed_event_types,omitempty"`
	AllowedChannelNames []string `json:"allowed_channel_names,omitempty"`
	// AllowedUserIDs is the list of Slack user IDs allowed to trigger the bot.
	// Empty means all users are allowed. Matching is exact (e.g., "U012AB3CD").
	AllowedUserIDs []string               `json:"allowed_user_ids,omitempty"`
	SessionConfig  *SlackBotSessionConfig `json:"session_config,omitempty"`
	MaxSessions    int                    `json:"max_sessions,omitempty"`
	// NotifyOnSessionCreated controls whether the bot posts a Slack message with
	// the session URL when a new session is created. Defaults to true.
	NotifyOnSessionCreated *bool `json:"notify_on_session_created,omitempty"`
	// AllowBotMessages controls whether the bot processes messages posted by other bots.
	// Defaults to false to prevent recursive session creation.
	AllowBotMessages *bool `json:"allow_bot_messages,omitempty"`
	// BotToken is the Slack bot token (xoxb-...). Write-only: stored in K8s Secret, never returned.
	BotToken string `json:"bot_token,omitempty"`
	// AppToken is the Slack app-level token (xapp-...). Write-only: stored in K8s Secret, never returned.
	AppToken string `json:"app_token,omitempty"`
}

CreateSlackBotRequest is the request body for creating a SlackBot

type Handlers

type Handlers struct {
	// contains filtered or unexported fields
}

Handlers provides SlackBot management REST API, implementing app.CustomHandler

func NewHandlers

func NewHandlers(repo repositories.SlackBotRepository) *Handlers

NewHandlers creates a new SlackBot Handlers instance (management API only). Socket Mode event handling is managed separately by SlackSocketManager.

func (*Handlers) GetName

func (h *Handlers) GetName() string

GetName returns the name of this handler for logging

func (*Handlers) RegisterRoutes

func (h *Handlers) RegisterRoutes(e *echo.Echo) error

RegisterRoutes registers SlackBot management routes. Note: Slack events are received via Socket Mode (not HTTP webhook).

type SlackBotController

type SlackBotController struct {
	// contains filtered or unexported fields
}

SlackBotController handles SlackBot management API requests

func NewSlackBotController

func NewSlackBotController(repo repositories.SlackBotRepository) *SlackBotController

NewSlackBotController creates a new SlackBotController

func (*SlackBotController) CreateSlackBot

func (c *SlackBotController) CreateSlackBot(ctx echo.Context) error

CreateSlackBot handles POST /slackbots

func (*SlackBotController) DeleteSlackBot

func (c *SlackBotController) DeleteSlackBot(ctx echo.Context) error

DeleteSlackBot handles DELETE /slackbots/:id

func (*SlackBotController) GetSlackBot

func (c *SlackBotController) GetSlackBot(ctx echo.Context) error

GetSlackBot handles GET /slackbots/:id

func (*SlackBotController) ListSlackBots

func (c *SlackBotController) ListSlackBots(ctx echo.Context) error

ListSlackBots handles GET /slackbots

func (*SlackBotController) UpdateSlackBot

func (c *SlackBotController) UpdateSlackBot(ctx echo.Context) error

UpdateSlackBot handles PUT /slackbots/:id

type SlackBotEventHandler

type SlackBotEventHandler struct {
	// contains filtered or unexported fields
}

SlackBotEventHandler handles incoming Slack events (via Socket Mode) and manages sessions

func NewSlackBotEventHandler

func NewSlackBotEventHandler(
	repo repositories.SlackBotRepository,
	sessionManager repositories.SessionManager,
	defaultBotTokenSecretName string,
	defaultBotTokenSecretKey string,
	channelResolver *SlackChannelResolver,
	baseURL string,
	dryRun bool,
	memoryRepo repositories.MemoryRepository,
	sessionProfileRepo repositories.SessionProfileRepository,
) *SlackBotEventHandler

NewSlackBotEventHandler creates a new SlackBotEventHandler

func (*SlackBotEventHandler) ProcessEvent

func (h *SlackBotEventHandler) ProcessEvent(ctx context.Context, botID string, payload SlackPayload) error

ProcessEvent processes a parsed Slack event received via Socket Mode. botID should be the SlackBot entity ID or slackBotDefaultID ("default"). This method is called by SlackSocketWorker after acknowledging the event to Slack.

type SlackBotResponse

type SlackBotResponse struct {
	ID                     string                  `json:"id"`
	Name                   string                  `json:"name"`
	UserID                 string                  `json:"user_id"`
	Scope                  entities.ResourceScope  `json:"scope,omitempty"`
	TeamID                 string                  `json:"team_id,omitempty"`
	Teams                  []string                `json:"teams,omitempty"`
	Status                 entities.SlackBotStatus `json:"status"`
	BotTokenSecretName     string                  `json:"bot_token_secret_name,omitempty"`
	BotTokenSecretKey      string                  `json:"bot_token_secret_key,omitempty"`
	AllowedEventTypes      []string                `json:"allowed_event_types,omitempty"`
	AllowedChannelNames    []string                `json:"allowed_channel_names,omitempty"`
	AllowedUserIDs         []string                `json:"allowed_user_ids,omitempty"`
	SessionConfig          *SlackBotSessionConfig  `json:"session_config,omitempty"`
	MaxSessions            int                     `json:"max_sessions"`
	NotifyOnSessionCreated bool                    `json:"notify_on_session_created"`
	AllowBotMessages       bool                    `json:"allow_bot_messages"`
	CreatedAt              time.Time               `json:"created_at"`
	UpdatedAt              time.Time               `json:"updated_at"`
}

SlackBotResponse is the API response for a SlackBot

type SlackBotSessionConfig

type SlackBotSessionConfig struct {
	InitialMessageTemplate string                 `json:"initial_message_template,omitempty"`
	ReuseMessageTemplate   string                 `json:"reuse_message_template,omitempty"`
	Tags                   map[string]string      `json:"tags,omitempty"`
	Environment            map[string]string      `json:"environment,omitempty"`
	Params                 *SlackBotSessionParams `json:"params,omitempty"`
	MemoryKey              map[string]string      `json:"memory_key,omitempty"`
}

SlackBotSessionConfig is the session configuration for a SlackBot

type SlackBotSessionParams

type SlackBotSessionParams struct {
	AgentType string `json:"agent_type,omitempty"`
	Oneshot   bool   `json:"oneshot,omitempty"`
	AuthProxy *bool  `json:"auth_proxy,omitempty"`
	// RepoFullName is the full name of the GitHub repository to clone (e.g. "org/repo").
	// When set, this repository is always used for sessions created by this SlackBot,
	// taking priority over any repository auto-detected from the Slack message text.
	RepoFullName string `json:"repo_full_name,omitempty"`
}

SlackBotSessionParams contains session parameters for SlackBot sessions

type SlackChannelResolver

type SlackChannelResolver struct {
	// contains filtered or unexported fields
}

SlackChannelResolver resolves Slack channel IDs to names using the Slack API, with a two-level cache: in-memory (sync.Map) and a Kubernetes ConfigMap for persistence.

func NewSlackChannelResolver

func NewSlackChannelResolver(kubeClient kubernetes.Interface, namespace string) *SlackChannelResolver

NewSlackChannelResolver creates a new SlackChannelResolver

func (*SlackChannelResolver) FetchThreadReplies

func (r *SlackChannelResolver) FetchThreadReplies(ctx context.Context, channel, threadTS, botToken string) ([]SlackMessage, error)

FetchThreadReplies fetches all messages in a Slack thread using the conversations.replies API. channel is the Slack channel ID and threadTS is the root message timestamp. Returns messages sorted by timestamp (oldest first), including the root message. Requires a bot token with channels:history or groups:history scope.

func (*SlackChannelResolver) GetBotToken

func (r *SlackChannelResolver) GetBotToken(ctx context.Context, secretName, secretKey string) (string, error)

GetBotToken retrieves the Slack bot token from a Kubernetes Secret.

func (*SlackChannelResolver) PostMessage

func (r *SlackChannelResolver) PostMessage(ctx context.Context, channel, threadTS, text, botToken string) error

PostMessage posts a message to a Slack channel, optionally in a thread. If threadTS is non-empty, the message is posted as a thread reply. Requires a bot token with chat:write scope.

func (*SlackChannelResolver) ResolveChannelName

func (r *SlackChannelResolver) ResolveChannelName(ctx context.Context, channelID, botToken string) (string, error)

ResolveChannelName resolves a Slack channel ID to its name. Resolution order:

  1. In-memory cache
  2. Kubernetes ConfigMap (persistent)
  3. Slack API conversations.info (requires bot token with channels:read / groups:read scope)

func (*SlackChannelResolver) WithSlackAPIBase

func (r *SlackChannelResolver) WithSlackAPIBase(base string) *SlackChannelResolver

WithSlackAPIBase overrides the Slack API base URL. Intended for testing only; production callers should use the default (https://slack.com/api).

type SlackEvent

type SlackEvent struct {
	Type     string `json:"type"`
	SubType  string `json:"subtype,omitempty"`
	BotID    string `json:"bot_id,omitempty"`
	Text     string `json:"text"`
	User     string `json:"user"`
	Channel  string `json:"channel"`
	Ts       string `json:"ts"`
	ThreadTs string `json:"thread_ts,omitempty"`
}

SlackEvent represents the inner Slack event

type SlackMessage

type SlackMessage struct {
	User    string `json:"user"`
	BotID   string `json:"bot_id,omitempty"`
	Text    string `json:"text"`
	Ts      string `json:"ts"`
	SubType string `json:"subtype,omitempty"`
}

SlackMessage represents a single Slack message returned by conversations.replies.

type SlackPayload

type SlackPayload struct {
	Type      string      `json:"type"`
	Challenge string      `json:"challenge,omitempty"`
	TeamID    string      `json:"team_id,omitempty"`
	Event     *SlackEvent `json:"event,omitempty"`
}

SlackPayload represents the outer Slack event payload structure

type SlackSocketManager

type SlackSocketManager struct {
	// contains filtered or unexported fields
}

SlackSocketManager discovers registered SlackBots and manages one leader-elected socket worker per bot group:

  • "default": all bots with no custom bot token secret
  • <slackbot-id>: each bot with a custom BotTokenSecretName

func NewSlackSocketManager

func NewSlackSocketManager(
	kubeClient kubernetes.Interface,
	namespace string,
	repo repoports.SlackBotRepository,
	eventHandler *SlackBotEventHandler,
	channelResolver *SlackChannelResolver,
	cfg SlackSocketManagerConfig,
) *SlackSocketManager

NewSlackSocketManager creates a new SlackSocketManager

func (*SlackSocketManager) Run

func (m *SlackSocketManager) Run(ctx context.Context)

Run starts the reconciliation loop. On each tick, it discovers SlackBots and starts/stops leader-elected socket workers.

func (*SlackSocketManager) Stop

func (m *SlackSocketManager) Stop()

Stop cancels all running workers

type SlackSocketManagerConfig

type SlackSocketManagerConfig struct {
	DefaultAppTokenSecretName string
	DefaultAppTokenSecretKey  string
	DefaultBotTokenSecretName string
	DefaultBotTokenSecretKey  string
	ReconcileInterval         time.Duration
	LeaderElectionConfig      schedule.LeaderElectionConfig
}

SlackSocketManagerConfig holds configuration for SlackSocketManager

type SlackSocketWorker

type SlackSocketWorker struct {
	// contains filtered or unexported fields
}

SlackSocketWorker manages one Socket Mode WebSocket connection for a Slack App. For the "default" group (bots with no custom token), botID is "default". For custom bots, botID is the SlackBot entity ID.

func NewSlackSocketWorker

func NewSlackSocketWorker(
	botID string,
	appTokenSecretName string,
	appTokenSecretKey string,
	botTokenSecretName string,
	botTokenSecretKey string,
	channelResolver *SlackChannelResolver,
	eventHandler *SlackBotEventHandler,
) *SlackSocketWorker

NewSlackSocketWorker creates a new SlackSocketWorker

func (*SlackSocketWorker) Run

func (w *SlackSocketWorker) Run(ctx context.Context)

Run connects to Slack via Socket Mode and processes events until ctx is cancelled. If the connection drops unexpectedly, it retries with exponential backoff.

type UpdateSlackBotRequest

type UpdateSlackBotRequest struct {
	Name   string                  `json:"name,omitempty"`
	Status entities.SlackBotStatus `json:"status,omitempty"`
	// Teams is an explicit list of team IDs (e.g. ["org/team-slug"]) whose settings
	// will be merged into sessions created by this bot. When omitted, the server
	// refreshes from the authenticated user's current team memberships.
	Teams []string `json:"teams,omitempty"`
	// BotTokenSecretName is a pointer to allow clearing the value by passing an empty string "".
	// nil means "not provided / do not change"; "" means "clear (revert to global default)".
	BotTokenSecretName  *string  `json:"bot_token_secret_name"`
	BotTokenSecretKey   *string  `json:"bot_token_secret_key"`
	AllowedEventTypes   []string `json:"allowed_event_types,omitempty"`
	AllowedChannelNames []string `json:"allowed_channel_names,omitempty"`
	// AllowedUserIDs is the list of Slack user IDs allowed to trigger the bot.
	// Empty means all users are allowed. Matching is exact (e.g., "U012AB3CD").
	AllowedUserIDs []string               `json:"allowed_user_ids,omitempty"`
	SessionConfig  *SlackBotSessionConfig `json:"session_config,omitempty"`
	MaxSessions    int                    `json:"max_sessions,omitempty"`
	// NotifyOnSessionCreated controls whether the bot posts a Slack message with
	// the session URL when a new session is created. Defaults to true.
	NotifyOnSessionCreated *bool `json:"notify_on_session_created,omitempty"`
	// AllowBotMessages controls whether the bot processes messages posted by other bots.
	// Defaults to false to prevent recursive session creation.
	AllowBotMessages *bool `json:"allow_bot_messages,omitempty"`
	// BotToken is the Slack bot token (xoxb-...). Write-only: stored in K8s Secret, never returned.
	BotToken string `json:"bot_token,omitempty"`
	// AppToken is the Slack app-level token (xapp-...). Write-only: stored in K8s Secret, never returned.
	AppToken string `json:"app_token,omitempty"`
}

UpdateSlackBotRequest is the request body for updating a SlackBot

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL