chatops

package
v0.31.3 Latest Latest
Warning

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

Go to latest
Published: May 17, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateBindCode

func GenerateBindCode() (string, error)

GenerateBindCode generates an 8-character unambiguous binding code using CSPRNG. Uses charset without 0/O/1/l/I to reduce user error in manual entry. Returns error only on crypto/rand failure (should be extremely rare).

func RegisterCommand

func RegisterCommand(spec CommandSpec)

Types

type AuditEntry

type AuditEntry struct {
	NotificationConfID uint
	ChannelType        string
	ChannelUserID      string
	Command            string
	Args               map[string]any
	Result             string
	LatencyMs          int64
}

AuditEntry is the audit row written by the chain.

type AuditRecorder

type AuditRecorder interface {
	Record(ctx context.Context, e AuditEntry) error
}

AuditRecorder writes a single audit row. Implemented by app.AuditService.

type BindCodeConsumer

type BindCodeConsumer interface {
	ConsumeCode(ctx context.Context, code, channelType, channelUserID string) error
}

BindCodeConsumer consumes a /bind <code> request. Implemented by app.BindingService.

type BindingInfo

type BindingInfo struct {
	ID            uint
	ConfID        uint
	ChannelType   string
	ChannelUserID string
	ReplyLang     string
	PtAdmin       bool
	Allowed       bool
}

BindingInfo is the subset of binding data needed by the chain. Defined locally (instead of importing internal/app) to avoid an import cycle: internal/app already imports internal/chatops for GenerateBindCode.

type BindingLookup

type BindingLookup interface {
	FindByChannelUser(ctx context.Context, channelType, channelUserID string) (BindingInfo, bool, error)
}

BindingLookup resolves a (channel, user) pair to a BindingInfo.

type Button

type Button struct {
	Text         string `json:"text"`
	CallbackData string `json:"callback_data,omitempty"`
	URL          string `json:"url,omitempty"`
}

type CommandHandler

type CommandHandler func(ctx context.Context, args []string, src Source) (Reply, error)

type CommandRegistry

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

func DefaultRegistry

func DefaultRegistry() *CommandRegistry

func NewCommandRegistry

func NewCommandRegistry() *CommandRegistry

func (*CommandRegistry) Get

func (r *CommandRegistry) Get(name string) (CommandSpec, bool)

func (*CommandRegistry) List

func (r *CommandRegistry) List() []CommandSpec

func (*CommandRegistry) Register

func (r *CommandRegistry) Register(spec CommandSpec)

type CommandRegistryAPI

type CommandRegistryAPI interface {
	Get(name string) (CommandSpec, bool)
	List() []CommandSpec
}

CommandRegistryAPI abstracts CommandRegistry so the chain can be tested without depending on the concrete registry implementation.

type CommandReply

type CommandReply = Reply

type CommandSource

type CommandSource = Source

type CommandSpec

type CommandSpec struct {
	Name        string
	Description string
	Aliases     []string
	AdminOnly   bool
	Handler     CommandHandler
	RateLimit   *RateLimitSpec
}

type MessageChain

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

MessageChain dispatches inbound messages through the permission gate per plan T22 (binding → allowed → command parse → session → registry → ratelimit → admin check → handler).

func NewMessageChain

func NewMessageChain(
	registry CommandRegistryAPI,
	bindings BindingLookup,
	bindCoder BindCodeConsumer,
	audit AuditRecorder,
	rl RateLimiterAPI,
	sessions SessionStoreAPI,
	replier Replier,
) *MessageChain

NewMessageChain wires the dependencies. replier may be nil when there is no outbound channel (e.g. CLI debugging).

func (*MessageChain) Process

func (mc *MessageChain) Process(ctx context.Context, msg notify.InboundMessage) error

Process is the inbound entry point. It returns an error only on unrecoverable conditions (lookup failure, nil handler); business denies are surfaced via audit + reply, never as errors.

type RateLimitSpec

type RateLimitSpec struct {
	Per   time.Duration
	Burst int
}

type RateLimiter

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

func NewRateLimiter

func NewRateLimiter() *RateLimiter

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(channel, userID, command string) bool

type RateLimiterAPI

type RateLimiterAPI interface {
	Allow(channel, userID, command string) bool
}

RateLimiterAPI abstracts RateLimiter for the chain.

type Replier

type Replier interface {
	Reply(ctx context.Context, msg notify.InboundMessage, reply Reply) error
}

Replier is the channel-side reply egress (implemented by adapters T17-T20).

type Reply

type Reply struct {
	Text       string
	Buttons    [][]Button
	SilentDrop bool
}

type SessionState

type SessionState struct {
	Step      string
	Data      string
	Handler   CommandHandler
	ExpiresAt time.Time
}

type SessionStore

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

func NewSessionStore

func NewSessionStore() *SessionStore

func (*SessionStore) Clear

func (s *SessionStore) Clear(channel string, confID uint, userID string)

func (*SessionStore) Pending

func (s *SessionStore) Pending(channel string, confID uint, userID string) (SessionState, bool)

func (*SessionStore) Set

func (s *SessionStore) Set(channel string, confID uint, userID string, state SessionState, ttl time.Duration)

func (*SessionStore) Stop

func (s *SessionStore) Stop()

type SessionStoreAPI

type SessionStoreAPI interface {
	Pending(channel string, confID uint, userID string) (SessionState, bool)
	Set(channel string, confID uint, userID string, state SessionState, ttl time.Duration)
	Clear(channel string, confID uint, userID string)
}

SessionStoreAPI abstracts SessionStore for the chain.

type Source

type Source struct {
	ChannelType   string
	ChannelConfID uint
	ChannelUserID string
	Username      string
	ChatID        string
	ReplyLang     string
	PtAdmin       bool
	IsAdmin       bool
	BindingID     uint
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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