telegem 3.3.0 → 3.4.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.
data/docs/api.md ADDED
@@ -0,0 +1,663 @@
1
+ # API Reference
2
+
3
+ Complete reference for Telegem's API client and available methods.
4
+
5
+ ## API Client
6
+
7
+ The `Telegem::API::Client` handles all communication with Telegram's Bot API.
8
+
9
+ ### Initialization
10
+
11
+ ```ruby
12
+ client = Telegem::API::Client.new(token, **options)
13
+ ```
14
+
15
+ **Parameters:**
16
+ - `token` (String): Bot token
17
+ - `options` (Hash):
18
+ - `logger` (Logger): Logger instance
19
+ - `timeout` (Integer): Request timeout in seconds (default: 30)
20
+
21
+ ### Methods
22
+
23
+ #### call(method, params = {})
24
+
25
+ Make a synchronous API call.
26
+
27
+ ```ruby
28
+ result = client.call('sendMessage', {
29
+ chat_id: 123,
30
+ text: 'Hello'
31
+ })
32
+ ```
33
+
34
+ #### call!(method, params = {}, &callback)
35
+
36
+ Make an asynchronous API call with callback.
37
+
38
+ ```ruby
39
+ client.call!('sendMessage', { chat_id: 123, text: 'Hello' }) do |result, error|
40
+ if error
41
+ puts "Error: #{error.message}"
42
+ else
43
+ puts "Message sent: #{result['message_id']}"
44
+ end
45
+ end
46
+ ```
47
+
48
+ #### upload(method, params)
49
+
50
+ Upload files with multipart/form-data.
51
+
52
+ ```ruby
53
+ client.upload('sendPhoto', {
54
+ chat_id: 123,
55
+ photo: File.open('image.jpg'),
56
+ caption: 'Photo'
57
+ })
58
+ ```
59
+
60
+ #### download(file_id, destination_path = nil)
61
+
62
+ Download files from Telegram.
63
+
64
+ ```ruby
65
+ # Download to memory
66
+ content = client.download('file_id')
67
+
68
+ # Download to file
69
+ client.download('file_id', '/path/to/file.jpg')
70
+ ```
71
+
72
+ #### get_updates(options = {})
73
+
74
+ Get updates (used internally by polling).
75
+
76
+ ```ruby
77
+ updates = client.get_updates(
78
+ offset: 123,
79
+ limit: 100,
80
+ timeout: 30,
81
+ allowed_updates: ['message']
82
+ )
83
+ ```
84
+
85
+ ## Available API Methods
86
+
87
+ ### Sending Messages
88
+
89
+ #### sendMessage
90
+
91
+ ```ruby
92
+ bot.api.call('sendMessage', {
93
+ chat_id: chat_id,
94
+ text: 'Hello world',
95
+ parse_mode: 'Markdown', # 'Markdown' or 'HTML'
96
+ disable_web_page_preview: true,
97
+ reply_to_message_id: 123,
98
+ reply_markup: keyboard_markup
99
+ })
100
+ ```
101
+
102
+ #### sendPhoto
103
+
104
+ ```ruby
105
+ bot.api.call('sendPhoto', {
106
+ chat_id: chat_id,
107
+ photo: 'file_id_or_url',
108
+ caption: 'Photo caption',
109
+ parse_mode: 'Markdown',
110
+ reply_markup: keyboard
111
+ })
112
+ ```
113
+
114
+ #### sendDocument
115
+
116
+ ```ruby
117
+ bot.api.call('sendDocument', {
118
+ chat_id: chat_id,
119
+ document: file,
120
+ caption: 'Document caption',
121
+ parse_mode: 'Markdown'
122
+ })
123
+ ```
124
+
125
+ #### sendAudio
126
+
127
+ ```ruby
128
+ bot.api.call('sendAudio', {
129
+ chat_id: chat_id,
130
+ audio: file,
131
+ caption: 'Audio caption',
132
+ title: 'Song title',
133
+ performer: 'Artist name',
134
+ duration: 180
135
+ })
136
+ ```
137
+
138
+ #### sendVideo
139
+
140
+ ```ruby
141
+ bot.api.call('sendVideo', {
142
+ chat_id: chat_id,
143
+ video: file,
144
+ caption: 'Video caption',
145
+ duration: 60,
146
+ width: 1920,
147
+ height: 1080
148
+ })
149
+ ```
150
+
151
+ #### sendVoice
152
+
153
+ ```ruby
154
+ bot.api.call('sendVoice', {
155
+ chat_id: chat_id,
156
+ voice: file, # OGG format required
157
+ caption: 'Voice message',
158
+ duration: 10
159
+ })
160
+ ```
161
+
162
+ #### sendLocation
163
+
164
+ ```ruby
165
+ bot.api.call('sendLocation', {
166
+ chat_id: chat_id,
167
+ latitude: 37.7749,
168
+ longitude: -122.4194
169
+ })
170
+ ```
171
+
172
+ #### sendContact
173
+
174
+ ```ruby
175
+ bot.api.call('sendContact', {
176
+ chat_id: chat_id,
177
+ phone_number: '+1234567890',
178
+ first_name: 'John',
179
+ last_name: 'Doe'
180
+ })
181
+ ```
182
+
183
+ #### sendPoll
184
+
185
+ ```ruby
186
+ bot.api.call('sendPoll', {
187
+ chat_id: chat_id,
188
+ question: 'What\'s your favorite color?',
189
+ options: ['Red', 'Blue', 'Green'],
190
+ is_anonymous: true,
191
+ allows_multiple_answers: false
192
+ })
193
+ ```
194
+
195
+ ### Editing Messages
196
+
197
+ #### editMessageText
198
+
199
+ ```ruby
200
+ bot.api.call('editMessageText', {
201
+ chat_id: chat_id,
202
+ message_id: 123,
203
+ text: 'Updated text',
204
+ parse_mode: 'Markdown'
205
+ })
206
+ ```
207
+
208
+ #### editMessageCaption
209
+
210
+ ```ruby
211
+ bot.api.call('editMessageCaption', {
212
+ chat_id: chat_id,
213
+ message_id: 123,
214
+ caption: 'New caption'
215
+ })
216
+ ```
217
+
218
+ #### editMessageReplyMarkup
219
+
220
+ ```ruby
221
+ bot.api.call('editMessageReplyMarkup', {
222
+ chat_id: chat_id,
223
+ message_id: 123,
224
+ reply_markup: new_keyboard
225
+ })
226
+ ```
227
+
228
+ ### Deleting Messages
229
+
230
+ #### deleteMessage
231
+
232
+ ```ruby
233
+ bot.api.call('deleteMessage', {
234
+ chat_id: chat_id,
235
+ message_id: 123
236
+ })
237
+ ```
238
+
239
+ ### Chat Management
240
+
241
+ #### getChat
242
+
243
+ ```ruby
244
+ chat = bot.api.call('getChat', chat_id: chat_id)
245
+ ```
246
+
247
+ #### getChatAdministrators
248
+
249
+ ```ruby
250
+ admins = bot.api.call('getChatAdministrators', chat_id: chat_id)
251
+ ```
252
+
253
+ #### getChatMembersCount
254
+
255
+ ```ruby
256
+ count = bot.api.call('getChatMembersCount', chat_id: chat_id)
257
+ ```
258
+
259
+ #### kickChatMember
260
+
261
+ ```ruby
262
+ bot.api.call('kickChatMember', {
263
+ chat_id: chat_id,
264
+ user_id: user_id,
265
+ until_date: future_timestamp,
266
+ revoke_messages: true
267
+ })
268
+ ```
269
+
270
+ #### banChatMember
271
+
272
+ ```ruby
273
+ bot.api.call('banChatMember', {
274
+ chat_id: chat_id,
275
+ user_id: user_id,
276
+ until_date: future_timestamp,
277
+ revoke_messages: true
278
+ })
279
+ ```
280
+
281
+ #### unbanChatMember
282
+
283
+ ```ruby
284
+ bot.api.call('unbanChatMember', {
285
+ chat_id: chat_id,
286
+ user_id: user_id,
287
+ only_if_banned: true
288
+ })
289
+ ```
290
+
291
+ #### restrictChatMember
292
+
293
+ ```ruby
294
+ bot.api.call('restrictChatMember', {
295
+ chat_id: chat_id,
296
+ user_id: user_id,
297
+ permissions: {
298
+ can_send_messages: false,
299
+ can_send_media_messages: false
300
+ },
301
+ until_date: future_timestamp
302
+ })
303
+ ```
304
+
305
+ #### promoteChatMember
306
+
307
+ ```ruby
308
+ bot.api.call('promoteChatMember', {
309
+ chat_id: chat_id,
310
+ user_id: user_id,
311
+ can_change_info: true,
312
+ can_delete_messages: true,
313
+ can_invite_users: true,
314
+ can_restrict_members: true,
315
+ can_pin_messages: true,
316
+ can_promote_members: false
317
+ })
318
+ ```
319
+
320
+ ### Message Management
321
+
322
+ #### pinChatMessage
323
+
324
+ ```ruby
325
+ bot.api.call('pinChatMessage', {
326
+ chat_id: chat_id,
327
+ message_id: 123,
328
+ disable_notification: false
329
+ })
330
+ ```
331
+
332
+ #### unpinChatMessage
333
+
334
+ ```ruby
335
+ bot.api.call('unpinChatMessage', {
336
+ chat_id: chat_id,
337
+ message_id: 123
338
+ })
339
+ ```
340
+
341
+ #### unpinAllChatMessages
342
+
343
+ ```ruby
344
+ bot.api.call('unpinAllChatMessages', chat_id: chat_id)
345
+ ```
346
+
347
+ #### forwardMessage
348
+
349
+ ```ruby
350
+ bot.api.call('forwardMessage', {
351
+ chat_id: destination_chat_id,
352
+ from_chat_id: source_chat_id,
353
+ message_id: 123,
354
+ disable_notification: false
355
+ })
356
+ ```
357
+
358
+ #### copyMessage
359
+
360
+ ```ruby
361
+ bot.api.call('copyMessage', {
362
+ chat_id: destination_chat_id,
363
+ from_chat_id: source_chat_id,
364
+ message_id: 123,
365
+ caption: 'Copied message'
366
+ })
367
+ ```
368
+
369
+ ### Bot Commands
370
+
371
+ #### setMyCommands
372
+
373
+ ```ruby
374
+ bot.api.call('setMyCommands', {
375
+ commands: [
376
+ { command: 'start', description: 'Start the bot' },
377
+ { command: 'help', description: 'Get help' }
378
+ ]
379
+ })
380
+ ```
381
+
382
+ #### getMyCommands
383
+
384
+ ```ruby
385
+ commands = bot.api.call('getMyCommands')
386
+ ```
387
+
388
+ #### deleteMyCommands
389
+
390
+ ```ruby
391
+ bot.api.call('deleteMyCommands')
392
+ ```
393
+
394
+ ### Webhook Management
395
+
396
+ #### setWebhook
397
+
398
+ ```ruby
399
+ bot.api.call('setWebhook', {
400
+ url: 'https://example.com/webhook',
401
+ max_connections: 40,
402
+ allowed_updates: ['message', 'callback_query'],
403
+ secret_token: 'secret_token'
404
+ })
405
+ ```
406
+
407
+ #### deleteWebhook
408
+
409
+ ```ruby
410
+ bot.api.call('deleteWebhook')
411
+ ```
412
+
413
+ #### getWebhookInfo
414
+
415
+ ```ruby
416
+ info = bot.api.call('getWebhookInfo')
417
+ ```
418
+
419
+ ### File Operations
420
+
421
+ #### getFile
422
+
423
+ ```ruby
424
+ file_info = bot.api.call('getFile', file_id: file_id)
425
+ file_path = file_info['file_path']
426
+ ```
427
+
428
+ ### Inline Queries
429
+
430
+ #### answerInlineQuery
431
+
432
+ ```ruby
433
+ bot.api.call('answerInlineQuery', {
434
+ inline_query_id: query_id,
435
+ results: [result_objects],
436
+ cache_time: 300,
437
+ next_offset: '20'
438
+ })
439
+ ```
440
+
441
+ ### Callback Queries
442
+
443
+ #### answerCallbackQuery
444
+
445
+ ```ruby
446
+ bot.api.call('answerCallbackQuery', {
447
+ callback_query_id: callback_id,
448
+ text: 'Button pressed!',
449
+ show_alert: false,
450
+ url: 'https://example.com',
451
+ cache_time: 5
452
+ })
453
+ ```
454
+
455
+ ### Chat Actions
456
+
457
+ #### sendChatAction
458
+
459
+ ```ruby
460
+ bot.api.call('sendChatAction', {
461
+ chat_id: chat_id,
462
+ action: 'typing' # typing, upload_photo, upload_video, etc.
463
+ })
464
+ ```
465
+
466
+ ### Games
467
+
468
+ #### sendGame
469
+
470
+ ```ruby
471
+ bot.api.call('sendGame', {
472
+ chat_id: chat_id,
473
+ game_short_name: 'my_game'
474
+ })
475
+ ```
476
+
477
+ #### setGameScore
478
+
479
+ ```ruby
480
+ bot.api.call('setGameScore', {
481
+ user_id: user_id,
482
+ score: 100,
483
+ chat_id: chat_id,
484
+ message_id: 123
485
+ })
486
+ ```
487
+
488
+ ### Payments
489
+
490
+ #### sendInvoice
491
+
492
+ ```ruby
493
+ bot.api.call('sendInvoice', {
494
+ chat_id: chat_id,
495
+ title: 'Product',
496
+ description: 'Description',
497
+ payload: 'order_id',
498
+ provider_token: 'payment_token',
499
+ currency: 'USD',
500
+ prices: [{ label: 'Price', amount: 1000 }]
501
+ })
502
+ ```
503
+
504
+ #### answerShippingQuery
505
+
506
+ ```ruby
507
+ bot.api.call('answerShippingQuery', {
508
+ shipping_query_id: query_id,
509
+ ok: true,
510
+ shipping_options: [shipping_option]
511
+ })
512
+ ```
513
+
514
+ #### answerPreCheckoutQuery
515
+
516
+ ```ruby
517
+ bot.api.call('answerPreCheckoutQuery', {
518
+ pre_checkout_query_id: query_id,
519
+ ok: true
520
+ })
521
+ ```
522
+
523
+ ### Stickers
524
+
525
+ #### sendSticker
526
+
527
+ ```ruby
528
+ bot.api.call('sendSticker', {
529
+ chat_id: chat_id,
530
+ sticker: sticker_file_id
531
+ })
532
+ ```
533
+
534
+ #### getStickerSet
535
+
536
+ ```ruby
537
+ sticker_set = bot.api.call('getStickerSet', name: 'sticker_set_name')
538
+ ```
539
+
540
+ ### Profile Management
541
+
542
+ #### setMyProfilePhoto
543
+
544
+ ```ruby
545
+ bot.api.call('setMyProfilePhoto', {
546
+ photo: photo_file
547
+ })
548
+ ```
549
+
550
+ #### removeMyProfilePhoto
551
+
552
+ ```ruby
553
+ bot.api.call('removeMyProfilePhoto')
554
+ ```
555
+
556
+ ### Business Features
557
+
558
+ #### sendBusinessMessage
559
+
560
+ ```ruby
561
+ bot.api.call('sendBusinessMessage', {
562
+ business_connection_id: connection_id,
563
+ chat_id: chat_id,
564
+ text: 'Business message'
565
+ })
566
+ ```
567
+
568
+ ## Context Methods
569
+
570
+ Convenience methods available on the context object.
571
+
572
+ ### Message Sending
573
+
574
+ ```ruby
575
+ ctx.reply(text, **options)
576
+ ctx.photo(file, **options)
577
+ ctx.document(file, **options)
578
+ ctx.audio(file, **options)
579
+ ctx.video(file, **options)
580
+ ctx.voice(file, **options)
581
+ ctx.sticker(file_id, **options)
582
+ ctx.location(lat, lng, **options)
583
+ ctx.contact(phone, first_name, **options)
584
+ ```
585
+
586
+ ### Message Editing
587
+
588
+ ```ruby
589
+ ctx.edit_message_text(text, **options)
590
+ ctx.edit_message_caption(caption, **options)
591
+ ctx.edit_message_reply_markup(keyboard, **options)
592
+ ctx.delete_message(message_id)
593
+ ```
594
+
595
+ ### Chat Management
596
+
597
+ ```ruby
598
+ ctx.kick_chat_member(user_id, **options)
599
+ ctx.ban_chat_member(user_id, **options)
600
+ ctx.unban_chat_member(user_id, **options)
601
+ ctx.restrict_chat_member(user_id, **options)
602
+ ctx.promote_chat_member(user_id, **options)
603
+ ```
604
+
605
+ ### Utilities
606
+
607
+ ```ruby
608
+ ctx.answer_callback_query(**options)
609
+ ctx.answer_inline_query(results, **options)
610
+ ctx.send_chat_action(action, **options)
611
+ ctx.download_file(file_id, path)
612
+ ```
613
+
614
+ ## Error Handling
615
+
616
+ API calls raise `Telegem::API::APIError` on failure.
617
+
618
+ ```ruby
619
+ begin
620
+ result = bot.api.call('sendMessage', params)
621
+ rescue Telegem::API::APIError => e
622
+ puts "API Error: #{e.message}"
623
+ puts "Error code: #{e.code}" if e.code
624
+ end
625
+ ```
626
+
627
+ ### Common Error Codes
628
+
629
+ - `400` - Bad Request (invalid parameters)
630
+ - `401` - Unauthorized (invalid token)
631
+ - `403` - Forbidden (bot blocked by user)
632
+ - `404` - Not Found (chat/user not found)
633
+ - `429` - Too Many Requests (rate limited)
634
+
635
+ ## Rate Limits
636
+
637
+ Telegram imposes rate limits on bot API calls:
638
+
639
+ - 30 messages per second for broadcasting
640
+ - 20 callback query answers per second
641
+ - 60 API calls per minute for other methods
642
+
643
+ Implement rate limiting middleware for high-traffic bots.
644
+
645
+ ## File Upload Limits
646
+
647
+ - Photos: 10 MB
648
+ - Documents: 50 MB
649
+ - Videos: 50 MB (upload), 20 MB (via URL)
650
+ - Other files: 50 MB
651
+
652
+ ## Best Practices
653
+
654
+ 1. **Use appropriate timeouts** for your use case
655
+ 2. **Handle API errors gracefully** with retries
656
+ 3. **Implement rate limiting** to avoid hitting limits
657
+ 4. **Validate parameters** before API calls
658
+ 5. **Use webhooks** for production deployments
659
+ 6. **Log API calls** for debugging
660
+ 7. **Cache file IDs** to avoid re-uploading
661
+
662
+ The Telegram Bot API is extensive. Refer to the [official documentation](https://core.telegram.org/bots/api) for complete method reference.</content>
663
+ <parameter name="filePath">/home/slick/telegem/docs/api.md