Documentation
¶
Overview ¶
Package messaging provides hook registry for persistent hook management
Package messaging provides response handling functionality for stateful interactions.
Index ¶
- Constants
- Variables
- type HookFactory
- type HookRegistry
- func (hr *HookRegistry) CreateHook(hookType models.HookType, params map[string]string, ...) (ResponseAction, error)
- func (hr *HookRegistry) IsRegistered(hookType models.HookType) bool
- func (hr *HookRegistry) ListRegisteredTypes() []models.HookType
- func (hr *HookRegistry) RegisterFactory(hookType models.HookType, factory HookFactory)
- type ResponseAction
- func CreateBranchHook(branchOptions []models.BranchOption, msgService Service) ResponseAction
- func CreateConversationHook(participantID string, msgService Service) ResponseAction
- func CreateGenAIHook(originalPrompt models.Prompt, msgService Service) ResponseAction
- func CreateStaticHook(msgService Service) ResponseAction
- type ResponseHandler
- func (rh *ResponseHandler) AutoRegisterResponseHandler(prompt models.Prompt) bool
- func (rh *ResponseHandler) CleanupStaleHooks(ctx context.Context) error
- func (rh *ResponseHandler) GetActiveParticipantCount(ctx context.Context) (int, error)
- func (rh *ResponseHandler) GetDefaultMessage() string
- func (rh *ResponseHandler) GetHookCount() int
- func (rh *ResponseHandler) IsHookRegistered(recipient string) bool
- func (rh *ResponseHandler) IsParticipantActive(ctx context.Context, phoneNumber string) (bool, error)
- func (rh *ResponseHandler) ListRegisteredRecipients() []string
- func (rh *ResponseHandler) ProcessResponse(ctx context.Context, response models.Response) error
- func (rh *ResponseHandler) RecoverPersistentHooks(ctx context.Context) error
- func (rh *ResponseHandler) RegisterHook(recipient string, action ResponseAction) error
- func (rh *ResponseHandler) RegisterPersistentHook(recipient string, hookType models.HookType, params map[string]string) error
- func (rh *ResponseHandler) SetDefaultMessage(message string)
- func (rh *ResponseHandler) SetDependencies(stateManager flow.StateManager, timer models.Timer)
- func (rh *ResponseHandler) Start(ctx context.Context)
- func (rh *ResponseHandler) UnregisterHook(recipient string) error
- func (rh *ResponseHandler) UnregisterPersistentHook(recipient string) error
- func (rh *ResponseHandler) ValidateAndCleanupHooks(ctx context.Context) error
- type ResponseHandlerFactory
- type Service
- type WhatsAppService
- func (s *WhatsAppService) Receipts() <-chan models.Receipt
- func (s *WhatsAppService) Responses() <-chan models.Response
- func (s *WhatsAppService) SendMessage(ctx context.Context, to string, body string) error
- func (s *WhatsAppService) SendTypingIndicator(ctx context.Context, to string, typing bool) error
- func (s *WhatsAppService) Start(ctx context.Context) error
- func (s *WhatsAppService) Stop() error
- func (s *WhatsAppService) ValidateAndCanonicalizeRecipient(recipient string) (string, error)
Constants ¶
const ( // DefaultChannelBufferSize defines the default buffer size for receipt and response channels DefaultChannelBufferSize = 100 // DefaultChannelTimeout defines the default timeout for non-blocking channel operations DefaultChannelTimeout = 1 * time.Second )
Constants for WhatsAppService configuration
Variables ¶
var (
ErrServiceStopped = errors.New("messaging service has been stopped")
)
Error variables for better error handling
Functions ¶
This section is empty.
Types ¶
type HookFactory ¶
type HookFactory func(params map[string]string, stateManager flow.StateManager, msgService Service, timer models.Timer) (ResponseAction, error)
HookFactory defines a function that creates a response hook from parameters
type HookRegistry ¶
type HookRegistry struct {
// contains filtered or unexported fields
}
HookRegistry manages the mapping of hook type names to factory functions
func NewHookRegistry ¶
func NewHookRegistry() *HookRegistry
NewHookRegistry creates a new hook registry with default factories
func (*HookRegistry) CreateHook ¶
func (hr *HookRegistry) CreateHook(hookType models.HookType, params map[string]string, stateManager flow.StateManager, msgService Service, timer models.Timer) (ResponseAction, error)
CreateHook creates a hook using the registered factory for the given type
func (*HookRegistry) IsRegistered ¶
func (hr *HookRegistry) IsRegistered(hookType models.HookType) bool
IsRegistered checks if a hook type has a registered factory
func (*HookRegistry) ListRegisteredTypes ¶
func (hr *HookRegistry) ListRegisteredTypes() []models.HookType
ListRegisteredTypes returns all registered hook types
func (*HookRegistry) RegisterFactory ¶
func (hr *HookRegistry) RegisterFactory(hookType models.HookType, factory HookFactory)
RegisterFactory registers a custom hook factory function
type ResponseAction ¶
type ResponseAction func(ctx context.Context, from, responseText string, timestamp int64) (handled bool, err error)
ResponseAction defines a hook function that processes a participant's response. It receives the participant's canonical phone number, response text, and timestamp. It should return true if the response was handled, false otherwise.
func CreateBranchHook ¶
func CreateBranchHook(branchOptions []models.BranchOption, msgService Service) ResponseAction
CreateBranchHook creates a response handler for branch-type prompts that validates user selections and responds appropriately.
func CreateConversationHook ¶
func CreateConversationHook(participantID string, msgService Service) ResponseAction
CreateConversationHook creates a specialized hook for conversation prompts that processes responses according to the conversation flow logic and maintains history.
func CreateGenAIHook ¶
func CreateGenAIHook(originalPrompt models.Prompt, msgService Service) ResponseAction
CreateGenAIHook creates a response handler for GenAI-generated prompts that acknowledges responses and can optionally trigger follow-up generation.
func CreateStaticHook ¶
func CreateStaticHook(msgService Service) ResponseAction
CreateStaticHook creates a response handler for static prompts that provides a simple acknowledgment for any responses.
type ResponseHandler ¶
type ResponseHandler struct {
// contains filtered or unexported fields
}
ResponseHandler manages stateful response processing by maintaining a map of recipient -> action hooks and routing incoming responses appropriately.
func NewResponseHandler ¶
func NewResponseHandler(msgService Service, store store.Store) *ResponseHandler
NewResponseHandler creates a new ResponseHandler with the given messaging service.
func (*ResponseHandler) AutoRegisterResponseHandler ¶
func (rh *ResponseHandler) AutoRegisterResponseHandler(prompt models.Prompt) bool
AutoRegisterResponseHandler automatically registers a response handler for a prompt if one is needed. Returns true if a handler was registered.
func (*ResponseHandler) CleanupStaleHooks ¶
func (rh *ResponseHandler) CleanupStaleHooks(ctx context.Context) error
CleanupStaleHooks removes hooks from the database for participants who are no longer active This should be called periodically to maintain database hygiene
func (*ResponseHandler) GetActiveParticipantCount ¶
func (rh *ResponseHandler) GetActiveParticipantCount(ctx context.Context) (int, error)
GetActiveParticipantCount returns the number of active participants across all flow types.
func (*ResponseHandler) GetDefaultMessage ¶
func (rh *ResponseHandler) GetDefaultMessage() string
GetDefaultMessage returns the current default message.
func (*ResponseHandler) GetHookCount ¶
func (rh *ResponseHandler) GetHookCount() int
GetHookCount returns the number of currently registered hooks.
func (*ResponseHandler) IsHookRegistered ¶
func (rh *ResponseHandler) IsHookRegistered(recipient string) bool
IsHookRegistered checks if a hook is registered for the given recipient.
func (*ResponseHandler) IsParticipantActive ¶
func (rh *ResponseHandler) IsParticipantActive(ctx context.Context, phoneNumber string) (bool, error)
IsParticipantActive checks if a participant is active based on their phone number.
func (*ResponseHandler) ListRegisteredRecipients ¶
func (rh *ResponseHandler) ListRegisteredRecipients() []string
ListRegisteredRecipients returns a slice of all recipients with registered hooks.
func (*ResponseHandler) ProcessResponse ¶
ProcessResponse processes an incoming response by checking for registered hooks and executing them, or sending a default response if no hook is found.
func (*ResponseHandler) RecoverPersistentHooks ¶
func (rh *ResponseHandler) RecoverPersistentHooks(ctx context.Context) error
RecoverPersistentHooks restores hooks from the database using the HookRegistry This method implements best-effort recovery: it will warn but not error if recreation fails
func (*ResponseHandler) RegisterHook ¶
func (rh *ResponseHandler) RegisterHook(recipient string, action ResponseAction) error
RegisterHook registers a response action for a specific participant. The recipient should be a canonicalized phone number (e.g., "1234567890").
func (*ResponseHandler) RegisterPersistentHook ¶
func (rh *ResponseHandler) RegisterPersistentHook(recipient string, hookType models.HookType, params map[string]string) error
RegisterPersistentHook registers a response action that will be persisted to the database
func (*ResponseHandler) SetDefaultMessage ¶
func (rh *ResponseHandler) SetDefaultMessage(message string)
SetDefaultMessage sets the default message sent when no hook handles a response.
func (*ResponseHandler) SetDependencies ¶
func (rh *ResponseHandler) SetDependencies(stateManager flow.StateManager, timer models.Timer)
SetDependencies sets the state manager and timer for hook creation This should be called during server initialization
func (*ResponseHandler) Start ¶
func (rh *ResponseHandler) Start(ctx context.Context)
Start begins processing responses from the messaging service. This should be called once to start the response processing loop.
func (*ResponseHandler) UnregisterHook ¶
func (rh *ResponseHandler) UnregisterHook(recipient string) error
UnregisterHook removes a response action for a specific participant.
func (*ResponseHandler) UnregisterPersistentHook ¶
func (rh *ResponseHandler) UnregisterPersistentHook(recipient string) error
UnregisterPersistentHook removes a persistent hook from both memory and database
func (*ResponseHandler) ValidateAndCleanupHooks ¶
func (rh *ResponseHandler) ValidateAndCleanupHooks(ctx context.Context) error
ValidateAndCleanupHooks removes hooks for participants who are no longer active. This should be called during startup and optionally periodically to prevent memory leaks while ensuring active users can always respond.
type ResponseHandlerFactory ¶
type ResponseHandlerFactory struct {
// contains filtered or unexported fields
}
ResponseHandlerFactory creates appropriate response handlers based on prompt type.
func NewResponseHandlerFactory ¶
func NewResponseHandlerFactory(msgService Service) *ResponseHandlerFactory
NewResponseHandlerFactory creates a new factory for response handlers.
func (*ResponseHandlerFactory) CreateHandlerForPrompt ¶
func (f *ResponseHandlerFactory) CreateHandlerForPrompt(prompt models.Prompt) ResponseAction
CreateHandlerForPrompt creates and returns a response handler appropriate for the given prompt type. Returns nil if no specific handler is needed for the prompt type.
type Service ¶
type Service interface { // ValidateAndCanonicalizeRecipient validates and canonicalizes a recipient identifier. // Returns the canonicalized recipient and an error if validation fails. // This allows each service to implement its own recipient validation rules. ValidateAndCanonicalizeRecipient(recipient string) (string, error) // SendMessage sends a message to a recipient. SendMessage(ctx context.Context, to string, body string) error // SendTypingIndicator updates the recipient's chat presence to show or hide a typing indicator. // Implementations should treat this as best-effort and not fail hard if the provider doesn't support it. SendTypingIndicator(ctx context.Context, to string, typing bool) error // Start begins any background processing (e.g., polling for events). Start(ctx context.Context) error // Stop stops background processing and cleans up resources. Stop() error // Receipts returns a channel of receipt events (sent, delivered, read). Receipts() <-chan models.Receipt // Responses returns a channel of incoming participant responses. Responses() <-chan models.Response }
Service defines a pluggable message delivery abstraction. It supports sending messages, and provides channels for receipt and response events.
type WhatsAppService ¶
type WhatsAppService struct {
// contains filtered or unexported fields
}
WhatsAppService implements Service using the Whatsmeow-based whatsapp client.
func NewWhatsAppService ¶
func NewWhatsAppService(client whatsapp.WhatsAppSender) *WhatsAppService
NewWhatsAppService creates a new WhatsAppService wrapping the given WhatsAppSender.
func (*WhatsAppService) Receipts ¶
func (s *WhatsAppService) Receipts() <-chan models.Receipt
Receipts returns a channel of receipt events.
func (*WhatsAppService) Responses ¶
func (s *WhatsAppService) Responses() <-chan models.Response
Responses returns a channel of incoming response events.
func (*WhatsAppService) SendMessage ¶
SendMessage sends a message and emits a sent receipt.
func (*WhatsAppService) SendTypingIndicator ¶
SendTypingIndicator updates the chat presence for the given recipient.
func (*WhatsAppService) Start ¶
func (s *WhatsAppService) Start(ctx context.Context) error
Start begins background processing (e.g., event polling).
func (*WhatsAppService) Stop ¶
func (s *WhatsAppService) Stop() error
Stop stops background processing.
func (*WhatsAppService) ValidateAndCanonicalizeRecipient ¶
func (s *WhatsAppService) ValidateAndCanonicalizeRecipient(recipient string) (string, error)
ValidateAndCanonicalizeRecipient validates and canonicalizes a WhatsApp phone number. It removes all non-numeric characters and validates the result has at least 6 digits.