notify

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: 15 Imported by: 0

Documentation

Overview

Package notify handles user notifications and reminders.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatChannelMessageBase

func FormatChannelMessageBase(ctx context.Context, params MessageParams) string

FormatChannelMessageBase formats the base Slack channel message for a PR (without next actions). This is the single source of truth for channel message formatting. It handles emoji determination and base message assembly. Use FormatNextActionsSuffix to add next actions when needed.

func FormatNextActionsSuffix

func FormatNextActionsSuffix(ctx context.Context, params MessageParams) string

FormatNextActionsSuffix formats the next actions suffix for a channel message. Returns empty string if no next actions are present. Call this after FormatChannelMessageBase to build a complete message with user mentions.

func PrefixForAction

func PrefixForAction(action string) string

PrefixForAction returns the emoji prefix for a given action kind.

func PrefixForAnalysis

func PrefixForAnalysis(workflowState string, nextActions map[string]turn.Action) string

PrefixForAnalysis returns the emoji prefix based on workflow state and next actions. This is the primary function for determining PR emoji - it handles the logic: 1. Use WorkflowState as primary signal (most reliable) 2. Fall back to NextAction if no WorkflowState.

func PrefixForState deprecated

func PrefixForState(prState string) string

PrefixForState returns the emoji prefix for a given PR state. Exported for use by bot package to ensure consistent PR state display.

Deprecated: Use PrefixForAnalysis instead to derive emoji from NextAction.

func PrimaryAction

func PrimaryAction(nextActions map[string]turn.Action) string

PrimaryAction determines the primary action kind from a NextAction map. Returns the highest-priority action (lowest priority score).

Types

type ConfigManager

type ConfigManager interface {
	DailyRemindersEnabled(org string) bool
	ReminderDMDelay(org, channel string) int
}

ConfigManager interface abstracts config.Manager for testability. Used by Manager for notification preferences.

type Manager

type Manager struct {
	Tracker *NotificationTracker
	// contains filtered or unexported fields
}

Manager handles user notifications across multiple workspaces.

func New

func New(slackManager SlackManager, configManager ConfigManager, store Store) *Manager

New creates a new notification manager.

func (*Manager) NotifyUser

func (m *Manager) NotifyUser(ctx context.Context, workspaceID, userID, channelID, channelName string, pr PRInfo) error

NotifyUser sends a smart notification to a user about a PR using the configured logic. Implements delayed DM logic: if user was tagged in channel, delay by configured time. If user is not in channel where tagged, send DM immediately.

func (*Manager) Run

func (m *Manager) Run(ctx context.Context) error

Run starts the notification scheduler.

type MessageParams

type MessageParams struct {
	CheckResult *turn.CheckResponse
	Owner       string
	Repo        string
	PRNumber    int
	Title       string
	Author      string
	HTMLURL     string
	Domain      string
	ChannelName string // Optional: if provided and matches Repo (case-insensitive), shows short form #123
	UserMapper  UserMapper
}

MessageParams contains all parameters needed to format a channel message.

type NotificationTracker

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

NotificationTracker tracks notification timestamps in memory. Rate limiting state resets on service restart, which is acceptable.

func (*NotificationTracker) Cleanup

func (t *NotificationTracker) Cleanup(maxAge time.Duration)

Cleanup removes entries older than the specified age from all maps. This prevents unbounded memory growth while keeping recent entries for rate limiting.

func (*NotificationTracker) LastChannelNotification

func (t *NotificationTracker) LastChannelNotification(workspaceID, owner, repo string, number int) time.Time

LastChannelNotification returns when a PR was last mentioned in a channel.

func (*NotificationTracker) LastDMNotification

func (t *NotificationTracker) LastDMNotification(workspaceID, userID string) time.Time

LastDMNotification returns when a user was last DM'd.

func (*NotificationTracker) LastDailyReminder

func (t *NotificationTracker) LastDailyReminder(workspaceID, userID string) time.Time

LastDailyReminder returns when a user last received a daily reminder.

func (*NotificationTracker) LastUserPRChannelTag

func (t *NotificationTracker) LastUserPRChannelTag(workspaceID, userID, owner, repo string, number int) TagInfo

LastUserPRChannelTag returns tag info (timestamp and channel) for when a user was last tagged for a specific PR.

func (*NotificationTracker) UpdateChannelNotification

func (t *NotificationTracker) UpdateChannelNotification(workspaceID, owner, repo string, number int)

UpdateChannelNotification records that a PR was just mentioned in a channel.

func (*NotificationTracker) UpdateDMNotification

func (t *NotificationTracker) UpdateDMNotification(workspaceID, userID string)

UpdateDMNotification records that a user was just DM'd.

func (*NotificationTracker) UpdateDailyReminder

func (t *NotificationTracker) UpdateDailyReminder(workspaceID, userID string)

UpdateDailyReminder records that a user just received a daily reminder.

func (*NotificationTracker) UpdateUserPRChannelTag

func (t *NotificationTracker) UpdateUserPRChannelTag(workspaceID, userID, channelID, owner, repo string, number int)

UpdateUserPRChannelTag records that a user was just tagged in a channel for a specific PR. If called multiple times for same user/PR, only keeps the FIRST tag (earliest channel).

type PRInfo

type PRInfo struct {
	Owner         string
	Repo          string
	Title         string
	Author        string
	State         string // Deprecated: use WorkflowState and NextAction for emoji determination
	HTMLURL       string
	Number        int
	WorkflowState string                 // Workflow state from turnclient Analysis
	NextAction    map[string]turn.Action // Next actions from turnclient Analysis
}

PRInfo contains the minimal information needed to notify about a PR.

type SlackClient

type SlackClient interface {
	// User operations
	IsUserActive(ctx context.Context, userID string) bool
	IsUserInChannel(ctx context.Context, channelID, userID string) bool
	UserTimezone(ctx context.Context, userID string) (string, error)

	// DM operations
	SendDirectMessage(ctx context.Context, userID, text string) (dmChannelID, messageTS string, err error)
	UpdateDMMessage(ctx context.Context, userID, prURL, newText string) error
	HasRecentDMAboutPR(ctx context.Context, userID, prURL string) (bool, error)
	SaveDMMessageInfo(ctx context.Context, userID, prURL, dmChannelID, messageTS, message string) error

	// Legacy - for usermapping compatibility
	API() *slackapi.Client
}

SlackClient interface abstracts slack.Client methods used by notify package. This enables unit testing of notification logic without real Slack API calls.

type SlackManager

type SlackManager interface {
	Client(ctx context.Context, teamID string) (SlackClient, error)
}

SlackManager interface abstracts slack.Manager for testability. This allows us to mock Slack interactions in unit tests.

func WrapSlackManager

func WrapSlackManager(manager *slack.Manager) SlackManager

WrapSlackManager wraps a concrete slack.Manager to implement SlackManager interface. This enables dependency injection and testing.

type Store

type Store interface {
	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
}

Store interface for persistent DM queue management.

type TagInfo

type TagInfo struct {
	Timestamp time.Time
	ChannelID string
}

TagInfo stores when and where a user was tagged for a PR.

type UserMapper

type UserMapper interface {
	FormatUserMentions(ctx context.Context, githubUsers []string, owner, domain string) string
}

UserMapper interface for formatting user mentions in messages.

Jump to

Keyboard shortcuts

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