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 ¶
- Variables
- func IsUniversalCancel(text string) bool
- type ConversationAdapter
- func (a ConversationAdapter) Cancel(st state)
- func (a ConversationAdapter) Load(st state) (ConversationState, bool)
- func (a ConversationAdapter) LoadChecked(st state) (ConversationState, bool, error)
- func (a ConversationAdapter) Save(st state, value ConversationState) error
- func (a ConversationAdapter) SaveIfRevision(st state, value ConversationState, expectedRevision int64) error
- type ConversationState
- type FeatureID
- type FlowID
- type Step
- type StepID
- type Values
- type Wizard
Constants ¶
This section is empty.
Variables ¶
Functions ¶
func IsUniversalCancel ¶ added in v0.77.1
Types ¶
type ConversationAdapter ¶ added in v0.77.1
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.
type FeatureID ¶ added in v0.77.1
type FeatureID string
FeatureID identifies the feature which owns a conversation.
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 Values ¶
Values holds the collected step values keyed by Step.Key, with typed getters.
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 ¶
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.