This document covers all FlowChat configuration options.
# config/initializers/flowchat.rb
# Core configuration
FlowChat::Config.logger = Rails.logger
FlowChat::Config.cache = Rails.cache
FlowChat::Config.simulator_secret = "your_secure_secret_here"
# Validation error display behavior
FlowChat::Config.combine_validation_error_with_message = true # default
# Setup instrumentation (optional)
FlowChat.setup_instrumentation!# Session boundaries control how session IDs are constructed
FlowChat::Config.session.boundaries = [:flow, :platform] # default
FlowChat::Config.session.hash_phone_numbers = true # hash phone numbers for privacy
FlowChat::Config.session.identifier = nil # let platforms choose (default)
# Available boundary options:
# :flow - separate sessions per flow class
# :platform - separate sessions per platform (ussd, whatsapp)
# :gateway - separate sessions per gateway
# [] - global sessions (no boundaries)
# Available identifier options:
# nil - platform chooses default (:request_id for USSD, :msisdn for WhatsApp)
# :msisdn - use phone number (durable sessions)
# :request_id - use request ID (ephemeral sessions)# USSD pagination settings
FlowChat::Config.ussd.pagination_page_size = 140 # characters per page
FlowChat::Config.ussd.pagination_next_option = "#" # option to go to next page
FlowChat::Config.ussd.pagination_next_text = "More" # text for next option
FlowChat::Config.ussd.pagination_back_option = "0" # option to go back
FlowChat::Config.ussd.pagination_back_text = "Back" # text for back option# Message handling modes
FlowChat::Config.whatsapp.message_handling_mode = :inline # :inline, :background, :simulator
FlowChat::Config.whatsapp.background_job_class = 'WhatsappMessageJob'rails credentials:editwhatsapp:
access_token: "your_access_token"
phone_number_id: "your_phone_number_id"
verify_token: "your_verify_token"
app_id: "your_app_id"
app_secret: "your_app_secret"
business_account_id: "your_business_account_id"
skip_signature_validation: falseexport WHATSAPP_ACCESS_TOKEN="your_access_token"
export WHATSAPP_PHONE_NUMBER_ID="your_phone_number_id"
export WHATSAPP_VERIFY_TOKEN="your_verify_token"
export WHATSAPP_APP_ID="your_app_id"
export WHATSAPP_APP_SECRET="your_app_secret"
export WHATSAPP_BUSINESS_ACCOUNT_ID="your_business_account_id"
export WHATSAPP_SKIP_SIGNATURE_VALIDATION="false"config = FlowChat::Whatsapp::Configuration.new(:my_config) # Named configuration
config.access_token = "your_access_token"
config.phone_number_id = "your_phone_number_id"
config.verify_token = "your_verify_token"
config.app_id = "your_app_id"
config.app_secret = "your_app_secret"
config.business_account_id = "your_business_account_id"
config.skip_signature_validation = false
# Configuration is automatically registered as :my_config# config/initializers/whatsapp_configs.rb
# Register configurations so background jobs can access them
production_config = FlowChat::Whatsapp::Configuration.new(:production)
production_config.access_token = ENV['PROD_WHATSAPP_TOKEN']
# ... other settings
staging_config = FlowChat::Whatsapp::Configuration.new(:staging)
staging_config.access_token = ENV['STAGING_WHATSAPP_TOKEN']
# ... other settingsThen use named configurations in controllers:
# Use registered configuration
config = FlowChat::Whatsapp::Configuration.get(:production)
processor = FlowChat::Whatsapp::Processor.new(self) do |config|
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi, config
end# Production security (recommended)
config.app_secret = "your_whatsapp_app_secret"
config.skip_signature_validation = false # default
# Development mode (disable validation)
config.app_secret = nil
config.skip_signature_validation = true# Use Rails secret for uniqueness
FlowChat::Config.simulator_secret = Rails.application.secret_key_base + "_simulator"
# Or use dedicated secret
FlowChat::Config.simulator_secret = ENV['FLOWCHAT_SIMULATOR_SECRET']# config/initializers/flowchat.rb
case Rails.env
when 'development'
FlowChat::Config.whatsapp.message_handling_mode = :simulator
FlowChat::Config.simulator_secret = Rails.application.secret_key_base + "_dev"
when 'test'
FlowChat::Config.whatsapp.message_handling_mode = :simulator
FlowChat::Config.simulator_secret = "test_secret"
when 'staging'
FlowChat::Config.whatsapp.message_handling_mode = :inline
FlowChat::Config.simulator_secret = ENV['FLOWCHAT_SIMULATOR_SECRET']
when 'production'
FlowChat::Config.whatsapp.message_handling_mode = :background
FlowChat::Config.whatsapp.background_job_class = 'WhatsappMessageJob'
FlowChat::Config.simulator_secret = ENV['FLOWCHAT_SIMULATOR_SECRET']
endprocessor = FlowChat::Ussd::Processor.new(self) do |config|
# Gateway (required)
config.use_gateway FlowChat::Ussd::Gateway::Nalo
# Session storage (required)
config.use_session_store FlowChat::Session::CacheSessionStore
# Optional middleware
config.use_middleware MyCustomMiddleware
# Configure session boundaries
config.use_session_config(
boundaries: [:flow, :platform], # which boundaries to enforce
hash_phone_numbers: true, # hash phone numbers for privacy
identifier: :msisdn # use MSISDN for durable sessions (optional)
)
# Shorthand for durable sessions (identifier: :msisdn)
config.use_durable_sessions
endprocessor = FlowChat::Whatsapp::Processor.new(self, enable_simulator: Rails.env.development?) do |config|
# Gateway (required)
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
# Session storage (required)
config.use_session_store FlowChat::Session::CacheSessionStore
# Optional custom configuration
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi, custom_whatsapp_config
endconfig.use_session_store FlowChat::Session::CacheSessionStoreUses Rails cache backend with automatic TTL management. This is the primary session store available in FlowChat.
# Pagination (USSD only, automatic)
FlowChat::Ussd::Middleware::Pagination
# Session management (automatic)
FlowChat::Session::Middleware
# Gateway communication (automatic)
FlowChat::Ussd::Gateway::Nalo
FlowChat::Whatsapp::Gateway::CloudApiclass LoggingMiddleware
def initialize(app)
@app = app
end
def call(context)
Rails.logger.info "Processing request: #{context.input}"
result = @app.call(context)
Rails.logger.info "Response: #{result[1]}"
result
end
end
# Use custom middleware
config.use_middleware LoggingMiddleware# Combine validation error with original message (default)
FlowChat::Config.combine_validation_error_with_message = true
# User sees: "Invalid email format\n\nEnter your email:"
# Show only validation error
FlowChat::Config.combine_validation_error_with_message = false
# User sees: "Invalid email format"# app/jobs/whatsapp_message_job.rb
class WhatsappMessageJob < ApplicationJob
include FlowChat::Whatsapp::SendJobSupport
def perform(send_data)
perform_whatsapp_send(send_data)
end
endConfiguration Resolution: The job automatically resolves configurations using:
- Named configuration from
send_data[:configuration_name]if present - Default configuration from credentials/environment variables
For custom resolution logic, override the configuration resolution:
class CustomWhatsappMessageJob < ApplicationJob
include FlowChat::Whatsapp::SendJobSupport
def perform(send_data)
perform_whatsapp_send(send_data)
end
private
def resolve_whatsapp_configuration(send_data)
# Custom logic to resolve configuration
tenant_id = ...
FlowChat::Whatsapp::Configuration.get("tenant_#{tenant_id}")
end
end# config/application.rb
config.active_job.queue_adapter = :sidekiq
# config/initializers/flowchat.rb
FlowChat::Config.whatsapp.background_job_class = 'WhatsappMessageJob'# Enable instrumentation
FlowChat.setup_instrumentation!# Subscribe to specific events
ActiveSupport::Notifications.subscribe("flow.execution.end.flow_chat") do |event|
# Custom handling
ExternalMonitoring.track_flow_execution(
event.payload[:flow_name],
event.duration
)
end
# Subscribe to all FlowChat events
ActiveSupport::Notifications.subscribe(/\.flow_chat$/) do |name, start, finish, id, payload|
CustomLogger.log_event(name, payload.merge(duration: finish - start))
endFlowChat validates configuration at runtime and provides helpful error messages:
FlowChat validates configuration at runtime and provides helpful error messages for missing or invalid configurations.