slack

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package slack holds the bot's Slack identity: a Socket Mode connection, mentions turned into inbound events, and the four ways the conductor talks back. It implements conductor.Source and knows nothing about sessions, tasks or briefs.

Index

Constants

View Source
const Kind = "slack"

Kind is the source kind Slack sessions are recorded under.

View Source
const MaxMessageChars = 4000

MaxMessageChars is Slack's own per-message limit. Longer text is split at the last newline before the limit and posted as consecutive messages.

Variables

This section is empty.

Functions

func ParseRef

func ParseRef(ref string) (channel, thread, trigger string, err error)

ParseRef splits a Ref.

func Ref

func Ref(channel, thread, trigger string) string

Ref is what the conductor carries around for one turn: the channel, the thread it posts into, and the message it reacts on. Three parts rather than two because a reaction goes on the triggering message and a reply goes into the thread, and both have to survive a restart (the ref is persisted as turns.trigger_ref).

func Split

func Split(text string, limit int) []string

Split breaks text into pieces of at most limit characters, preferring the last newline that fits so a paragraph is not cut mid-sentence. It counts runes, not bytes: Slack's limit is characters and a multi-byte one must never be cut in half.

Types

type ChannelInfo added in v0.2.0

type ChannelInfo struct {
	ID   string
	Name string
}

ChannelInfo is one Slack channel as ListChannels reports it.

type Options

type Options struct {
	// AppToken is the xapp-… app-level token with connections:write. SENSITIVE.
	AppToken string
	// BotToken is the xoxb-… bot token. SENSITIVE.
	BotToken string
	Logger   *slog.Logger
	// contains filtered or unexported fields
}

Options configures the source.

type ReviewDoor added in v0.2.0

type ReviewDoor interface {
	LookupSlack(ctx context.Context, slackRef string) (sourceKey string, ok bool, err error)
	BindSlack(ctx context.Context, slackRef, sourceKey string) error
	IngestSlack(ctx context.Context, m ghreview.SlackMention) error
}

ReviewDoor is the GitHub source as Slack is allowed to see it: bind a thread to a PR review, and ingest a mention as if it had been an @ on that PR.

type Source

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

Source is the Slack integration.

func New

func New(opts Options) (*Source, error)

New builds the source. Nothing is dialled until Run.

func (*Source) Attach

func (s *Source) Attach(ctx context.Context, ref string, file conductor.Attachment) error

Attach uploads one file into the thread.

The modern upload flow declares the length before the bytes move, so FileSize and Filename are both required and a zero source uploads nothing at all — silently. Both are checked here rather than trusted to the library.

func (*Source) Edit

func (s *Source) Edit(ctx context.Context, ref, msgID string, out conductor.Outbound) error

Edit replaces a message this source posted. Only the first part of a split message is ever edited, which is what a progress line is.

func (*Source) Events

func (s *Source) Events() <-chan conductor.InboundEvent

Events implements conductor.Source. The channel closes when Run returns.

func (*Source) FetchTranscript

func (s *Source) FetchTranscript(ctx context.Context, ref string) ([]conductor.BriefEntry, error)

FetchTranscript reads the thread, oldest first. The bot's own placeholder and progress messages are left out — they are noise, not conversation — and its finals are kept.

func (*Source) Kind

func (s *Source) Kind() string

Kind implements conductor.Source.

func (*Source) ListChannels added in v0.2.0

func (s *Source) ListChannels(ctx context.Context) ([]ChannelInfo, error)

ListChannels pages the conversations the bot is in. It is how the Channels screen seeds the catalogue before the first mention. Archived channels are left out.

func (*Source) MirrorKey

func (s *Source) MirrorKey(ref string) (string, bool)

MirrorKey is the session key a ref belongs to, so the conductor can keep a readable copy of this thread in the Podium UI. It is the same key emit builds, out of the same two parts of the ref — the channel and the thread, never the triggering message, because the copy is of the conversation and not of one turn of it.

func (*Source) Post

func (s *Source) Post(ctx context.Context, ref string, out conductor.Outbound) (string, error)

Post says something new. Text over Slack's per-message limit is split at the last newline that fits and posted as consecutive messages; the id returned is the first one's, because that is the message progress edits address.

func (*Source) React

func (s *Source) React(ctx context.Context, ref string, kind conductor.Reaction) error

React shows a turn's state on the message that started it, so a thread shows one state rather than a history of them. "Already reacted" and "no reaction" are both fine outcomes and not errors.

Only the running mark is ever removed, and only by the outcome that replaces it. A turn's reactions go on the message that TRIGGERED it — a message a human has just sent, which is a different message every turn — so nothing of this bot's can already be on it, and the state machine is only ever working → done | failed. Removing the two emoji it was not setting on every call meant three requests a turn that Slack answered "no_reaction" to, two of them ahead of the working mark, where somebody is waiting to see that they were heard.

func (*Source) Run

func (s *Source) Run(ctx context.Context) error

Run learns the bot's own identity and then holds the Socket Mode connection until ctx is cancelled. Reconnects are the library's; this only logs and counts them.

func (*Source) SetReview added in v0.2.0

func (s *Source) SetReview(r ReviewDoor)

SetReview attaches the GitHub App source. Called from agent.New before Run; nil is "GitHub is not configured" and leaves mention handling unchanged.

Jump to

Keyboard shortcuts

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