telegem 2.0.7 β†’ 2.0.9

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Test-Projects/Movie-tracker-bot/Gemfile +2 -0
  3. data/Test-Projects/Movie-tracker-bot/bot.rb +62 -0
  4. data/Test-Projects/Movie-tracker-bot/handlers/.gitkeep +0 -0
  5. data/Test-Projects/Movie-tracker-bot/handlers/add_1_.rb +160 -0
  6. data/Test-Projects/Movie-tracker-bot/handlers/add_2_.rb +139 -0
  7. data/Test-Projects/Movie-tracker-bot/handlers/premium.rb +13 -0
  8. data/Test-Projects/Movie-tracker-bot/handlers/report.rb +31 -0
  9. data/Test-Projects/Movie-tracker-bot/handlers/search.rb +150 -0
  10. data/Test-Projects/Movie-tracker-bot/handlers/sponsor.rb +14 -0
  11. data/Test-Projects/Movie-tracker-bot/handlers/start.rb +48 -0
  12. data/Test-Projects/Movie-tracker-bot/handlers/watch.rb +210 -0
  13. data/Test-Projects/Test-submitted-by-marvel/.gitkeep +0 -0
  14. data/Test-Projects/Test-submitted-by-marvel/Marvel-bot.md +3 -0
  15. data/docs-src/.gitkeep +0 -0
  16. data/docs-src/Bot-registration_.PNG +0 -0
  17. data/docs-src/bot.md +295 -0
  18. data/docs-src/context|ctx|.md +531 -0
  19. data/docs-src/getting-started.md +328 -0
  20. data/docs-src/keyboard_inline.md +413 -0
  21. data/docs-src/scene.md +509 -0
  22. data/docs-src/understanding-ctx.md +581 -0
  23. data/lib/api/client.rb +17 -16
  24. data/lib/core/bot.rb +19 -25
  25. data/lib/telegem.rb +1 -1
  26. data/lib/webhook/server.rb +1 -1
  27. metadata +26 -15
  28. data/docs/Api.md +0 -211
  29. data/docs/Cookbook(copy_paste).md +0 -644
  30. data/docs/Getting_started.md +0 -348
  31. data/docs/How_to_use.md +0 -571
  32. data/docs/QuickStart.md +0 -258
  33. data/docs/Understanding_Scene.md +0 -434
  34. data/docs/Usage.md +0 -717
  35. data/docs/webhook_setup.md +0 -199
  36. /data/{docs β†’ Test-Projects/Movie-tracker-bot}/.gitkeep +0 -0
data/docs/QuickStart.md DELETED
@@ -1,258 +0,0 @@
1
-
2
- # πŸš€ Quick Start: Your First Bot in 5 Minutes
3
-
4
- Welcome! This guide will help you create your first Telegram bot with Telegem. No prior bot experience needed!
5
-
6
- ## πŸ“‹ What You'll Need
7
-
8
- 1. **Ruby installed** (version 3.0 or newer)
9
- 2. **A Telegram account**
10
- 3. **A bot token** (we'll get this next)
11
-
12
- ---
13
-
14
- ## πŸ”‘ Step 1: Get Your Bot Token
15
-
16
- 1. Open Telegram and search for **@BotFather**
17
- 2. Start a chat and send: `/newbot`
18
- 3. Choose a name for your bot (e.g., `My Test Bot`)
19
- 4. Choose a username ending in `bot` (e.g., `my_test_123_bot`)
20
- 5. **Copy the token** that looks like this:
21
- ```
22
-
23
- 1234567890:ABCdefGHIjklMNOpqrSTUvwxYZ-123456789
24
-
25
- ```
26
- ⚠️ **Keep this token secret!** It's your bot's password.
27
-
28
- ---
29
-
30
- ## πŸ“¦ Step 2: Install Telegem
31
-
32
- Open your terminal and run:
33
-
34
- ```bash
35
- gem install telegem
36
- ```
37
-
38
- You should see something like:
39
-
40
- ```
41
- Successfully installed telegem-0.1.0
42
- 1 gem installed
43
- ```
44
-
45
- ---
46
-
47
- πŸ€– Step 3: Create Your First Bot
48
-
49
- Create a new file called my_first_bot.rb:
50
-
51
- ```ruby
52
- # my_first_bot.rb
53
- require 'telegem'
54
-
55
- # 1. Paste your token here (replace the example)
56
- BOT_TOKEN = "1234567890:ABCdefGHIjklMNOpqrSTUvwxYZ"
57
-
58
- # 2. Create your bot
59
- bot = Telegem.new(BOT_TOKEN)
60
-
61
- # 3. Add your first command
62
- bot.command('start') do |ctx|
63
- ctx.reply "Hello! I'm your new bot. πŸ‘‹"
64
- ctx.reply "Try sending me /help"
65
- end
66
-
67
- # 4. Add a help command
68
- bot.command('help') do |ctx|
69
- help_text = <<~TEXT
70
- πŸ€– **My First Bot Commands:**
71
-
72
- /start - Start the bot
73
- /help - Show this message
74
- /echo [text] - Repeat your text
75
-
76
- Just send me any message and I'll reply!
77
- TEXT
78
-
79
- ctx.reply help_text
80
- end
81
-
82
- # 5. Add an echo command
83
- bot.command('echo') do |ctx|
84
- if ctx.message.text == "/echo"
85
- ctx.reply "Please add some text: /echo hello world"
86
- else
87
- # Remove "/echo " from the beginning
88
- text = ctx.message.text.sub('/echo ', '')
89
- ctx.reply "You said: #{text}"
90
- end
91
- end
92
-
93
- # 6. Reply to ANY message
94
- bot.on(:message) do |ctx|
95
- # Don't reply to commands (they're handled above)
96
- next if ctx.message.command?
97
-
98
- ctx.reply "I got your message: #{ctx.message.text}"
99
- end
100
-
101
- # 7. Start the bot
102
- puts "πŸ€– Bot starting... (Press Ctrl+C to stop)"
103
- bot.start_polling
104
- ```
105
-
106
- ---
107
-
108
- ▢️ Step 4: Run Your Bot
109
-
110
- In your terminal, run:
111
-
112
- ```bash
113
- ruby my_first_bot.rb
114
- ```
115
-
116
- You should see:
117
-
118
- ```
119
- πŸ€– Bot starting... (Press Ctrl+C to stop)
120
- ```
121
-
122
- Congratulations! Your bot is now running! πŸŽ‰
123
-
124
- ---
125
-
126
- πŸ’¬ Step 5: Test Your Bot
127
-
128
- 1. Open Telegram and search for your bot's username (e.g., @my_test_123_bot)
129
- 2. Click "Start"
130
- 3. Try these commands:
131
- Β· /start - Should say hello
132
- Β· /help - Should show commands
133
- Β· /echo hello - Should repeat "hello"
134
- Β· Send any normal message - Should echo it back
135
-
136
- It should work like this:
137
-
138
- ```
139
- You: /start
140
- Bot: Hello! I'm your new bot. πŸ‘‹
141
- Bot: Try sending me /help
142
-
143
- You: Hello bot!
144
- Bot: I got your message: Hello bot!
145
-
146
- You: /echo testing
147
- Bot: You said: testing
148
- ```
149
-
150
- ---
151
-
152
- 🎨 Step 6: Add a Simple Keyboard
153
-
154
- Let's make it more interactive! Update your bot with this:
155
-
156
- ```ruby
157
- # Add this new command
158
- bot.command('menu') do |ctx|
159
- # Create a simple keyboard
160
- keyboard = [
161
- ["Option 1", "Option 2"],
162
- ["Option 3", "Cancel"]
163
- ]
164
-
165
- ctx.reply "Choose an option:", reply_markup: { keyboard: keyboard }
166
- end
167
-
168
- # Handle the keyboard button presses
169
- bot.on(:message) do |ctx|
170
- next if ctx.message.command?
171
-
172
- text = ctx.message.text
173
-
174
- case text
175
- when "Option 1"
176
- ctx.reply "You chose Option 1! βœ…"
177
- when "Option 2"
178
- ctx.reply "Option 2 selected! πŸ‘"
179
- when "Option 3"
180
- ctx.reply "Option 3 picked! 🎯"
181
- when "Cancel"
182
- ctx.reply "Cancelled! ❌"
183
- else
184
- ctx.reply "I got: #{text}"
185
- end
186
- end
187
- ```
188
-
189
- Restart your bot and try /menu to see the keyboard!
190
-
191
- ---
192
-
193
- πŸ› οΈ Step 7: Common Fixes
194
-
195
- "Token is invalid" error?
196
-
197
- Β· Make sure you copied the entire token
198
- Β· Check there are no spaces before/after
199
- Β· Try creating a new bot with @BotFather
200
-
201
- "gem not found" error?
202
-
203
- Β· Run gem install telegem again
204
- Β· Check Ruby version: ruby -v (should be 3.0+)
205
-
206
- Bot not responding?
207
-
208
- Β· Make sure your bot is running (ruby my_first_bot.rb)
209
- Β· Check you've started the bot in Telegram (send /start)
210
- Β· Wait a few seconds - sometimes there's a small delay
211
-
212
- Want to stop the bot?
213
-
214
- Press Ctrl+C in your terminal.
215
-
216
- ---
217
-
218
- πŸš€ Next Steps
219
-
220
- Your bot is working! Now try:
221
-
222
- 1. Change the replies - Make the bot say different things
223
- 2. Add more commands - Try /time to send current time
224
- 3. Send a photo - Add this to your bot:
225
- ```ruby
226
- bot.command('photo') do |ctx|
227
- ctx.reply "Here's a cat! 🐱"
228
- # Send a cat photo from the internet
229
- ctx.photo("https://placekitten.com/400/400")
230
- end
231
- ```
232
- 4. Check the examples - Look in the /examples folder for more ideas
233
- 5. Read the API Reference - When you're ready for more features, check api.md
234
-
235
- ---
236
-
237
- πŸ’‘ Tips for Beginners
238
-
239
- Β· Save your token safely - You'll need it every time
240
- Β· Restart after changes - Stop (Ctrl+C) and restart your bot when you change the code
241
- Β· Start simple - Get one thing working before adding more
242
- Β· Use puts for debugging - Add puts "Got here!" to see what's happening
243
-
244
- ---
245
-
246
- πŸ†˜ Need Help?
247
-
248
- 1. Check your code against the examples above
249
- 2. Read error messages - They often tell you what's wrong
250
- 3. Ask for help - Open an issue on GitLab
251
-
252
- ---
253
-
254
- πŸŽ‰ You did it! You've built your first Telegram bot. What will you create next?
255
-
256
- ```
257
-
258
- ---
@@ -1,434 +0,0 @@
1
- 🧠 Telegem Scenes: The Complete Guide (Without the Confusion)
2
-
3
- Scenes are conversation flows in Telegem. They handle back-and-forth interactions like forms, surveys, or onboarding. Let's remove all confusion.
4
-
5
- πŸ“– The Two-Step Dance: Define vs. Start
6
-
7
- Scenes work in two distinct phases:
8
-
9
- ```ruby
10
- # PHASE 1: DEFINE (Write the script)
11
- bot.scene :registration do
12
- step :ask_name { |ctx| ctx.reply "What's your name?" }
13
- step :ask_email { |ctx| ctx.reply "What's your email?" }
14
- end
15
-
16
- # PHASE 2: START (Run the script)
17
- bot.command('register') do |ctx|
18
- ctx.enter_scene(:registration) # This actually begins the scene
19
- end
20
- ```
21
-
22
- 🎯 The Analogy That Makes Sense
23
-
24
- Β· bot.scene = Writing a movie script
25
- Β· ctx.enter_scene = Yelling "Action!" on set
26
- Β· The scene steps = What the actors actually do
27
-
28
- πŸ”§ The Complete Working Template
29
-
30
- ```ruby
31
- require 'telegem'
32
-
33
- bot = Telegem.new('YOUR_BOT_TOKEN')
34
-
35
- # =============== DEFINE THE SCENE ===============
36
- bot.scene :feedback do
37
- # Optional: Runs when scene starts
38
- on_enter do |ctx|
39
- ctx.session[:feedback] = { user_id: ctx.from.id }
40
- ctx.reply "πŸ“ Let's collect your feedback!"
41
- end
42
-
43
- # Step 1: Ask for rating
44
- step :ask_rating do |ctx|
45
- keyboard = Telegem::Markup.inline do
46
- row callback("⭐️ 1", "rating_1"), callback("⭐️ 2", "rating_2")
47
- row callback("⭐️ 3", "rating_3"), callback("⭐️ 4", "rating_4"), callback("⭐️ 5", "rating_5")
48
- end
49
- ctx.reply "How would you rate us? (1-5 stars)", reply_markup: keyboard
50
- end
51
-
52
- # Step 2: Handle rating choice
53
- step :handle_rating do |ctx|
54
- if ctx.data&.start_with?('rating_')
55
- rating = ctx.data.split('_').last.to_i
56
- ctx.session[:feedback][:rating] = rating
57
- ctx.reply "Thanks! Now please share your comments:"
58
- else
59
- ctx.reply "Please use the buttons above ⬆️"
60
- return # Stay on this step
61
- end
62
- end
63
-
64
- # Step 3: Collect comments
65
- step :collect_comments do |ctx|
66
- if ctx.message.text
67
- ctx.session[:feedback][:comments] = ctx.message.text
68
-
69
- # Show summary
70
- summary = <<~SUMMARY
71
- πŸ“‹ **Feedback Summary:**
72
-
73
- Rating: #{ctx.session[:feedback][:rating]} stars
74
- Comments: #{ctx.session[:feedback][:comments]}
75
-
76
- Submit? (yes/no)
77
- SUMMARY
78
-
79
- ctx.reply summary, parse_mode: 'Markdown'
80
- end
81
- end
82
-
83
- # Step 4: Final confirmation
84
- step :confirm do |ctx|
85
- if ctx.message.text&.downcase == 'yes'
86
- save_feedback(ctx.session[:feedback])
87
- ctx.reply "βœ… Feedback submitted! Thank you."
88
- else
89
- ctx.reply "❌ Feedback cancelled."
90
- end
91
- ctx.leave_scene
92
- end
93
-
94
- # Optional: Runs when scene ends (success or cancel)
95
- on_leave do |ctx|
96
- ctx.session.delete(:feedback)
97
- ctx.reply "Back to main menu!"
98
- end
99
- end
100
-
101
- # =============== START THE SCENE ===============
102
- bot.command('feedback') do |ctx|
103
- ctx.enter_scene(:feedback) # THIS actually starts it
104
- end
105
-
106
- # Start the bot
107
- bot.start_polling
108
- ```
109
-
110
- πŸ“¦ 4 Production-Ready Scene Templates
111
-
112
- Template 1: Simple Form (Beginner Friendly)
113
-
114
- Perfect for basic data collection.
115
-
116
- ```ruby
117
- bot.scene :quick_survey do
118
- on_enter { |ctx| ctx.reply "Quick 3-question survey:" }
119
-
120
- step :q1 do |ctx|
121
- ctx.reply "1. What's your favorite language? (Ruby/JS/Python)"
122
- end
123
-
124
- step :q2 do |ctx|
125
- ctx.session[:lang] = ctx.message.text
126
- ctx.reply "2. How many years experience?"
127
- end
128
-
129
- step :q3 do |ctx|
130
- ctx.session[:exp] = ctx.message.text
131
- ctx.reply "3. What's your biggest challenge?"
132
- end
133
-
134
- step :finish do |ctx|
135
- ctx.session[:challenge] = ctx.message.text
136
- save_survey(ctx.session)
137
- ctx.reply "βœ… Survey complete! Thanks for sharing."
138
- ctx.leave_scene
139
- end
140
- end
141
-
142
- # Usage: /survey
143
- bot.command('survey') { |ctx| ctx.enter_scene(:quick_survey) }
144
- ```
145
-
146
- Template 2: Menu Navigator (With Branching)
147
-
148
- For complex flows with different paths.
149
-
150
- ```ruby
151
- bot.scene :support_ticket do
152
- step :ask_type do |ctx|
153
- keyboard = Telegem::Markup.keyboard do
154
- row "πŸ› Bug Report", "✨ Feature Request"
155
- row "❓ Question", "πŸ”§ Technical Issue"
156
- end
157
- ctx.reply "What type of support do you need?", reply_markup: keyboard
158
- end
159
-
160
- step :collect_details do |ctx|
161
- type = ctx.message.text
162
- ctx.session[:ticket_type] = type
163
-
164
- case type
165
- when "πŸ› Bug Report"
166
- ctx.reply "Describe the bug (steps to reproduce):"
167
- ctx.session[:next_action] = :save_bug
168
- when "✨ Feature Request"
169
- ctx.reply "Describe the feature you'd like:"
170
- ctx.session[:next_action] = :save_feature
171
- else
172
- ctx.reply "Describe your issue:"
173
- ctx.session[:next_action] = :save_general
174
- end
175
- end
176
-
177
- step :process_ticket do |ctx|
178
- description = ctx.message.text
179
- ticket_id = "TICKET-#{SecureRandom.hex(4).upcase}"
180
-
181
- case ctx.session[:next_action]
182
- when :save_bug
183
- save_to_database(type: 'bug', desc: description, id: ticket_id)
184
- ctx.reply "πŸ› Bug logged as #{ticket_id}"
185
- when :save_feature
186
- save_to_database(type: 'feature', desc: description, id: ticket_id)
187
- ctx.reply "✨ Feature requested as #{ticket_id}"
188
- end
189
-
190
- ctx.leave_scene
191
- end
192
-
193
- on_leave do |ctx|
194
- ctx.reply "Support will contact you soon. Use /status to check ticket."
195
- end
196
- end
197
-
198
- # Usage: /support
199
- bot.command('support') { |ctx| ctx.enter_scene(:support_ticket) }
200
- ```
201
-
202
- Template 3: Async Data Fetching (Advanced)
203
-
204
- For scenes that need to fetch external data.
205
-
206
- ```ruby
207
- bot.scene :github_analyzer do
208
- step :ask_repo do |ctx|
209
- ctx.reply "Enter a GitHub repo URL (e.g., https://github.com/user/repo):"
210
- end
211
-
212
- step :fetch_data do |ctx|
213
- url = ctx.message.text
214
-
215
- # Show loading
216
- ctx.reply "⏳ Fetching repo data..."
217
-
218
- # Async HTTP request
219
- Async do
220
- begin
221
- # Fetch from GitHub API using httpx
222
- data = await fetch_github_data(url)
223
-
224
- # Show results
225
- info = <<~INFO
226
- πŸ“Š **Repo Analysis:**
227
-
228
- Name: #{data[:name]}
229
- Stars: #{data[:stars]}
230
- Language: #{data[:language]}
231
- Description: #{data[:description]}
232
-
233
- Last updated: #{data[:updated_at]}
234
- INFO
235
-
236
- ctx.reply info, parse_mode: 'Markdown'
237
-
238
- rescue => e
239
- ctx.reply "❌ Error: #{e.message}"
240
- ensure
241
- ctx.leave_scene
242
- end
243
- end
244
- end
245
- end
246
-
247
- # Usage: /analyze
248
- bot.command('analyze') { |ctx| ctx.enter_scene(:github_analyzer) }
249
- ```
250
-
251
- Template 4: Multi-Step With Validation (Production Ready)
252
-
253
- Includes proper error handling and validation.
254
-
255
- ```ruby
256
- bot.scene :user_registration, timeout: 300 do # 5 minute timeout
257
- on_enter do |ctx|
258
- ctx.session[:registration] = {
259
- started_at: Time.now,
260
- attempts: 0,
261
- data: {}
262
- }
263
- ctx.reply "πŸ‘€ Registration Process\n\nLet's get started!"
264
- end
265
-
266
- step :ask_email do |ctx|
267
- ctx.reply "Enter your email address:"
268
- end
269
-
270
- step :validate_email do |ctx|
271
- email = ctx.message.text.strip
272
-
273
- unless email.include?('@') && email.include?('.')
274
- ctx.session[:registration][:attempts] += 1
275
-
276
- if ctx.session[:registration][:attempts] >= 3
277
- ctx.reply "❌ Too many attempts. Registration cancelled."
278
- ctx.leave_scene
279
- return
280
- end
281
-
282
- ctx.reply "❌ Invalid email format. Please try again:"
283
- return # Stay on this step
284
- end
285
-
286
- # Email is valid
287
- ctx.session[:registration][:data][:email] = email
288
- ctx.session[:registration][:attempts] = 0
289
- ctx.reply "βœ… Email accepted!"
290
- ctx.reply "Enter your full name:"
291
- end
292
-
293
- step :ask_password do |ctx|
294
- ctx.session[:registration][:data][:name] = ctx.message.text
295
- ctx.reply "Create a password (min 8 characters):"
296
- end
297
-
298
- step :confirm_registration do |ctx|
299
- password = ctx.message.text
300
-
301
- if password.length < 8
302
- ctx.reply "❌ Password too short. Min 8 characters:"
303
- return
304
- end
305
-
306
- ctx.session[:registration][:data][:password] = password
307
-
308
- # Show summary
309
- summary = <<~SUMMARY
310
- πŸ“‹ **Registration Summary:**
311
-
312
- Email: #{ctx.session[:registration][:data][:email]}
313
- Name: #{ctx.session[:registration][:data][:name]}
314
-
315
- Confirm registration? (yes/no)
316
- SUMMARY
317
-
318
- ctx.reply summary, parse_mode: 'Markdown'
319
- end
320
-
321
- step :finalize do |ctx|
322
- if ctx.message.text&.downcase == 'yes'
323
- # Save to database
324
- user_id = create_user(ctx.session[:registration][:data])
325
- ctx.reply "βœ… Registration complete!\nYour ID: #{user_id}"
326
- else
327
- ctx.reply "❌ Registration cancelled."
328
- end
329
- ctx.leave_scene
330
- end
331
-
332
- on_timeout do |ctx|
333
- ctx.reply "⏰ Registration timed out. Please start over with /register."
334
- ctx.session.delete(:registration)
335
- end
336
-
337
- on_leave do |ctx|
338
- # Cleanup
339
- ctx.session.delete(:registration)
340
- end
341
- end
342
-
343
- # Usage: /register
344
- bot.command('register') { |ctx| ctx.enter_scene(:user_registration) }
345
- ```
346
-
347
- πŸš€ Common Patterns Cheat Sheet
348
-
349
- Pattern 1: Basic Form Flow
350
-
351
- ```ruby
352
- bot.scene :simple_form
353
- bot.command('start_form') { |ctx| ctx.enter_scene(:simple_form) }
354
- ```
355
-
356
- Pattern 2: Inline Button Navigation
357
-
358
- ```ruby
359
- bot.scene :menu_driven
360
- # Uses callback buttons for choices
361
- ```
362
-
363
- Pattern 3: Async Operations
364
-
365
- ```ruby
366
- bot.scene :async_task
367
- # Uses Async { } for HTTP/DB operations
368
- ```
369
-
370
- Pattern 4: Validated Input
371
-
372
- ```ruby
373
- bot.scene :validated_input
374
- # Uses return to stay on step when validation fails
375
- ```
376
-
377
- πŸ”§ Debugging Scenes: Quick Fixes
378
-
379
- ❌ "Scene doesn't start!"
380
-
381
- Check: Did you call ctx.enter_scene?
382
-
383
- ```ruby
384
- bot.command('start') do |ctx|
385
- ctx.enter_scene(:your_scene) # ← MUST BE PRESENT
386
- end
387
- ```
388
-
389
- ❌ "Steps skip unexpectedly!"
390
-
391
- Cause: Missing return on validation failure
392
- Fix:
393
-
394
- ```ruby
395
- step :collect_age do |ctx|
396
- age = ctx.message.text.to_i
397
- if age < 18
398
- ctx.reply "Must be 18+. Try again:"
399
- return # ← THIS keeps you on the same step
400
- end
401
- # Continues only if age >= 18
402
- end
403
- ```
404
-
405
- ❌ "Data lost between steps!"
406
-
407
- Solution: Use ctx.session
408
-
409
- ```ruby
410
- step :one do |ctx|
411
- ctx.session[:temp] = "saved data" # ← Save
412
- end
413
-
414
- step :two do |ctx|
415
- data = ctx.session[:temp] # ← Retrieve
416
- end
417
- ```
418
-
419
- πŸ“ Remember This Mental Model
420
-
421
- 1. Define once (bot.scene) - Teach the bot a conversation pattern
422
- 2. Start many times (ctx.enter_scene) - Begin that conversation with users
423
- 3. Steps auto-advance - After user responds, Telegem moves to next step
424
- 4. Use ctx.session - Store data between steps
425
- 5. Clean up in on_leave - Remove session data when done
426
-
427
- 🎯 Your Homework (Test Understanding)
428
-
429
- 1. Create a pizza ordering scene with size and toppings
430
- 2. Add validation (size must be S/M/L, max 3 toppings)
431
- 3. Add a timeout of 10 minutes
432
- 4. Test it with /order_pizza
433
-
434
- You now have everything you need to build robust scenes. The key is practiceβ€”start simple, then add complexity one piece at a time.