flow_chat 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.cliff.toml +74 -0
- data/.github/workflows/ci.yml +2 -3
- data/.github/workflows/release.yml +56 -0
- data/.standard.yml +4 -0
- data/CHANGELOG.md +22 -0
- data/CLAUDE.md +327 -0
- data/CONTRIBUTING.md +134 -0
- data/Gemfile +1 -0
- data/README.md +290 -105
- data/Rakefile +5 -1
- data/SECURITY.md +42 -349
- data/docs/architecture.md +510 -0
- data/docs/async-background-processing.md +298 -0
- data/docs/configuration.md +556 -226
- data/docs/factory-pattern.md +355 -0
- data/docs/gateway-context-variables.md +171 -0
- data/docs/gateway-development.md +723 -0
- data/docs/getting-started.md +429 -0
- data/docs/instrumentation.md +264 -153
- data/docs/platforms/telegram.md +1013 -0
- data/docs/platforms/ussd.md +693 -0
- data/docs/platforms/whatsapp.md +1395 -0
- data/docs/testing.md +243 -365
- data/examples/custom_session_id_example.rb +119 -0
- data/examples/http_controller.rb +154 -0
- data/examples/intercom_configuration_example.rb +118 -0
- data/examples/intercom_controller.rb +194 -0
- data/examples/multi_tenant_whatsapp_controller.rb +4 -4
- data/examples/simulator_controller.rb +21 -1
- data/examples/ussd_controller.rb +10 -10
- data/examples/whatsapp_controller.rb +2 -2
- data/flow_chat.gemspec +4 -0
- data/lib/flow_chat/{base_app.rb → app.rb} +28 -9
- data/lib/flow_chat/async_job.rb +176 -0
- data/lib/flow_chat/config.rb +23 -28
- data/lib/flow_chat/{base_executor.rb → executor.rb} +7 -12
- data/lib/flow_chat/factory.rb +94 -0
- data/lib/flow_chat/gateway_async_support.rb +106 -0
- data/lib/flow_chat/generic_async_job.rb +30 -0
- data/lib/flow_chat/http/gateway/simple.rb +125 -0
- data/lib/flow_chat/http/renderer.rb +41 -0
- data/lib/flow_chat/instrumentation/setup.rb +1 -1
- data/lib/flow_chat/instrumentation.rb +25 -0
- data/lib/flow_chat/intercom/client.rb +155 -0
- data/lib/flow_chat/intercom/configuration.rb +149 -0
- data/lib/flow_chat/intercom/gateway/intercom_api.rb +396 -0
- data/lib/flow_chat/intercom/renderer.rb +71 -0
- data/lib/flow_chat/phone_number_util.rb +49 -0
- data/lib/flow_chat/processor.rb +188 -0
- data/lib/flow_chat/renderers/markdown_support.rb +58 -0
- data/lib/flow_chat/session/cache_session_store.rb +1 -17
- data/lib/flow_chat/session/middleware.rb +43 -26
- data/lib/flow_chat/simulator/controller.rb +17 -5
- data/lib/flow_chat/simulator/views/simulator.html.erb +220 -8
- data/lib/flow_chat/telegram/client.rb +240 -0
- data/lib/flow_chat/telegram/configuration.rb +118 -0
- data/lib/flow_chat/telegram/gateway/bot_api.rb +300 -0
- data/lib/flow_chat/telegram/middleware/choice_mapper.rb +35 -0
- data/lib/flow_chat/telegram/renderer.rb +125 -0
- data/lib/flow_chat/telegram.rb +7 -0
- data/lib/flow_chat/ussd/gateway/nalo.rb +27 -11
- data/lib/flow_chat/ussd/middleware/pagination.rb +9 -5
- data/lib/flow_chat/ussd/renderer.rb +1 -1
- data/lib/flow_chat/version.rb +1 -1
- data/lib/flow_chat/whatsapp/client.rb +144 -13
- data/lib/flow_chat/whatsapp/configuration.rb +1 -1
- data/lib/flow_chat/whatsapp/gateway/cloud_api.rb +144 -106
- data/lib/flow_chat/whatsapp/id_generator.rb +124 -0
- data/lib/flow_chat/whatsapp/middleware/choice_mapper.rb +147 -0
- data/lib/flow_chat/whatsapp/renderer.rb +145 -11
- data/lib/flow_chat.rb +11 -1
- data/lib/tasks/release.rake +165 -0
- metadata +88 -21
- data/docs/flows.md +0 -320
- data/docs/images/simulator.png +0 -0
- data/docs/media.md +0 -153
- data/docs/sessions.md +0 -433
- data/docs/ussd-setup.md +0 -322
- data/docs/whatsapp-setup.md +0 -162
- data/examples/whatsapp_message_job.rb +0 -113
- data/lib/flow_chat/base_processor.rb +0 -145
- data/lib/flow_chat/session/rails_session_store.rb +0 -68
- data/lib/flow_chat/ussd/app.rb +0 -6
- data/lib/flow_chat/ussd/gateway/nsano.rb +0 -98
- data/lib/flow_chat/ussd/middleware/executor.rb +0 -24
- data/lib/flow_chat/ussd/processor.rb +0 -39
- data/lib/flow_chat/whatsapp/app.rb +0 -29
- data/lib/flow_chat/whatsapp/middleware/executor.rb +0 -24
- data/lib/flow_chat/whatsapp/processor.rb +0 -32
- data/lib/flow_chat/whatsapp/send_job_support.rb +0 -79
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# Getting Started with FlowChat
|
|
2
|
+
|
|
3
|
+
This guide will walk you through setting up FlowChat and building your first conversational application that works across multiple platforms.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Ruby 2.3+ (Ruby 3.0+ recommended)
|
|
8
|
+
- Rails 6.0+ (Rails 7.0+ recommended)
|
|
9
|
+
- Basic understanding of Rails controllers and routing
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Add FlowChat to your Rails application:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
# Gemfile
|
|
17
|
+
gem 'flow_chat'
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bundle install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start: Your First Multi-Platform App
|
|
25
|
+
|
|
26
|
+
Let's build a simple survey application that works across USSD, WhatsApp, Telegram, and HTTP APIs.
|
|
27
|
+
|
|
28
|
+
### 1. Create the Flow
|
|
29
|
+
|
|
30
|
+
Create a new file `app/flow_chat/survey_flow.rb`:
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
class SurveyFlow < FlowChat::Flow
|
|
34
|
+
def start
|
|
35
|
+
# Welcome message that works on all platforms
|
|
36
|
+
name = app.screen(:name) do |prompt|
|
|
37
|
+
prompt.ask "Welcome to our survey! What's your name?",
|
|
38
|
+
validate: ->(input) {
|
|
39
|
+
return "Name must be at least 2 characters" if input.length < 2
|
|
40
|
+
nil
|
|
41
|
+
},
|
|
42
|
+
transform: ->(input) { input.strip.titleize }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Rating question with platform-appropriate choices
|
|
46
|
+
rating = app.screen(:rating) do |prompt|
|
|
47
|
+
prompt.select "Hi #{name}! Rate our service:", {
|
|
48
|
+
"5" => "⭐⭐⭐⭐⭐ Excellent",
|
|
49
|
+
"4" => "⭐⭐⭐⭐ Good",
|
|
50
|
+
"3" => "⭐⭐⭐ Average",
|
|
51
|
+
"2" => "⭐⭐ Poor",
|
|
52
|
+
"1" => "⭐ Very Poor"
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Feedback collection
|
|
57
|
+
feedback = app.screen(:feedback) do |prompt|
|
|
58
|
+
prompt.ask "Any additional feedback?",
|
|
59
|
+
validate: ->(input) {
|
|
60
|
+
return "Feedback too short" if input.length < 5
|
|
61
|
+
nil
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Save the survey (your business logic)
|
|
66
|
+
save_survey(name, rating, feedback, app.msisdn)
|
|
67
|
+
|
|
68
|
+
# Thank you message
|
|
69
|
+
app.say "Thank you #{name}! Your feedback (#{rating}⭐) has been recorded."
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def save_survey(name, rating, feedback, phone)
|
|
75
|
+
# Your database logic here
|
|
76
|
+
Rails.logger.info "Survey: #{name} (#{phone}) rated #{rating}/5: #{feedback}"
|
|
77
|
+
|
|
78
|
+
# Example: Save to database
|
|
79
|
+
# Survey.create!(
|
|
80
|
+
# name: name,
|
|
81
|
+
# rating: rating.to_i,
|
|
82
|
+
# feedback: feedback,
|
|
83
|
+
# phone: phone,
|
|
84
|
+
# platform: app.platform
|
|
85
|
+
# )
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2. Create Controllers for Each Platform
|
|
91
|
+
|
|
92
|
+
#### USSD Controller
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# app/controllers/ussd_controller.rb
|
|
96
|
+
class UssdController < ApplicationController
|
|
97
|
+
skip_forgery_protection
|
|
98
|
+
|
|
99
|
+
def nalo_webhook
|
|
100
|
+
processor = FlowChat::Processor.new(self) do |config|
|
|
101
|
+
config.use_gateway FlowChat::Ussd::Gateway::Nalo
|
|
102
|
+
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
103
|
+
|
|
104
|
+
# Optional: Configure USSD-specific settings
|
|
105
|
+
config.use_session_config(boundaries: [:flow, :platform])
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
processor.run SurveyFlow, :start
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### WhatsApp Controller
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
# app/controllers/whatsapp_controller.rb
|
|
117
|
+
class WhatsappController < ApplicationController
|
|
118
|
+
skip_forgery_protection
|
|
119
|
+
|
|
120
|
+
def webhook
|
|
121
|
+
processor = FlowChat::Processor.new(self) do |config|
|
|
122
|
+
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
123
|
+
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
processor.run SurveyFlow, :start
|
|
127
|
+
rescue => e
|
|
128
|
+
Rails.logger.error "WhatsApp error: #{e.message}"
|
|
129
|
+
head :internal_server_error
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### Telegram Controller
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
# app/controllers/telegram_controller.rb
|
|
138
|
+
class TelegramController < ApplicationController
|
|
139
|
+
skip_forgery_protection
|
|
140
|
+
|
|
141
|
+
def webhook
|
|
142
|
+
processor = FlowChat::Processor.new(self) do |config|
|
|
143
|
+
config.use_gateway FlowChat::Telegram::Gateway::BotApi
|
|
144
|
+
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
processor.run SurveyFlow, :start
|
|
148
|
+
rescue => e
|
|
149
|
+
Rails.logger.error { "Telegram error: #{e.message}" }
|
|
150
|
+
head :internal_server_error
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### HTTP API Controller
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
# app/controllers/api/chat_controller.rb
|
|
159
|
+
class Api::ChatController < ApplicationController
|
|
160
|
+
before_action :authenticate_api_user # Your auth logic
|
|
161
|
+
|
|
162
|
+
def message
|
|
163
|
+
processor = FlowChat::Processor.new(self) do |config|
|
|
164
|
+
config.use_gateway FlowChat::Http::Gateway::Simple
|
|
165
|
+
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
166
|
+
|
|
167
|
+
# Session isolation per API user
|
|
168
|
+
config.use_session_config(identifier: :user_id)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
processor.run SurveyFlow, :start
|
|
172
|
+
# Automatically returns JSON response
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 3. Add Routes
|
|
178
|
+
|
|
179
|
+
```ruby
|
|
180
|
+
# config/routes.rb
|
|
181
|
+
Rails.application.routes.draw do
|
|
182
|
+
# USSD routes
|
|
183
|
+
post '/ussd/nalo', to: 'ussd#nalo_webhook'
|
|
184
|
+
|
|
185
|
+
# WhatsApp routes
|
|
186
|
+
post '/whatsapp/webhook', to: 'whatsapp#webhook'
|
|
187
|
+
get '/whatsapp/webhook', to: 'whatsapp#verify' # For webhook verification
|
|
188
|
+
|
|
189
|
+
# Telegram routes
|
|
190
|
+
post '/telegram/webhook', to: 'telegram#webhook'
|
|
191
|
+
|
|
192
|
+
# API routes
|
|
193
|
+
namespace :api do
|
|
194
|
+
post '/chat/message', to: 'chat#message'
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 4. Configuration
|
|
200
|
+
|
|
201
|
+
#### Environment Variables
|
|
202
|
+
|
|
203
|
+
Add these to your `.env` file:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# WhatsApp Configuration
|
|
207
|
+
WHATSAPP_ACCESS_TOKEN=your_access_token
|
|
208
|
+
WHATSAPP_PHONE_NUMBER_ID=your_phone_number_id
|
|
209
|
+
WHATSAPP_VERIFY_TOKEN=your_verify_token
|
|
210
|
+
WHATSAPP_APP_SECRET=your_app_secret
|
|
211
|
+
|
|
212
|
+
# Telegram Configuration
|
|
213
|
+
TELEGRAM_BOT_TOKEN=your_bot_token
|
|
214
|
+
TELEGRAM_SECRET_TOKEN=your_webhook_secret # Optional: for webhook validation
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### FlowChat Configuration
|
|
218
|
+
|
|
219
|
+
Create `config/initializers/flow_chat.rb`:
|
|
220
|
+
|
|
221
|
+
```ruby
|
|
222
|
+
FlowChat::Config.logger = Rails.logger
|
|
223
|
+
FlowChat::Config.cache = Rails.cache
|
|
224
|
+
|
|
225
|
+
# USSD Configuration
|
|
226
|
+
FlowChat::Config.ussd.pagination_page_size = 160 # Adjust for your network
|
|
227
|
+
FlowChat::Config.ussd.pagination_next_option = "#"
|
|
228
|
+
FlowChat::Config.ussd.pagination_back_option = "0"
|
|
229
|
+
|
|
230
|
+
# WhatsApp Configuration
|
|
231
|
+
FlowChat::Config.whatsapp.message_handling_mode = :inline # or :background
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 5. Test Your Application
|
|
235
|
+
|
|
236
|
+
#### Using the Built-in Simulator
|
|
237
|
+
|
|
238
|
+
Create a simple test in `rails console`:
|
|
239
|
+
|
|
240
|
+
```ruby
|
|
241
|
+
# Start a simulator session
|
|
242
|
+
simulator = FlowChat::Simulator.new(SurveyFlow, :start)
|
|
243
|
+
|
|
244
|
+
# Simulate the conversation
|
|
245
|
+
simulator.start
|
|
246
|
+
# => "Welcome to our survey! What's your name?"
|
|
247
|
+
|
|
248
|
+
simulator.send_message("John Doe")
|
|
249
|
+
# => "Hi John Doe! Rate our service:"
|
|
250
|
+
|
|
251
|
+
simulator.select_option("5")
|
|
252
|
+
# => "Any additional feedback?"
|
|
253
|
+
|
|
254
|
+
simulator.send_message("Great service, very helpful!")
|
|
255
|
+
# => "Thank you John Doe! Your feedback (5⭐) has been recorded."
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### Testing HTTP API
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Test the HTTP endpoint
|
|
262
|
+
curl -X POST http://localhost:3000/api/chat/message \
|
|
263
|
+
-H "Content-Type: application/json" \
|
|
264
|
+
-H "Authorization: Bearer your_api_token" \
|
|
265
|
+
-d '{
|
|
266
|
+
"user_id": "user123",
|
|
267
|
+
"input": "Hello"
|
|
268
|
+
}'
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### Testing USSD (using simulator)
|
|
272
|
+
|
|
273
|
+
Visit your Rails app with the simulator enabled:
|
|
274
|
+
|
|
275
|
+
```ruby
|
|
276
|
+
# In development, add this to your controller
|
|
277
|
+
processor = FlowChat::Processor.new(self, enable_simulator: true) do |config|
|
|
278
|
+
config.use_gateway FlowChat::Ussd::Gateway::Nalo
|
|
279
|
+
# ... other config
|
|
280
|
+
end
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Key Concepts
|
|
284
|
+
|
|
285
|
+
### 1. Screen-Based Navigation
|
|
286
|
+
|
|
287
|
+
FlowChat uses a **screen-based** approach where each `app.screen(:key)` represents a step in your conversation:
|
|
288
|
+
|
|
289
|
+
- **Automatic State Management**: Each screen's result is automatically cached
|
|
290
|
+
- **Navigation Stack**: FlowChat tracks where users are in the flow
|
|
291
|
+
- **Resume Capability**: Users can return to where they left off
|
|
292
|
+
|
|
293
|
+
### 2. Platform Abstraction
|
|
294
|
+
|
|
295
|
+
The same flow code works across all platforms because:
|
|
296
|
+
|
|
297
|
+
- **Unified Prompts**: `prompt.ask()` and `prompt.select()` adapt to each platform
|
|
298
|
+
- **Context Normalization**: All platforms provide consistent context (phone number, input, etc.)
|
|
299
|
+
- **Flexible Rendering**: Emojis show on WhatsApp, get stripped for USSD
|
|
300
|
+
|
|
301
|
+
### 3. Pluggable Gateways
|
|
302
|
+
|
|
303
|
+
Each platform can have multiple gateway implementations:
|
|
304
|
+
|
|
305
|
+
```ruby
|
|
306
|
+
# USSD with different providers
|
|
307
|
+
config.use_gateway FlowChat::Ussd::Gateway::Nalo
|
|
308
|
+
# config.use_gateway FlowChat::Ussd::Gateway::Africaist
|
|
309
|
+
# config.use_gateway YourCompany::Ussd::Gateway::CustomProvider
|
|
310
|
+
|
|
311
|
+
# WhatsApp with different APIs
|
|
312
|
+
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
313
|
+
# config.use_gateway FlowChat::Whatsapp::Gateway::OnPremise
|
|
314
|
+
# config.use_gateway YourCompany::Whatsapp::Gateway::Twilio
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 4. Session Management
|
|
318
|
+
|
|
319
|
+
FlowChat provides flexible session configuration:
|
|
320
|
+
|
|
321
|
+
```ruby
|
|
322
|
+
# Ephemeral sessions (restart on each request)
|
|
323
|
+
config.use_session_config(identifier: :request_id)
|
|
324
|
+
|
|
325
|
+
# Durable sessions (persist across timeouts using phone number)
|
|
326
|
+
config.use_durable_sessions
|
|
327
|
+
|
|
328
|
+
# Cross-platform sessions (same user, different platforms)
|
|
329
|
+
config.use_cross_platform_sessions
|
|
330
|
+
|
|
331
|
+
# Multi-tenant isolation
|
|
332
|
+
config.use_url_isolation
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Next Steps
|
|
336
|
+
|
|
337
|
+
Now that you have a basic multi-platform application running:
|
|
338
|
+
|
|
339
|
+
1. **Explore Platform Features**: Learn platform-specific capabilities
|
|
340
|
+
- [USSD Development](platforms/ussd.md) - Pagination, choice mapping
|
|
341
|
+
- [WhatsApp Development](platforms/whatsapp.md) - Rich media, templates
|
|
342
|
+
- [Telegram Development](platforms/telegram.md) - Inline keyboards, media, callbacks
|
|
343
|
+
- [HTTP Development](platforms/http.md) - API integration patterns
|
|
344
|
+
|
|
345
|
+
2. **Advanced Topics**:
|
|
346
|
+
- [Session Management](../session-management.md) - Deep dive into session boundaries
|
|
347
|
+
- [Middleware Development](../middleware.md) - Custom processing logic
|
|
348
|
+
- [Gateway Development](../gateway-development.md) - Build your own platform support
|
|
349
|
+
|
|
350
|
+
3. **Production Deployment**:
|
|
351
|
+
- [Configuration](../configuration.md) - Production-ready settings
|
|
352
|
+
- [Background Jobs](../background-jobs.md) - Async processing for WhatsApp
|
|
353
|
+
- [Testing](../testing.md) - Comprehensive testing strategies
|
|
354
|
+
|
|
355
|
+
## Common Patterns
|
|
356
|
+
|
|
357
|
+
### Validation and Transformation
|
|
358
|
+
|
|
359
|
+
```ruby
|
|
360
|
+
app.screen(:phone) do |prompt|
|
|
361
|
+
prompt.ask "Enter your phone number:",
|
|
362
|
+
validate: ->(input) {
|
|
363
|
+
return "Invalid phone format" unless input.match?(/^\+?[\d\s-()]+$/)
|
|
364
|
+
parsed = Phonelib.parse(input)
|
|
365
|
+
return "Invalid phone number" unless parsed.valid?
|
|
366
|
+
nil
|
|
367
|
+
},
|
|
368
|
+
transform: ->(input) { Phonelib.parse(input).e164 }
|
|
369
|
+
end
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Conditional Flow Logic
|
|
373
|
+
|
|
374
|
+
```ruby
|
|
375
|
+
def main_menu
|
|
376
|
+
user_type = determine_user_type(app.msisdn)
|
|
377
|
+
|
|
378
|
+
if user_type == :premium
|
|
379
|
+
premium_menu
|
|
380
|
+
else
|
|
381
|
+
basic_menu
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Error Handling
|
|
387
|
+
|
|
388
|
+
```ruby
|
|
389
|
+
def payment_flow
|
|
390
|
+
begin
|
|
391
|
+
amount = app.screen(:amount) { |p| p.ask "Enter amount:" }
|
|
392
|
+
process_payment(amount)
|
|
393
|
+
app.say "Payment successful!"
|
|
394
|
+
rescue PaymentError => e
|
|
395
|
+
app.say "Payment failed: #{e.message}"
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Troubleshooting
|
|
401
|
+
|
|
402
|
+
### Common Issues
|
|
403
|
+
|
|
404
|
+
1. **Session Not Persisting**
|
|
405
|
+
- Check your session store configuration
|
|
406
|
+
- Verify session boundaries match your use case
|
|
407
|
+
|
|
408
|
+
2. **Gateway Errors**
|
|
409
|
+
- Ensure environment variables are set correctly
|
|
410
|
+
- Check gateway-specific configuration requirements
|
|
411
|
+
|
|
412
|
+
3. **Platform Differences**
|
|
413
|
+
- Test flows on each platform's simulator
|
|
414
|
+
- Be aware of character limits (USSD) vs rich features (WhatsApp)
|
|
415
|
+
|
|
416
|
+
### Debug Mode
|
|
417
|
+
|
|
418
|
+
Enable comprehensive logging:
|
|
419
|
+
|
|
420
|
+
```ruby
|
|
421
|
+
# config/initializers/flow_chat.rb
|
|
422
|
+
FlowChat::Config.logger.level = Logger::DEBUG
|
|
423
|
+
|
|
424
|
+
# In your flow
|
|
425
|
+
Rails.logger.debug "Current screen: #{app.navigation_stack.last}"
|
|
426
|
+
Rails.logger.debug "User input: #{app.input.inspect}"
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Ready to build more sophisticated flows? Continue with the [Architecture Overview](architecture.md) to understand FlowChat's design principles.
|