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
@@ -0,0 +1,413 @@
1
+
2
+ # Keyboards & Inline Keyboards Guide
3
+
4
+ Learn how to create interactive buttons for your Telegram bot.
5
+
6
+ ## 📱 Two Types of Keyboards
7
+
8
+ ### Reply Keyboard (Bottom of Chat)
9
+ **Position:** Always at the bottom of the chat screen
10
+ **Behavior:** User taps → Sends a text message to chat
11
+ **Best for:** Menus, forms, options that everyone should see
12
+ **Visibility:** All chat members see the keyboard
13
+
14
+ ### Inline Keyboard (Under Messages)
15
+ **Position:** Attached to a specific message
16
+ **Behavior:** User taps → Triggers private callback (no chat message)
17
+ **Best for:** Polls, votes, games, interactive content
18
+ **Visibility:** Only people who see the message can tap
19
+
20
+ ---
21
+
22
+ ## ⌨️ Reply Keyboards
23
+
24
+ ### Creating a Basic Keyboard
25
+ ```ruby
26
+ # Simple 2x2 keyboard
27
+ keyboard = Telegem.keyboard do
28
+ row "Yes", "No" # First row with 2 buttons
29
+ row "Maybe", "Cancel" # Second row with 2 buttons
30
+ end
31
+
32
+ # Send with message
33
+ ctx.reply("Do you agree?", reply_markup: keyboard)
34
+ ```
35
+
36
+ What happens:
37
+
38
+ 1. User sees keyboard at bottom with 4 buttons
39
+ 2. User taps "Yes"
40
+ 3. Bot receives message: "Yes"
41
+ 4. Everyone in chat sees "User: Yes"
42
+
43
+ Handling Keyboard Responses
44
+
45
+ ```ruby
46
+ # When user taps "Yes" from keyboard
47
+ bot.hears("Yes") do |ctx|
48
+ ctx.reply("Great! You agreed! ✅")
49
+ end
50
+
51
+ # When user taps "No"
52
+ bot.hears("No") do |ctx|
53
+ ctx.reply("Oh, you disagreed ❌")
54
+ end
55
+ ```
56
+
57
+ Keyboard Options
58
+
59
+ ```ruby
60
+ keyboard = Telegem.keyboard do
61
+ row "Option 1", "Option 2"
62
+ end.resize(false) # Don't resize buttons (keep original size)
63
+ .one_time(true) # Hide keyboard after first use
64
+ .selective(true) # Show only to mentioned users
65
+
66
+ ctx.reply("Choose:", reply_markup: keyboard)
67
+ ```
68
+
69
+ Special Button Types
70
+
71
+ ```ruby
72
+ keyboard = Telegem.keyboard do
73
+ request_contact("📞 Share Phone") # Requests phone number
74
+ request_location("📍 Share Location") # Requests GPS location
75
+ request_poll("📊 Create Poll") # Requests to create poll
76
+ end
77
+
78
+ ctx.reply("Share your info:", reply_markup: keyboard)
79
+ ```
80
+
81
+ Removing Keyboards
82
+
83
+ ```ruby
84
+ # Method 1: Using helper
85
+ ctx.reply("Keyboard removed", reply_markup: Telegem.remove)
86
+
87
+ # Method 2: After user makes choice
88
+ bot.hears("Done") do |ctx|
89
+ ctx.reply("Finished!", reply_markup: { remove_keyboard: true })
90
+ end
91
+ ```
92
+
93
+ Real Example: Pizza Order
94
+
95
+ ```ruby
96
+ bot.command("order") do |ctx|
97
+ # Step 1: Ask for size
98
+ keyboard = Telegem.keyboard do
99
+ row "Small 🍕", "Medium 🍕", "Large 🍕"
100
+ end
101
+
102
+ ctx.session[:step] = "size"
103
+ ctx.reply("Choose pizza size:", reply_markup: keyboard)
104
+ end
105
+
106
+ # Handle size selection
107
+ bot.hears(/Small|Medium|Large/) do |ctx|
108
+ if ctx.session[:step] == "size"
109
+ ctx.session[:size] = ctx.message.text
110
+
111
+ # Step 2: Ask for toppings
112
+ keyboard = Telegem.keyboard do
113
+ row "Cheese 🧀", "Pepperoni 🍖"
114
+ row "Mushroom 🍄", "Veggie 🥦"
115
+ end
116
+
117
+ ctx.session[:step] = "topping"
118
+ ctx.reply("Choose toppings:", reply_markup: keyboard)
119
+ end
120
+ end
121
+ ```
122
+
123
+ ---
124
+
125
+ 🔘 Inline Keyboards
126
+
127
+ Creating Basic Inline Buttons
128
+
129
+ ```ruby
130
+ # Create inline keyboard
131
+ inline = Telegem.inline do
132
+ row button "👍 Like", callback_data: "like"
133
+ row button "👎 Dislike", callback_data: "dislike"
134
+ end
135
+
136
+ # Send message with buttons underneath
137
+ ctx.reply("Rate this message:", reply_markup: inline)
138
+ ```
139
+
140
+ What happens:
141
+
142
+ 1. Message appears with buttons under it
143
+ 2. User taps "👍 Like"
144
+ 3. NO message appears in chat
145
+ 4. Bot receives private callback: data: "like"
146
+
147
+ Handling Inline Button Clicks
148
+
149
+ ```ruby
150
+ # This handles ALL inline button clicks
151
+ bot.on(:callback_query) do |ctx|
152
+ # ctx.data contains the callback_data from button
153
+
154
+ case ctx.data
155
+ when "like"
156
+ # Show popup notification (disappears after 2 seconds)
157
+ ctx.answer_callback_query(text: "Thanks for liking! ❤️")
158
+
159
+ # Update the original message
160
+ ctx.edit_message_text("✅ You liked this!")
161
+
162
+ when "dislike"
163
+ ctx.answer_callback_query(text: "Sorry you didn't like it 😢")
164
+ ctx.edit_message_text("😞 You disliked this")
165
+ end
166
+ end
167
+ ```
168
+
169
+ Different Button Types
170
+
171
+ ```ruby
172
+ inline = Telegem.inline do
173
+ # Opens URL when clicked
174
+ url "🌐 Visit Website", "https://example.com"
175
+
176
+ # Triggers callback (most common)
177
+ callback "✅ Select", "select_item_123"
178
+
179
+ # Opens web app
180
+ web_app "📱 Open App", "https://app.example.com"
181
+
182
+ # Login with Telegram
183
+ login "🔐 Login", "https://example.com/login"
184
+
185
+ # Switch to inline mode
186
+ switch_inline "🔍 Search", "cats"
187
+ end
188
+
189
+ ctx.reply("Choose action:", reply_markup: inline)
190
+ ```
191
+
192
+ Interactive Quiz Example
193
+
194
+ ```ruby
195
+ bot.command("quiz") do |ctx|
196
+ inline = Telegem.inline do
197
+ row button "Paris", callback_data: "answer_paris"
198
+ row button "London", callback_data: "answer_london"
199
+ row button "Berlin", callback_data: "answer_berlin"
200
+ end
201
+
202
+ ctx.reply("What is the capital of France?", reply_markup: inline)
203
+ end
204
+
205
+ bot.on(:callback_query) do |ctx|
206
+ case ctx.data
207
+ when "answer_paris"
208
+ ctx.answer_callback_query(text: "✅ Correct! Paris is right!")
209
+ ctx.edit_message_text("🎉 Correct! Paris is the capital of France")
210
+
211
+ when "answer_london", "answer_berlin"
212
+ ctx.answer_callback_query(text: "❌ Wrong! Try again", show_alert: true)
213
+ # Keep same question for retry
214
+ end
215
+ end
216
+ ```
217
+
218
+ Pagination Example (Multiple Pages)
219
+
220
+ ```ruby
221
+ ITEMS = ["Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig", "Grape"]
222
+
223
+ def items_keyboard(page = 0)
224
+ start = page * 3
225
+ page_items = ITEMS[start, 3] || []
226
+
227
+ Telegem.inline do
228
+ # Current page items
229
+ page_items.each do |item|
230
+ row button item, callback_data: "select_#{item}"
231
+ end
232
+
233
+ # Navigation buttons
234
+ row do
235
+ if page > 0
236
+ button "⬅️ Previous", callback_data: "page_#{page-1}"
237
+ end
238
+ button "📄 Page #{page+1}", callback_data: "current"
239
+ if ITEMS.length > (page + 1) * 3
240
+ button "Next ➡️", callback_data: "page_#{page+1}"
241
+ end
242
+ end
243
+ end
244
+ end
245
+
246
+ bot.command("fruits") do |ctx|
247
+ ctx.reply("Select a fruit:", reply_markup: items_keyboard)
248
+ end
249
+
250
+ bot.on(:callback_query) do |ctx|
251
+ if ctx.data.start_with?("select_")
252
+ fruit = ctx.data.split("_").last
253
+ ctx.answer_callback_query(text: "Selected: #{fruit}")
254
+ ctx.edit_message_text("You selected: #{fruit} 🍎")
255
+
256
+ elsif ctx.data.start_with?("page_")
257
+ page = ctx.data.split("_").last.to_i
258
+ ctx.edit_message_reply_markup(items_keyboard(page))
259
+ ctx.answer_callback_query # Empty response (no popup)
260
+ end
261
+ end
262
+ ```
263
+
264
+ ---
265
+
266
+ ⚖️ When to Use Which?
267
+
268
+ Use Reply Keyboard When:
269
+
270
+ · Creating a main menu
271
+ · Collecting user information (name, age, etc.)
272
+ · Multi-step forms
273
+ · Simple yes/no questions
274
+ · You want everyone to see the choice
275
+
276
+ Use Inline Keyboard When:
277
+
278
+ · Creating polls or votes
279
+ · Interactive games
280
+ · Confirmation dialogs (delete? confirm?)
281
+ · Paginated lists
282
+ · You want to keep chat clean
283
+ · Private interactions
284
+
285
+ ---
286
+
287
+ 🔧 Best Practices
288
+
289
+ 1. Button Text Length
290
+
291
+ ```ruby
292
+ # ❌ Too long
293
+ button "Click here to confirm your selection and proceed to checkout"
294
+
295
+ # ✅ Concise and clear
296
+ button "Confirm Purchase"
297
+ button "Proceed to Checkout"
298
+ ```
299
+
300
+ 2. Logical Grouping
301
+
302
+ ```ruby
303
+ # ✅ Group related actions
304
+ Telegem.keyboard do
305
+ row "View Products", "View Cart" # Shopping actions
306
+ row "My Account", "Help" # Account actions
307
+ row "Cancel" # Cancel action
308
+ end
309
+ ```
310
+
311
+ 3. Callback Data Optimization
312
+
313
+ ```ruby
314
+ # Store data efficiently in callback_data
315
+ # Format: "action:id:extra"
316
+ callback_data: "like:post_123:user_456"
317
+
318
+ # In handler
319
+ if ctx.data.start_with?("like:")
320
+ action, post_id, user_id = ctx.data.split(":")
321
+ # Process like
322
+ end
323
+ ```
324
+
325
+ 4. Error Handling
326
+
327
+ ```ruby
328
+ bot.on(:callback_query) do |ctx|
329
+ begin
330
+ # Your button handling logic
331
+ rescue => e
332
+ ctx.answer_callback_query(
333
+ text: "Something went wrong!",
334
+ show_alert: true
335
+ )
336
+ ctx.logger.error("Button error: #{e.message}")
337
+ end
338
+ end
339
+ ```
340
+
341
+ ---
342
+
343
+ 🎮 Complete Game Example
344
+
345
+ ```ruby
346
+ class NumberGame
347
+ def self.start_game(ctx)
348
+ inline = Telegem.inline do
349
+ row button "1️⃣", callback_data: "guess_1"
350
+ row button "2️⃣", callback_data: "guess_2"
351
+ row button "3️⃣", callback_data: "guess_3"
352
+ row button "4️⃣", callback_data: "guess_4"
353
+ row button "5️⃣", callback_data: "guess_5"
354
+ end
355
+
356
+ ctx.session[:secret_number] = rand(1..5)
357
+ ctx.reply("Guess the number (1-5):", reply_markup: inline)
358
+ end
359
+
360
+ def self.handle_guess(ctx)
361
+ guess = ctx.data.split("_").last.to_i
362
+ secret = ctx.session[:secret_number]
363
+
364
+ if guess == secret
365
+ ctx.answer_callback_query(text: "🎉 Correct! You won!")
366
+ ctx.edit_message_text("✅ Correct! The number was #{secret}")
367
+
368
+ # Play again button
369
+ inline = Telegem.inline do
370
+ row button "Play Again", callback_data: "play_again"
371
+ end
372
+ ctx.edit_message_reply_markup(inline)
373
+
374
+ else
375
+ ctx.answer_callback_query(text: "❌ Wrong! Try again")
376
+ # Keep same buttons
377
+ end
378
+ end
379
+ end
380
+
381
+ # Register handlers
382
+ bot.command("game") { |ctx| NumberGame.start_game(ctx) }
383
+ bot.on(:callback_query) do |ctx|
384
+ if ctx.data.start_with?("guess_")
385
+ NumberGame.handle_guess(ctx)
386
+ elsif ctx.data == "play_again"
387
+ NumberGame.start_game(ctx)
388
+ end
389
+ end
390
+ ```
391
+
392
+ ---
393
+
394
+ 📚 Summary
395
+
396
+ Aspect Reply Keyboard Inline Keyboard
397
+ Position Bottom of chat Under message
398
+ Creates Message Yes No
399
+ Chat Visibility Everyone sees choice Private
400
+ Best For Menus, forms Polls, games
401
+ Response Method bot.hears() bot.on(:callback_query)
402
+ Clean Chat No (adds messages) Yes (no spam)
403
+
404
+ Remember:
405
+
406
+ · Reply keyboards = Public conversation
407
+ · Inline keyboards = Private interaction
408
+ · Choose based on whether you want choices visible to everyone
409
+
410
+ Start with simple keyboards, then add inline buttons for interactive features! 🚀
411
+
412
+ ```
413
+ ```