botswizard

package
v0.77.8 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package botswizard is a thin declarative wrapper over the framework's built-in wizard-param machinery (ChatData's AwaitingReplyTo plus AddWizardParam/GetWizardParam, where params ride in the AwaitingReplyTo query string and self-clear when it is reset).

Instead of hand-rolling one command per step and threading state by hand, you describe a wizard as an ordered list of typed Steps. The driver then handles:

  • routing each reply to the current step,
  • re-prompting on invalid input (Step.Parse returns an error),
  • /cancel and /back,
  • an optional inactivity TTL,
  • typed access to the collected values,
  • self-clearing state on completion.

One Wizard registers a single command (Wizard.Command); the current step index and all collected values live in the self-clearing wizard params, so there is no persistent state to leak.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrConversationExpired          = errors.New("conversation has expired")
	ErrConversationCorrupt          = errors.New("conversation state is corrupt")
	ErrConversationRevisionConflict = errors.New("conversation revision conflict")
)

Functions

func IsUniversalCancel added in v0.77.1

func IsUniversalCancel(text string) bool

Types

type ConversationAdapter added in v0.77.1

type ConversationAdapter struct{ Now func() time.Time }

ConversationAdapter migrates existing AwaitingReplyTo state lazily. New state is stored in namespaced wizard params; routing remains on the legacy AwaitingReplyTo path, preserving existing command matching behaviour.

func (ConversationAdapter) Cancel added in v0.77.1

func (a ConversationAdapter) Cancel(st state)

func (ConversationAdapter) Load added in v0.77.1

func (a ConversationAdapter) Load(st state) (ConversationState, bool)

Load preserves the original two-value API. It fails closed for expired or malformed persisted state; callers needing the reason should use LoadChecked.

func (ConversationAdapter) LoadChecked added in v0.77.1

func (a ConversationAdapter) LoadChecked(st state) (ConversationState, bool, error)

LoadChecked returns a typed error for malformed or expired persisted state. In either case it clears AwaitingReplyTo so a stale flow cannot be resumed.

func (ConversationAdapter) Save added in v0.77.1

func (a ConversationAdapter) Save(st state, value ConversationState) error

Save writes the supplied revision as-is. It is intended for migration and single-writer flows; concurrent callers must use SaveIfRevision.

func (ConversationAdapter) SaveIfRevision added in v0.77.1

func (a ConversationAdapter) SaveIfRevision(st state, value ConversationState, expectedRevision int64) error

SaveIfRevision stores the next revision only when expectedRevision matches the current state. An absent state has revision zero. This turns the legacy parameter store into a fail-closed optimistic-concurrency boundary.

type ConversationState added in v0.77.1

type ConversationState struct {
	Version   int
	Revision  int64
	Feature   FeatureID
	Flow      FlowID
	Step      StepID
	Payload   map[string]string
	ExpiresAt time.Time
}

ConversationState is the portable, versioned state contract for a feature flow. Payload is deliberately string-valued so it can be persisted through legacy BotChatData wizard params without a storage migration. Revision is observational when saved with Save; use SaveIfRevision to detect stale writes.

func (ConversationState) Expired added in v0.77.1

func (v ConversationState) Expired(now time.Time) bool

type FeatureID added in v0.77.1

type FeatureID string

FeatureID identifies the feature which owns a conversation.

type FlowID added in v0.77.1

type FlowID string

FlowID identifies a flow within a feature.

type Step

type Step struct {
	// Key is the wizard-param key the parsed value is stored under and the key
	// it is later read from in Values. Must not start with "_wz".
	Key string
	// Prompt is the question shown when the step is entered (HTML allowed).
	Prompt string
	// Parse validates and normalizes the raw user text into the value to store.
	// Returning an error re-prompts the SAME step with the error text shown
	// above the prompt. A nil Parse stores the trimmed text as-is.
	Parse func(raw string) (stored string, err error)
}

Step is one question in a wizard.

type StepID added in v0.77.1

type StepID string

StepID identifies the current step within a flow.

type Values

type Values map[string]string

Values holds the collected step values keyed by Step.Key, with typed getters.

func (Values) Int64

func (v Values) Int64(key string) int64

Int64 returns the value parsed as int64 (0 if absent/unparseable).

func (Values) String

func (v Values) String(key string) string

String returns the raw stored value for key.

func (Values) Time

func (v Values) Time(key, layout string) time.Time

Time returns the value parsed with layout (zero time if absent/unparseable).

type Wizard

type Wizard struct {
	// Code is the command code (also the AwaitingReplyTo path). Unique per bot.
	Code botsfw.CommandCode
	// Steps are asked in order.
	Steps []Step
	// OnComplete runs after the last step with all collected values. Its
	// message is returned to the user. State is already cleared when it runs.
	OnComplete func(whc botsfw.WebhookContext, v Values) (botmsg.MessageFromBot, error)
	// Intro is optional text prepended to the first prompt.
	Intro string
	// TTL, if > 0, abandons the wizard when this long passes since Start.
	TTL time.Duration
	// CancelText / TimeoutText override the default end messages.
	CancelText  string
	TimeoutText string
	// Now overrides the clock for TTL (tests); nil = time.Now.
	Now func() time.Time
}

Wizard is a declarative, multi-step, text-input dialog.

func (Wizard) Command

func (w Wizard) Command() botsfw.Command

Command returns the single command that drives every step of this wizard. Register it with the bot; arm the wizard from your entry command via Start.

func (Wizard) Start

func (w Wizard) Start(whc botsfw.WebhookContext, prefill Values) (botmsg.MessageFromBot, error)

Start arms the wizard and sends the first prompt. prefill lets an entry command supply leading answers (e.g. "/commit run a 5k" prefilling the title); each is validated through its Step.Parse and, if valid, that step is skipped.

Jump to

Keyboard shortcuts

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