Documentation
¶
Overview ¶
Package mirageslack provides a Slack Apps dispatcher / multiplexer for developer environments.
See docs/ARCHITECTURE.md for the design rationale and CLAUDE.md for maintenance hand-off notes.
Index ¶
- Constants
- Variables
- func Run(ctx context.Context, args []string) error
- type App
- func (a *App) HandleEvent(w http.ResponseWriter, r *http.Request)
- func (a *App) HandleInteractive(w http.ResponseWriter, r *http.Request)
- func (a *App) HandleSlashCommand(w http.ResponseWriter, r *http.Request)
- func (a *App) Handler() http.Handler
- func (a *App) Serve(ctx context.Context, addr string) error
- type CLI
- type Column
- type CommandConfig
- type Config
- type Entry
- type RoutingConfig
- type ServerConfig
- type ServerPaths
- type SlackConfig
- type SlackListClient
- func (c *SlackListClient) DeleteList(ctx context.Context, fileID string) error
- func (c *SlackListClient) Ensure(ctx context.Context) (string, error)
- func (c *SlackListClient) GrantViewAccessToChannel(ctx context.Context, channelID string) error
- func (c *SlackListClient) Launch(ctx context.Context, name, channel string, protect bool) error
- func (c *SlackListClient) ListEntries(ctx context.Context) ([]Entry, error)
- func (c *SlackListClient) ListID() string
- func (c *SlackListClient) ListName() string
- func (c *SlackListClient) ListPermalink() string
- func (c *SlackListClient) Register(ctx context.Context, name, endpoint string) error
- func (c *SlackListClient) Terminate(ctx context.Context, name string) error
- func (c *SlackListClient) Unregister(ctx context.Context, name string) error
- type SlashCommand
Constants ¶
const ( ColName = "name" ColEndpoint = "endpoint" ColLaunched = "launched" ColLaunchedChannel = "launched_channel" ColProtected = "protected" )
Column keys for the mirage-slack Slack List schema.
Variables ¶
var Schema = []Column{ {Key: ColName, Name: "Name", Type: "text", IsPrimaryColumn: true}, {Key: ColEndpoint, Name: "Endpoint", Type: "link"}, {Key: ColLaunched, Name: "Launched", Type: "checkbox"}, {Key: ColLaunchedChannel, Name: "Launched Channel", Type: "channel"}, {Key: ColProtected, Name: "Protected", Type: "checkbox"}, }
Schema is the fixed Slack List schema that mirage-slack owns.
var Version = "0.2.1"
Version is the release version reported by the binary.
Managed by tagpr (https://github.com/Songmu/tagpr) — the value here is bumped automatically when tagpr cuts a release. Do not hand-edit outside of that flow.
Functions ¶
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App bundles the runtime state needed to serve mirage-slack.
func NewApp ¶
NewApp builds an App and ensures the Slack List is ready (discovered or created) before returning.
func (*App) HandleEvent ¶
func (a *App) HandleEvent(w http.ResponseWriter, r *http.Request)
HandleEvent is the Events API entrypoint. url_verification challenges are answered here; everything else is forwarded using the event's channel_id.
func (*App) HandleInteractive ¶
func (a *App) HandleInteractive(w http.ResponseWriter, r *http.Request)
HandleInteractive is the forward-only entrypoint for block actions, modal submissions, and shortcuts.
func (*App) HandleSlashCommand ¶
func (a *App) HandleSlashCommand(w http.ResponseWriter, r *http.Request)
HandleSlashCommand dispatches slash command requests to either the internal subcommand pipeline or the forward pipeline.
type CLI ¶
type CLI struct {
Config string `help:"path to config file (jsonnet)" short:"c" default:"config.jsonnet"`
LogFormat string `help:"log output format (json or text)" enum:"json,text" default:"json"`
LogLevel string `help:"log level (debug, info, warn, error)" enum:"debug,info,warn,error" default:"info"`
Version kong.VersionFlag `help:"show version and exit" short:"V"`
Run runCmd `cmd:"" default:"withargs" help:"run the mirage-slack HTTP server"`
InitConfig initConfigCmd `cmd:"init-config" help:"emit a starter config.jsonnet"`
}
CLI is the top-level kong grammar for the `mirage-slack` binary.
type Column ¶
type Column struct {
Key string `json:"key"`
Name string `json:"name"`
Type string `json:"type"`
IsPrimaryColumn bool `json:"is_primary_column,omitempty"`
}
Column describes one column in a Slack List schema.
type CommandConfig ¶
type CommandConfig struct {
Name string `json:"name"`
}
type Config ¶
type Config struct {
Slack SlackConfig `json:"slack"`
Command CommandConfig `json:"command"`
Routing RoutingConfig `json:"routing"`
Server ServerConfig `json:"server"`
}
Config is the top-level configuration loaded from a jsonnet file.
func LoadConfig ¶
LoadConfig evaluates the jsonnet file at path and decodes it into a Config. Native functions (ssm, env) are registered against the provided context.
func (*Config) DefaultEndpointProtectEnabled ¶
DefaultEndpointProtectEnabled returns the effective value with default applied.
type Entry ¶
type Entry struct {
ItemID string
Name string
Endpoint string
Launched bool
LaunchedChannel string
Protected bool
}
Entry is one mirage-slack environment row.
type RoutingConfig ¶
type ServerConfig ¶ added in v0.1.1
type ServerConfig struct {
Paths ServerPaths `json:"paths"`
}
ServerConfig overrides the HTTP mount points exposed by mirage-slack.
type ServerPaths ¶ added in v0.1.1
type ServerPaths struct {
Commands string `json:"commands"`
Interactive string `json:"interactive"`
Events string `json:"events"`
}
ServerPaths maps each Slack entrypoint to its URL path. Empty fields fall back to the defaults shown in DefaultServerPaths.
func DefaultServerPaths ¶ added in v0.1.1
func DefaultServerPaths() ServerPaths
DefaultServerPaths returns the default URL paths used when the config leaves the corresponding fields empty.
type SlackConfig ¶
type SlackConfig struct {
SigningSecret string `json:"signing_secret"`
BotToken string `json:"bot_token"`
// ListName identifies the bot-owned Slack List. At run startup mirage-slack
// looks up a bot-owned list with this title; if none exists, it creates one.
// Defaults to the slash command name without the leading slash (e.g. command
// "/mirage-slack" yields "mirage-slack"), so running multiple instances with
// distinct command names yields distinct list titles with zero extra config.
ListName string `json:"list_name"`
}
type SlackListClient ¶
type SlackListClient struct {
// contains filtered or unexported fields
}
SlackListClient is a thin wrapper around the slackLists.* Web API methods plus a handful of files.* calls that we use to discover the bot-owned list.
slack-go/slack does not expose the Lists API yet (2026-04), so we call the raw endpoints with a bot token.
func NewSlackListClient ¶
func NewSlackListClient(token, listName string) *SlackListClient
NewSlackListClient constructs a client. Call Ensure before any read/write operation to populate list_id / column IDs. listName must be non-empty; Config.applyDefaults derives it from the configured slash command name.
func (*SlackListClient) DeleteList ¶ added in v0.2.0
func (c *SlackListClient) DeleteList(ctx context.Context, fileID string) error
DeleteList removes a bot-owned Slack List via files.delete. Refuses to delete the currently active list (file_id equal to ListID()) so the caller cannot accidentally wipe the live entries. slackLists.delete returns unknown_method, but files.delete works against list-type files.
func (*SlackListClient) Ensure ¶
func (c *SlackListClient) Ensure(ctx context.Context) (string, error)
Ensure makes sure mirage-slack has a usable list:
- auth.test → bot user_id + team_id + team url
- files.list?types=lists → find bot-owned list whose title matches
- if not found, slackLists.create with the mirage-slack schema
- cache list_id + column_id map + permalink components on the client
Emits INFO logs at every step so a slow startup (typically caused by files.list scanning many lists in a large workspace) is visible.
func (*SlackListClient) GrantViewAccessToChannel ¶
func (c *SlackListClient) GrantViewAccessToChannel(ctx context.Context, channelID string) error
GrantViewAccessToChannel shares the bot-owned list with the given channel as "Can view" (read-only). Idempotent: Slack treats the call as upsert. Needed so Slack's automatic unfurl of the permalink works for channel members who don't otherwise have access to the bot-owned list.
func (*SlackListClient) Launch ¶
Launch binds an already-registered entry to the given channel and flips its launched flag on. Rejects the operation if the channel is already bound to a different entry (v1 rule: one launched entry per channel).
func (*SlackListClient) ListEntries ¶
func (c *SlackListClient) ListEntries(ctx context.Context) ([]Entry, error)
ListEntries returns every mirage-slack environment row.
func (*SlackListClient) ListID ¶
func (c *SlackListClient) ListID() string
ListID returns the resolved list_id (available after Ensure).
func (*SlackListClient) ListName ¶
func (c *SlackListClient) ListName() string
ListName returns the configured list name (primary identifier).
func (*SlackListClient) ListPermalink ¶
func (c *SlackListClient) ListPermalink() string
ListPermalink returns the Slack URL for the bot-owned list. Posting this URL in a message triggers Slack's automatic unfurl.
func (*SlackListClient) Register ¶
func (c *SlackListClient) Register(ctx context.Context, name, endpoint string) error
Register creates a new entry with the given endpoint, or updates an existing entry's endpoint while preserving its launch state.
func (*SlackListClient) Terminate ¶
func (c *SlackListClient) Terminate(ctx context.Context, name string) error
Terminate clears the launch state of a registered entry.
func (*SlackListClient) Unregister ¶
func (c *SlackListClient) Unregister(ctx context.Context, name string) error
Unregister deletes the entry by name.