messaging

package
v0.0.0-...-2bf20ed Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2025 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package messaging provides hook registry for persistent hook management

Package messaging provides response handling functionality for stateful interactions.

Index

Constants

View Source
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

View Source
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

func (rh *ResponseHandler) ProcessResponse(ctx context.Context, response models.Response) error

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

func (s *WhatsAppService) SendMessage(ctx context.Context, to string, body string) error

SendMessage sends a message and emits a sent receipt.

func (*WhatsAppService) SendTypingIndicator

func (s *WhatsAppService) SendTypingIndicator(ctx context.Context, to string, typing bool) error

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.

Jump to

Keyboard shortcuts

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