bot

package
v0.0.0-...-72f1ef6 Latest Latest
Warning

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

Go to latest
Published: Jan 17, 2026 License: GPL-3.0 Imports: 23 Imported by: 0

Documentation

Overview

Package bot implements the coordination logic between GitHub, Slack, and notifications.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConfigManager

type ConfigManager interface {
	Config(org string) (*config.RepoConfig, bool)
	LoadConfig(ctx context.Context, org string) error
	ReloadConfig(ctx context.Context, org string) error
	Domain(org string) string
	WorkspaceName(org string) string
	ChannelsForRepo(org, repo string) []string
	ReminderDMDelay(org, channelName string) int
	When(org, channelName string) string
	SetGitHubClient(org string, client any)
	SetWorkspaceName(workspaceName string)
}

ConfigManager defines configuration operations.

type Coordinator

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

Coordinator coordinates between GitHub, Slack, and notifications for a single org.

func New

func New(
	ctx context.Context,
	slackClient SlackClient,
	githubClient GitHubClient,
	configManager ConfigManager,
	notifier *notify.Manager,
	sprinklerURL string,
	stateStore StateStore,
) *Coordinator

New creates a new bot coordinator for a single GitHub organization.

func (*Coordinator) PollAndReconcile

func (c *Coordinator) PollAndReconcile(ctx context.Context)

PollAndReconcile checks all open PRs and ensures notifications are sent. This runs every 5 minutes as a safety net to catch anything sprinkler missed.

func (*Coordinator) RunWithSprinklerClient

func (c *Coordinator) RunWithSprinklerClient(ctx context.Context) error

RunWithSprinklerClient runs the bot using the official sprinkler client library.

func (*Coordinator) StartupReconciliation

func (c *Coordinator) StartupReconciliation(ctx context.Context)

StartupReconciliation runs once at startup to catch up on any missed notifications. This ensures that if the service was down, we still notify about PRs that need attention.

type GitHubClient

type GitHubClient interface {
	InstallationToken(ctx context.Context) string
	Organization() string
	Client() any
	FindPRsForCommit(ctx context.Context, owner, repo, commitSHA string) ([]int, error)
	RefreshToken(ctx context.Context) error
}

GitHubClient defines GitHub operations needed by bot.

type PRSearcher

type PRSearcher interface {
	ListOpenPRs(ctx context.Context, org string, updatedSinceHours int) ([]github.PRSnapshot, error)
	ListClosedPRs(ctx context.Context, org string, updatedSinceHours int) ([]github.PRSnapshot, error)
}

PRSearcher defines GitHub PR search operations for polling.

type SlackClient

type SlackClient interface {
	PostThread(ctx context.Context, channelID, text string, attachments []slack.Attachment) (string, error)
	UpdateMessage(ctx context.Context, channelID, timestamp, text string) error
	UpdateDMMessage(ctx context.Context, userID, prURL, text string) error
	SendDirectMessage(ctx context.Context, userID, text string) (dmChannelID, messageTS string, err error)
	SendDirectMessageWithBlocks(ctx context.Context, userID string, blocks []slack.Block) (dmChannelID, messageTS string, err error)
	IsUserInChannel(ctx context.Context, channelID, userID string) bool
	IsUserActive(ctx context.Context, userID string) bool
	UserTimezone(ctx context.Context, userID string) (string, error)
	FindDMMessagesInHistory(ctx context.Context, userID, prURL string, since time.Time) ([]slackapi.DMLocation, error)
	ChannelHistory(ctx context.Context, channelID string, oldest, latest string, limit int) (*slack.GetConversationHistoryResponse, error)
	ResolveChannelID(ctx context.Context, channelName string) string
	IsBotInChannel(ctx context.Context, channelID string) bool
	BotInfo(ctx context.Context) (*slack.AuthTestResponse, error)
	WorkspaceInfo(ctx context.Context) (*slack.TeamInfo, error)
	PublishHomeView(ctx context.Context, userID string, blocks []slack.Block) error
	API() *slack.Client
}

SlackClient defines Slack operations needed by bot. Small interface - only methods we actually call.

type SprinklerMessage

type SprinklerMessage struct {
	Timestamp time.Time `json:"timestamp,omitempty"` // Event timestamp from sprinkler
	Type      string    `json:"type,omitempty"`      // Message type (e.g., "ping", "event")
	Event     string    `json:"event,omitempty"`     // GitHub event type
	Repo      string    `json:"repo,omitempty"`      // Repository name
	URL       string    `json:"url,omitempty"`       // GitHub URL for reference
	PRNumber  int       `json:"pr_number,omitempty"` // PR number extracted from URL
}

SprinklerMessage represents a message from sprinkler.

type StateStore

type StateStore interface {
	Thread(ctx context.Context, owner, repo string, number int, channelID string) (cache.ThreadInfo, bool)
	SaveThread(ctx context.Context, owner, repo string, number int, channelID string, info cache.ThreadInfo) error
	LastDM(ctx context.Context, userID, prURL string) (time.Time, bool)
	RecordDM(ctx context.Context, userID, prURL string, sentAt time.Time) error
	DMMessage(ctx context.Context, userID, prURL string) (state.DMInfo, bool)
	SaveDMMessage(ctx context.Context, userID, prURL string, info state.DMInfo) error
	ListDMUsers(ctx context.Context, prURL string) []string
	LastDigest(ctx context.Context, userID, date string) (time.Time, bool)
	RecordDigest(ctx context.Context, userID, date string, sentAt time.Time) error
	QueuePendingDM(ctx context.Context, dm *state.PendingDM) error
	PendingDMs(ctx context.Context, before time.Time) ([]state.PendingDM, error)
	RemovePendingDM(ctx context.Context, id string) error
	WasProcessed(ctx context.Context, eventKey string) bool
	MarkProcessed(ctx context.Context, eventKey string, ttl time.Duration) error
	LastNotification(ctx context.Context, prURL string) time.Time
	RecordNotification(ctx context.Context, prURL string, notifiedAt time.Time) error
	LastReportSent(ctx context.Context, userID string) (time.Time, bool)
	RecordReportSent(ctx context.Context, userID string, sentAt time.Time) error
	Cleanup(ctx context.Context) error
	Close() error
}

StateStore interface for persistent state - allows dependency injection for testing.

type UserMapper

type UserMapper interface {
	SlackHandle(ctx context.Context, githubUsername, organization, domain string) (string, error)
	FormatUserMentions(ctx context.Context, githubUsernames []string, organization, domain string) string
}

UserMapper defines user mapping operations.

type UserTagInfo

type UserTagInfo struct {
	UserID         string
	IsInAnyChannel bool // True if user is member of at least one channel where they were tagged
}

UserTagInfo contains information about a user who was tagged in PR notifications.

Directories

Path Synopsis
Package cache provides thread information caching for bot operations.
Package cache provides thread information caching for bot operations.

Jump to

Keyboard shortcuts

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