flow_chat 0.9.0 → 0.10.1
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/.github/workflows/ci.yml +29 -0
- data/.github/workflows/pages.yml +43 -0
- data/.gitignore +4 -1
- data/CHANGELOG.md +49 -0
- data/README.md +166 -295
- data/Rakefile +12 -1
- data/SECURITY.md +1 -1
- data/docs/architecture.md +52 -479
- data/docs/async-background-processing.md +31 -265
- data/docs/configuration.md +106 -613
- data/docs/factory-pattern.md +27 -324
- data/docs/gateway-context-variables.md +140 -143
- data/docs/gateway-development.md +86 -650
- data/docs/getting-started.md +40 -379
- data/docs/instrumentation.md +88 -279
- data/docs/platforms/instagram.md +278 -0
- data/docs/platforms/messenger.md +205 -0
- data/docs/platforms/telegram.md +47 -951
- data/docs/platforms/ussd.md +38 -653
- data/docs/platforms/whatsapp.md +73 -1321
- data/docs/superpowers/plans/2026-07-09-inbound-media-support.md +732 -0
- data/docs/superpowers/plans/2026-07-09-inbound-media-support.md.tasks.json +58 -0
- data/docs/superpowers/plans/2026-08-10-messenger-instagram.md +4064 -0
- data/docs/superpowers/plans/2026-08-10-messenger-instagram.md.tasks.json +226 -0
- data/docs/superpowers/plans/2026-08-16-unified-choice-resolution.md +972 -0
- data/docs/superpowers/plans/2026-08-16-unified-choice-resolution.md.tasks.json +88 -0
- data/docs/superpowers/specs/2026-07-09-inbound-media-support-design.md +195 -0
- data/docs/superpowers/specs/2026-08-10-messenger-instagram-design.md +391 -0
- data/docs/testing.md +26 -297
- data/examples/http_controller.rb +12 -10
- data/examples/intercom_configuration_example.rb +19 -24
- data/examples/intercom_controller.rb +8 -20
- data/examples/multi_tenant_whatsapp_controller.rb +61 -166
- data/examples/simulator_controller.rb +0 -1
- data/examples/ussd_controller.rb +86 -158
- data/examples/whatsapp_controller.rb +16 -15
- data/examples/whatsapp_media_examples.rb +27 -79
- data/flow_chat.gemspec +22 -2
- data/gemfiles/rails_main.gemfile +18 -0
- data/lib/flow_chat/app.rb +129 -11
- data/lib/flow_chat/async_job.rb +10 -0
- data/lib/flow_chat/choice_titles.rb +95 -0
- data/lib/flow_chat/config.rb +124 -1
- data/lib/flow_chat/delivery_error.rb +9 -0
- data/lib/flow_chat/gateway_async_support.rb +19 -1
- data/lib/flow_chat/http/configuration_error.rb +9 -0
- data/lib/flow_chat/http/gateway/simple.rb +24 -4
- data/lib/flow_chat/http/middleware/choice_mapper.rb +94 -0
- data/lib/flow_chat/input.rb +86 -0
- data/lib/flow_chat/instagram/client.rb +32 -0
- data/lib/flow_chat/instagram/configuration.rb +147 -0
- data/lib/flow_chat/instagram/configuration_error.rb +7 -0
- data/lib/flow_chat/instagram/gateway/send_api.rb +63 -0
- data/lib/flow_chat/instagram/middleware/choice_mapper.rb +22 -0
- data/lib/flow_chat/instagram/renderer.rb +23 -0
- data/lib/flow_chat/instrumentation/metrics_collector.rb +6 -1
- data/lib/flow_chat/instrumentation.rb +160 -1
- data/lib/flow_chat/intercom/client.rb +34 -28
- data/lib/flow_chat/intercom/configuration.rb +2 -49
- data/lib/flow_chat/intercom/configuration_error.rb +9 -0
- data/lib/flow_chat/intercom/gateway/intercom_api.rb +81 -57
- data/lib/flow_chat/intercom/middleware/choice_mapper.rb +101 -0
- data/lib/flow_chat/intercom/renderer.rb +57 -5
- data/lib/flow_chat/media.rb +121 -0
- data/lib/flow_chat/messenger/client.rb +264 -0
- data/lib/flow_chat/messenger/configuration.rb +103 -0
- data/lib/flow_chat/messenger/configuration_error.rb +9 -0
- data/lib/flow_chat/messenger/gateway/send_api.rb +42 -0
- data/lib/flow_chat/messenger/middleware/choice_mapper.rb +185 -0
- data/lib/flow_chat/messenger/renderer.rb +150 -0
- data/lib/flow_chat/meta/challenge.rb +24 -0
- data/lib/flow_chat/meta/choice_ladder.rb +37 -0
- data/lib/flow_chat/meta/configuration_error.rb +7 -0
- data/lib/flow_chat/meta/gateway_identity.rb +38 -0
- data/lib/flow_chat/meta/messaging_gateway.rb +471 -0
- data/lib/flow_chat/meta/signature.rb +30 -0
- data/lib/flow_chat/meta/signature_validation.rb +66 -0
- data/lib/flow_chat/meta/webhook_verification.rb +43 -0
- data/lib/flow_chat/named_configuration.rb +65 -0
- data/lib/flow_chat/prompt.rb +13 -16
- data/lib/flow_chat/renderers/markdown_support.rb +109 -0
- data/lib/flow_chat/security.rb +76 -0
- data/lib/flow_chat/session/middleware.rb +11 -2
- data/lib/flow_chat/simulator/controller.rb +31 -15
- data/lib/flow_chat/simulator/views/simulator.html.erb +184 -20
- data/lib/flow_chat/telegram/client.rb +47 -4
- data/lib/flow_chat/telegram/configuration.rb +2 -42
- data/lib/flow_chat/telegram/configuration_error.rb +9 -0
- data/lib/flow_chat/telegram/gateway/bot_api.rb +46 -28
- data/lib/flow_chat/telegram/middleware/choice_mapper.rb +77 -16
- data/lib/flow_chat/telegram/renderer.rb +10 -2
- data/lib/flow_chat/text_truncator.rb +75 -0
- data/lib/flow_chat/ussd/middleware/choice_mapper.rb +10 -0
- data/lib/flow_chat/version.rb +1 -1
- data/lib/flow_chat/whatsapp/client.rb +14 -7
- data/lib/flow_chat/whatsapp/configuration.rb +12 -51
- data/lib/flow_chat/whatsapp/configuration_error.rb +9 -0
- data/lib/flow_chat/whatsapp/gateway/cloud_api.rb +259 -203
- data/lib/flow_chat/whatsapp/middleware/choice_mapper.rb +144 -57
- data/lib/flow_chat/whatsapp/renderer.rb +121 -60
- data/lib/flow_chat.rb +0 -10
- data/lib/tasks/release.rake +11 -1
- data/site/.nojekyll +0 -0
- data/site/.og-card.html +89 -0
- data/site/favicon.svg +6 -0
- data/site/index.html +209 -0
- data/site/og.png +0 -0
- metadata +60 -11
- data/lib/flow_chat/whatsapp/id_generator.rb +0 -124
data/docs/factory-pattern.md
CHANGED
|
@@ -1,355 +1,58 @@
|
|
|
1
|
-
# Factory
|
|
1
|
+
# Factory pattern
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A factory is a named block that builds and runs a processor. You register it once, then call it by name from both the webhook and the background job. This keeps the processor configuration in one place, so the two contexts cannot drift apart.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Without a factory, a webhook that enqueues a background job needs the same processor setup written twice: once in the controller and once in the job. A factory removes the duplication.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Registering and executing
|
|
8
8
|
|
|
9
|
-
Register
|
|
9
|
+
Register the factory in an initializer:
|
|
10
10
|
|
|
11
11
|
```ruby
|
|
12
12
|
# config/initializers/flow_chat.rb
|
|
13
|
-
|
|
14
|
-
FlowChat::Factory.register :whatsapp do |controller|
|
|
13
|
+
FlowChat::Factory.register(:whatsapp) do |controller|
|
|
15
14
|
processor = FlowChat::Processor.new(controller) do |config|
|
|
16
15
|
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
17
16
|
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
18
|
-
config.
|
|
17
|
+
config.use_async(factory: :whatsapp)
|
|
19
18
|
end
|
|
20
19
|
processor.run(WhatsAppFlow, :start)
|
|
21
20
|
end
|
|
22
|
-
|
|
23
|
-
FlowChat::Factory.register :intercom do |controller|
|
|
24
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
25
|
-
config.use_gateway FlowChat::Intercom::Gateway::IntercomApi
|
|
26
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
27
|
-
config.use_session_config(boundaries: [:conversation], identifier: :conversation_id)
|
|
28
|
-
end
|
|
29
|
-
processor.run(IntercomFlow, :start)
|
|
30
|
-
end
|
|
31
21
|
```
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Execute factories directly in webhook controllers:
|
|
23
|
+
Execute it from the webhook controller:
|
|
36
24
|
|
|
37
25
|
```ruby
|
|
38
|
-
# app/controllers/
|
|
39
|
-
class
|
|
40
|
-
|
|
41
|
-
FlowChat::Factory.execute(:whatsapp, controller: self)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def intercom
|
|
45
|
-
FlowChat::Factory.execute(:intercom, controller: self)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### 3. Use with Async (Recommended)
|
|
51
|
-
|
|
52
|
-
Register factory with async support for background processing:
|
|
26
|
+
# app/controllers/whatsapp_controller.rb
|
|
27
|
+
class WhatsappController < ApplicationController
|
|
28
|
+
skip_forgery_protection
|
|
53
29
|
|
|
54
|
-
|
|
55
|
-
# config/initializers/flow_chat.rb
|
|
56
|
-
FlowChat::Factory.register :whatsapp do |controller|
|
|
57
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
58
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
59
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
60
|
-
config.use_session_config(boundaries: [:flow])
|
|
61
|
-
config.use_async(factory: :whatsapp) # Self-referencing for async
|
|
62
|
-
end
|
|
63
|
-
processor.run(WhatsAppFlow, :start)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# app/controllers/webhooks_controller.rb
|
|
67
|
-
class WebhooksController < ApplicationController
|
|
68
|
-
def whatsapp
|
|
30
|
+
def webhook
|
|
69
31
|
FlowChat::Factory.execute(:whatsapp, controller: self)
|
|
70
32
|
end
|
|
71
33
|
end
|
|
72
34
|
```
|
|
73
35
|
|
|
74
|
-
|
|
75
|
-
1. Webhook receives request
|
|
76
|
-
2. `use_async(factory: :whatsapp)` automatically uses `GenericAsyncJob`
|
|
77
|
-
3. Job is enqueued with `factory: :whatsapp` parameter
|
|
78
|
-
4. Background worker executes `FlowChat::Factory.execute(:whatsapp, controller: background_controller)`
|
|
79
|
-
5. Flow processes in background with same configuration
|
|
80
|
-
|
|
81
|
-
## Benefits
|
|
82
|
-
|
|
83
|
-
### 1. Single Source of Truth
|
|
84
|
-
|
|
85
|
-
Define processor configuration once, use everywhere:
|
|
86
|
-
|
|
87
|
-
```ruby
|
|
88
|
-
# Before: Duplicated configuration
|
|
89
|
-
# Webhook controller
|
|
90
|
-
processor = FlowChat::Processor.new(self) do |config|
|
|
91
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
92
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
93
|
-
config.use_session_config(boundaries: [:flow])
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Background job (duplicate!)
|
|
97
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
98
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
99
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
100
|
-
config.use_session_config(boundaries: [:flow])
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# After: Single registration
|
|
104
|
-
FlowChat::Factory.register :whatsapp do |controller|
|
|
105
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
106
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
107
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
108
|
-
config.use_session_config(boundaries: [:flow])
|
|
109
|
-
end
|
|
110
|
-
processor.run(WhatsAppFlow, :start)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# Use everywhere with one line
|
|
114
|
-
FlowChat::Factory.execute(:whatsapp, controller: self)
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### 2. No Custom Job Classes
|
|
118
|
-
|
|
119
|
-
For simple cases, use `GenericAsyncJob` automatically:
|
|
120
|
-
|
|
121
|
-
```ruby
|
|
122
|
-
# No need to create MyFlowJob class
|
|
123
|
-
config.use_async(factory: :whatsapp)
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### 3. Context-Aware Execution
|
|
127
|
-
|
|
128
|
-
Same factory works in both webhook and background contexts:
|
|
129
|
-
|
|
130
|
-
```ruby
|
|
131
|
-
# Webhook context - processes inline or enqueues
|
|
132
|
-
FlowChat::Factory.execute(:whatsapp, controller: webhook_controller)
|
|
133
|
-
|
|
134
|
-
# Background context - always processes inline
|
|
135
|
-
FlowChat::Factory.execute(:whatsapp, controller: background_controller)
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Gateways automatically detect the context and prevent double-enqueueing.
|
|
139
|
-
|
|
140
|
-
### 4. Easy Testing
|
|
141
|
-
|
|
142
|
-
Test factories in isolation:
|
|
143
|
-
|
|
144
|
-
```ruby
|
|
145
|
-
RSpec.describe "WhatsApp Factory" do
|
|
146
|
-
it "executes successfully" do
|
|
147
|
-
controller = mock_controller
|
|
148
|
-
expect {
|
|
149
|
-
FlowChat::Factory.execute(:whatsapp, controller: controller)
|
|
150
|
-
}.not_to raise_error
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## API Reference
|
|
156
|
-
|
|
157
|
-
### Registration
|
|
158
|
-
|
|
159
|
-
**`FlowChat::Factory.register(name, &block)`**
|
|
160
|
-
|
|
161
|
-
Register a factory with a given name.
|
|
162
|
-
|
|
163
|
-
```ruby
|
|
164
|
-
FlowChat::Factory.register :my_flow do |controller|
|
|
165
|
-
# Build and run processor
|
|
166
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
167
|
-
# ... configuration
|
|
168
|
-
end
|
|
169
|
-
processor.run(MyFlow, :start)
|
|
170
|
-
end
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
**Parameters:**
|
|
174
|
-
- `name` (Symbol): Unique factory identifier
|
|
175
|
-
- `block` (Proc): Factory block receiving `controller`
|
|
176
|
-
|
|
177
|
-
**Returns:** `nil`
|
|
178
|
-
|
|
179
|
-
### Execution
|
|
180
|
-
|
|
181
|
-
**`FlowChat::Factory.execute(name, controller:)`**
|
|
182
|
-
|
|
183
|
-
Execute a registered factory.
|
|
184
|
-
|
|
185
|
-
```ruby
|
|
186
|
-
FlowChat::Factory.execute(:my_flow, controller: self)
|
|
187
|
-
```
|
|
36
|
+
The block receives a controller and returns whatever `processor.run` returns. Executing an unregistered name raises `FlowChat::Factory::FactoryNotFoundError`.
|
|
188
37
|
|
|
189
|
-
|
|
190
|
-
- `name` (Symbol): Factory name to execute
|
|
191
|
-
- `controller` (Object): Rails controller or BackgroundController
|
|
38
|
+
## How it pairs with async
|
|
192
39
|
|
|
193
|
-
|
|
40
|
+
Notice the factory references itself: `config.use_async(factory: :whatsapp)`. That closes the loop.
|
|
194
41
|
|
|
195
|
-
|
|
196
|
-
|
|
42
|
+
1. The webhook calls `Factory.execute(:whatsapp, controller: self)`.
|
|
43
|
+
2. The factory builds a processor with `use_async(factory: :whatsapp)`, so the gateway enqueues `FlowChat::GenericAsyncJob` with `factory: :whatsapp` and returns immediately.
|
|
44
|
+
3. The background job calls `Factory.execute(:whatsapp, controller: background_controller)` again.
|
|
45
|
+
4. This time the gateway is running in the background, so it processes the flow inline and sends the reply.
|
|
197
46
|
|
|
198
|
-
|
|
47
|
+
The same factory builds the processor in both passes, so there is one definition of the gateway, session store, and flow. See [async-background-processing.md](async-background-processing.md) for what happens inside the job.
|
|
199
48
|
|
|
200
|
-
|
|
49
|
+
## Other methods
|
|
201
50
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
FlowChat::Factory.registered?(:whatsapp) # => true
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
**`FlowChat::Factory.registered_factories`**
|
|
209
|
-
|
|
210
|
-
Get all registered factory names.
|
|
211
|
-
|
|
212
|
-
```ruby
|
|
213
|
-
FlowChat::Factory.registered_factories # => [:whatsapp, :intercom, :ussd]
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
**`FlowChat::Factory.clear!`**
|
|
217
|
-
|
|
218
|
-
Clear all registered factories (primarily for testing).
|
|
219
|
-
|
|
220
|
-
```ruby
|
|
221
|
-
FlowChat::Factory.clear!
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Advanced Patterns
|
|
225
|
-
|
|
226
|
-
### Environment-Specific Factories
|
|
227
|
-
|
|
228
|
-
Create different configurations per environment:
|
|
229
|
-
|
|
230
|
-
```ruby
|
|
231
|
-
if Rails.env.production?
|
|
232
|
-
FlowChat::Factory.register :whatsapp do |controller|
|
|
233
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
234
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
235
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
236
|
-
end
|
|
237
|
-
processor.run(ProductionFlow, :start)
|
|
238
|
-
end
|
|
239
|
-
else
|
|
240
|
-
FlowChat::Factory.register :whatsapp do |controller|
|
|
241
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
242
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
243
|
-
config.use_session_store FlowChat::Session::RailsSessionStore
|
|
244
|
-
end
|
|
245
|
-
processor.run(DevelopmentFlow, :start)
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Multiple Variants
|
|
251
|
-
|
|
252
|
-
Register multiple factories for the same platform:
|
|
253
|
-
|
|
254
|
-
```ruby
|
|
255
|
-
FlowChat::Factory.register :whatsapp_support do |controller|
|
|
256
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
257
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
258
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
259
|
-
end
|
|
260
|
-
processor.run(SupportFlow, :start)
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
FlowChat::Factory.register :whatsapp_sales do |controller|
|
|
264
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
265
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
266
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
267
|
-
end
|
|
268
|
-
processor.run(SalesFlow, :start)
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
# Use based on routing
|
|
272
|
-
def whatsapp
|
|
273
|
-
factory = params[:department] == 'sales' ? :whatsapp_sales : :whatsapp_support
|
|
274
|
-
FlowChat::Factory.execute(factory, controller: self)
|
|
275
|
-
end
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Accessing Request Data
|
|
279
|
-
|
|
280
|
-
Factories receive the controller, which includes request data:
|
|
281
|
-
|
|
282
|
-
```ruby
|
|
283
|
-
FlowChat::Factory.register :whatsapp do |controller|
|
|
284
|
-
# Access request params
|
|
285
|
-
user_id = controller.params[:user_id]
|
|
286
|
-
platform = controller.request.headers["User-Agent"]
|
|
287
|
-
|
|
288
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
289
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
290
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
# Route to different flows based on params
|
|
294
|
-
flow = user_id.start_with?('premium_') ? PremiumFlow : StandardFlow
|
|
295
|
-
processor.run(flow, :start)
|
|
296
|
-
end
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Migration Guide
|
|
300
|
-
|
|
301
|
-
### From Duplicate Configuration
|
|
302
|
-
|
|
303
|
-
**Before:**
|
|
304
|
-
```ruby
|
|
305
|
-
# Webhook controller
|
|
306
|
-
class WebhooksController < ApplicationController
|
|
307
|
-
def whatsapp
|
|
308
|
-
processor = FlowChat::Processor.new(self) do |config|
|
|
309
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
310
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
311
|
-
config.use_async(WhatsAppFlowJob)
|
|
312
|
-
end
|
|
313
|
-
processor.run(WhatsAppFlow, :start)
|
|
314
|
-
end
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
# Background job (duplicate!)
|
|
318
|
-
class WhatsAppFlowJob < FlowChat::AsyncJob
|
|
319
|
-
def execute(controller, **job_params)
|
|
320
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
321
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
322
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
323
|
-
end
|
|
324
|
-
processor.run(WhatsAppFlow, :start)
|
|
325
|
-
end
|
|
326
|
-
end
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
**After:**
|
|
330
|
-
```ruby
|
|
331
|
-
# config/initializers/flow_chat.rb
|
|
332
|
-
FlowChat::Factory.register :whatsapp do |controller|
|
|
333
|
-
processor = FlowChat::Processor.new(controller) do |config|
|
|
334
|
-
config.use_gateway FlowChat::Whatsapp::Gateway::CloudApi
|
|
335
|
-
config.use_session_store FlowChat::Session::CacheSessionStore
|
|
336
|
-
config.use_async(factory: :whatsapp) # Self-referencing for async
|
|
337
|
-
end
|
|
338
|
-
processor.run(WhatsAppFlow, :start)
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
# Webhook controller - ONE LINE!
|
|
342
|
-
class WebhooksController < ApplicationController
|
|
343
|
-
def whatsapp
|
|
344
|
-
FlowChat::Factory.execute(:whatsapp, controller: self)
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
# No custom job class needed!
|
|
349
|
-
```
|
|
51
|
+
- `FlowChat::Factory.registered?(:whatsapp)` returns whether a name is registered.
|
|
52
|
+
- `FlowChat::Factory.registered_factories` lists the registered names.
|
|
53
|
+
- `FlowChat::Factory.clear!` removes all registrations (useful in tests).
|
|
350
54
|
|
|
351
|
-
##
|
|
55
|
+
## Related
|
|
352
56
|
|
|
353
|
-
- [Async
|
|
354
|
-
- [
|
|
355
|
-
- [Gateways](gateways.md) - Platform-specific gateway configuration
|
|
57
|
+
- [Async and background processing](async-background-processing.md)
|
|
58
|
+
- [Configuration](configuration.md#async-processing)
|