telegem 3.2.4 → 3.3.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/CHANGELOG.md +103 -0
- data/Gemfile +1 -1
- data/Readme.md +2 -6
- data/bin/telegem-init +32 -0
- data/bin/telegem-ssl +7 -0
- data/lib/api/client.rb +1 -10
- data/lib/api/types.rb +321 -47
- data/lib/core/bot.rb +23 -17
- data/lib/core/context.rb +9 -7
- data/lib/core/rate_limit.rb +0 -14
- data/lib/core/scene.rb +1 -1
- data/lib/markup/inline.rb +104 -0
- data/lib/markup/keyboard.rb +77 -298
- data/lib/plugins/file_extract.rb +4 -24
- data/lib/session/memory_store.rb +91 -128
- data/lib/telegem.rb +3 -2
- data/lib/webhook/server.rb +1 -1
- metadata +17 -12
- data/CHANGELOG +0 -95
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d2afc9e262ffced76a28974a69c6e652bf433b2b6da80c6827d45e6da43002a
|
|
4
|
+
data.tar.gz: 61f440f2523473e3f5435075bfece0519c374f4aa498d789cc6752c5ce285abf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 378d55910d0b38b255b35ea357af4cb88f45000362b9d16688dff82a02fe3e5119e71e591c2cec61556d9c9cc82c0edd914ba7cd153ba1cae04c0e97b3f6d229
|
|
7
|
+
data.tar.gz: 527cb2833282c03d7f19145d7421e6df5d867ffbb479846ac9e969a8be339450c7358fdefaced5952dfc7d96b999348253a2494b2a2fe3d9c55480073587a421
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Telegem Changelog
|
|
2
|
+
|
|
3
|
+
## v3.3.1(lastest)
|
|
4
|
+
### Features
|
|
5
|
+
- improved memeorystore to include diskbackup
|
|
6
|
+
- added 'telegem-init' cli
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## v3.1.1
|
|
10
|
+
|
|
11
|
+
### New Features
|
|
12
|
+
|
|
13
|
+
-FileExtractor Plugin: New plugin for extracting content from various file types (PDF, JSON, HTML, TXT)
|
|
14
|
+
- Async File Download: Added download method to API client for downloading Telegram files
|
|
15
|
+
- Context File Helpers: Added download_file, download_photo, download_document methods to Context
|
|
16
|
+
- Extended File Support: Plugin supports PDF text extraction, JSON parsing, HTML/raw text processing
|
|
17
|
+
- Async/Sync Dual Mode: All file operations available in both sync (download) and async (download!) modes
|
|
18
|
+
|
|
19
|
+
## v3.1.0
|
|
20
|
+
|
|
21
|
+
### features
|
|
22
|
+
- BREAKING: Rewrote polling system to prevent duplicate messages
|
|
23
|
+
- Fixed thread deadlock in async polling loop
|
|
24
|
+
- Added scene_middleware.rb for scene-based conversations
|
|
25
|
+
- Improved MemoryStore with TTL and thread safety
|
|
26
|
+
- Enhanced keyboard markup builder with web_app support
|
|
27
|
+
- Added message reaction and chat boost update types
|
|
28
|
+
- Fixed callback query handling for inline keyboards
|
|
29
|
+
|
|
30
|
+
## v3.0.0
|
|
31
|
+
### features
|
|
32
|
+
|
|
33
|
+
- BREAKING: Complete async rewrite with async gem
|
|
34
|
+
- New HTTP client using HTTPX with proper async/await pattern
|
|
35
|
+
- Added scene system for multi-step conversations
|
|
36
|
+
- Middleware composer system for plugin architecture
|
|
37
|
+
- Type system with dynamic accessors for Telegram objects
|
|
38
|
+
- Session management with memory store
|
|
39
|
+
- Rate limiting middleware
|
|
40
|
+
- File upload support via multipart forms
|
|
41
|
+
|
|
42
|
+
## v2.0.0
|
|
43
|
+
|
|
44
|
+
- BREAKING: Ruby 3.0+ requirement
|
|
45
|
+
- Added webhook support with Rack middleware
|
|
46
|
+
- Inline query and callback query handlers
|
|
47
|
+
- Location, contact, and poll answer handlers
|
|
48
|
+
- Keyboard markup helpers (Telegem::Markup)
|
|
49
|
+
- Improved error handling with custom error classes
|
|
50
|
+
- Logging integration with configurable loggers
|
|
51
|
+
|
|
52
|
+
## v1.5.0
|
|
53
|
+
|
|
54
|
+
- Added command argument parsing (ctx.command_args)
|
|
55
|
+
- Message entity parsing (mentions, hashtags, bot commands)
|
|
56
|
+
- Chat member update handlers
|
|
57
|
+
- Pre-checkout and shipping query support
|
|
58
|
+
- File download helper methods
|
|
59
|
+
- Context helper methods for common API calls
|
|
60
|
+
|
|
61
|
+
## v1.0.0
|
|
62
|
+
|
|
63
|
+
- Stable API release
|
|
64
|
+
- Message handlers with text pattern matching
|
|
65
|
+
- Command handlers with regex support
|
|
66
|
+
- Basic context object with chat/message accessors
|
|
67
|
+
- Simple API client with error handling
|
|
68
|
+
- Polling and webhook modes
|
|
69
|
+
- Configuration options for timeout and limits
|
|
70
|
+
|
|
71
|
+
## v0.5.0
|
|
72
|
+
|
|
73
|
+
- Added callback query support
|
|
74
|
+
- Inline keyboard builder
|
|
75
|
+
- Message editing and deletion helpers
|
|
76
|
+
- Media sending methods (photo, document, audio, video)
|
|
77
|
+
- Chat action methods (typing, upload indicators)
|
|
78
|
+
|
|
79
|
+
## v0.3.0
|
|
80
|
+
|
|
81
|
+
- Middleware system with bot.use
|
|
82
|
+
- Session management foundation
|
|
83
|
+
- Basic rate limiting
|
|
84
|
+
- Command filtering by chat type
|
|
85
|
+
- Improved logging with debug levels
|
|
86
|
+
|
|
87
|
+
## v0.2.0
|
|
88
|
+
|
|
89
|
+
- Basic polling implementation
|
|
90
|
+
- Message type detection (text, photo, document)
|
|
91
|
+
- Command parsing with arguments
|
|
92
|
+
- Simple reply methods
|
|
93
|
+
- Error handling for API calls
|
|
94
|
+
|
|
95
|
+
## v0.1.0 (Initial Release)
|
|
96
|
+
|
|
97
|
+
- Basic Telegram Bot API wrapper
|
|
98
|
+
- Send/receive messages
|
|
99
|
+
- Simple command handling
|
|
100
|
+
- Minimal dependencies (just httparty)
|
|
101
|
+
- Support for basic message types
|
|
102
|
+
|
|
103
|
+
---
|
data/Gemfile
CHANGED
data/Readme.md
CHANGED
|
@@ -4,10 +4,6 @@ Modern, blazing-fast async Telegram Bot API for Ruby - Inspired by Telegraf, bui
|
|
|
4
4
|
|
|
5
5
|
    
|
|
6
6
|
|
|
7
|
-

|
|
8
|
-

|
|
9
|
-

|
|
10
|
-

|
|
11
7
|
|
|
12
8
|
|
|
13
9
|
|
|
@@ -108,7 +104,7 @@ Perfect For:
|
|
|
108
104
|
|
|
109
105
|
---
|
|
110
106
|
|
|
111
|
-
[📚 Documentation](https://rubydoc.info/gems/telegem/3.2.
|
|
107
|
+
[📚 Documentation](https://rubydoc.info/gems/telegem/3.2.3/index)
|
|
112
108
|
|
|
113
109
|
|
|
114
110
|
|
|
@@ -299,4 +295,4 @@ ruby -r telegem -e "puts 'Welcome to Telegem! 🚀'"
|
|
|
299
295
|
|
|
300
296
|
---
|
|
301
297
|
|
|
302
|
-
Built with ❤️ for the Ruby community. Happy bot building! 🤖✨
|
|
298
|
+
Built with ❤️ for the Ruby community. Happy bot building! 🤖✨
|
data/bin/telegem-init
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# bin/telegem-init
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
puts " Creating a telegem application..."
|
|
7
|
+
|
|
8
|
+
# Create the nested directory structure
|
|
9
|
+
FileUtils.mkdir_p("src/handlers")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
code = <<~RUBY
|
|
13
|
+
require 'telegem'
|
|
14
|
+
require 'dotenv/load'
|
|
15
|
+
|
|
16
|
+
# Load all handlers from the handlers directory relative to this file
|
|
17
|
+
Dir[File.join(__dir__, 'handlers', '*.rb')].each { |file| require file }
|
|
18
|
+
|
|
19
|
+
bot = Telegem.new(ENV['BOT_TOKEN'])
|
|
20
|
+
|
|
21
|
+
puts "Bot is starting..."
|
|
22
|
+
bot.start_polling
|
|
23
|
+
RUBY
|
|
24
|
+
|
|
25
|
+
File.write('src/bot.rb', code)
|
|
26
|
+
|
|
27
|
+
# Optional: Create a blank .env file so the bot doesn't crash on load
|
|
28
|
+
File.write('.env', "BOT_TOKEN=your_token_here") unless File.exist?('.env')
|
|
29
|
+
|
|
30
|
+
puts "Successfully created src/bot.rb"
|
|
31
|
+
puts " Structure created: src/handlers/"
|
|
32
|
+
puts " Done working. Run your bot with: ruby src/bot.rb"
|
data/bin/telegem-ssl
CHANGED
|
@@ -2,10 +2,17 @@
|
|
|
2
2
|
# bin/telegem-ssl
|
|
3
3
|
|
|
4
4
|
require 'fileutils'
|
|
5
|
+
require 'yaml'
|
|
5
6
|
|
|
6
7
|
puts "🔐 Telegem SSL Setup"
|
|
7
8
|
puts "=" * 10
|
|
8
9
|
|
|
10
|
+
if File.exist?('.telegem-ssl')
|
|
11
|
+
puts "🚫 SSL config already exists at .telegem-ssl"
|
|
12
|
+
print "Overwrite? (y/n): "
|
|
13
|
+
exit unless gets.chomp.downcase == 'y'
|
|
14
|
+
end
|
|
15
|
+
|
|
9
16
|
# Get domain
|
|
10
17
|
domain = ARGV[0]
|
|
11
18
|
unless domain
|
data/lib/api/client.rb
CHANGED
|
@@ -18,26 +18,19 @@ module Telegem
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def call(method, params = {})
|
|
21
|
-
Async do
|
|
22
21
|
make_request(method, params)
|
|
23
|
-
end.wait
|
|
24
22
|
end
|
|
25
23
|
|
|
26
24
|
def call!(method, params = {}, &callback)
|
|
27
25
|
return unless callback
|
|
28
|
-
|
|
29
|
-
Async do
|
|
30
26
|
begin
|
|
31
27
|
result = make_request(method, params)
|
|
32
28
|
callback.call(result, nil)
|
|
33
29
|
rescue => error
|
|
34
30
|
callback.call(nil, error)
|
|
35
31
|
end
|
|
36
|
-
end
|
|
37
32
|
end
|
|
38
|
-
|
|
39
33
|
def upload(method, params)
|
|
40
|
-
Async do
|
|
41
34
|
url = "/bot#{@token}/#{method}"
|
|
42
35
|
|
|
43
36
|
body = Async::HTTP::Body::Multipart.new
|
|
@@ -52,11 +45,10 @@ module Telegem
|
|
|
52
45
|
|
|
53
46
|
response = @client.post(url, {}, body)
|
|
54
47
|
handle_response(response)
|
|
55
|
-
|
|
48
|
+
|
|
56
49
|
end
|
|
57
50
|
|
|
58
51
|
def download(file_id, destination_path = nil)
|
|
59
|
-
Async do
|
|
60
52
|
file_info = call('getFile', file_id: file_id)
|
|
61
53
|
return nil unless file_info && file_info['file_path']
|
|
62
54
|
|
|
@@ -76,7 +68,6 @@ module Telegem
|
|
|
76
68
|
else
|
|
77
69
|
raise NetworkError.new("Download failed: HTTP #{response.status}")
|
|
78
70
|
end
|
|
79
|
-
end.wait
|
|
80
71
|
end
|
|
81
72
|
|
|
82
73
|
def get_updates(offset: nil, timeout: 30, limit: 100, allowed_updates: nil)
|
data/lib/api/types.rb
CHANGED
|
@@ -62,6 +62,21 @@ module Telegem
|
|
|
62
62
|
@_accessors_defined[name] = true
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
# helpers for converting nested objects
|
|
66
|
+
def wrap(key, klass)
|
|
67
|
+
if @_raw_data[key] && !@_raw_data[key].is_a?(klass)
|
|
68
|
+
@_raw_data[key] = klass.new(@_raw_data[key])
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def wrap_array(key, klass)
|
|
73
|
+
if @_raw_data[key] && @_raw_data[key].is_a?(Array)
|
|
74
|
+
@_raw_data[key] = @_raw_data[key].map do |v|
|
|
75
|
+
v.is_a?(klass) ? v : klass.new(v)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
65
80
|
def snake_to_camel(str)
|
|
66
81
|
str.gsub(/_([a-z])/) { $1.upcase }
|
|
67
82
|
end
|
|
@@ -250,48 +265,104 @@ module Telegem
|
|
|
250
265
|
private
|
|
251
266
|
|
|
252
267
|
def convert_complex_fields
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
268
|
+
# time conversions
|
|
269
|
+
@_raw_data['date'] = Time.at(@_raw_data['date']) if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
|
|
270
|
+
@_raw_data['edit_date'] = Time.at(@_raw_data['edit_date']) if @_raw_data['edit_date'] && !@_raw_data['edit_date'].is_a?(Time)
|
|
271
|
+
@_raw_data['forward_date'] = Time.at(@_raw_data['forward_date']) if @_raw_data['forward_date'] && !@_raw_data['forward_date'].is_a?(Time)
|
|
272
|
+
|
|
273
|
+
# basic object wrappers
|
|
274
|
+
wrap('from', User)
|
|
275
|
+
wrap('chat', Chat)
|
|
276
|
+
wrap('via_bot', User)
|
|
277
|
+
wrap('forward_from', User)
|
|
278
|
+
wrap('forward_from_chat', Chat)
|
|
279
|
+
wrap('left_chat_member', User)
|
|
280
|
+
|
|
281
|
+
wrap_array('entities', MessageEntity)
|
|
282
|
+
wrap_array('caption_entities', MessageEntity)
|
|
283
|
+
|
|
284
|
+
wrap('reply_to_message', Message)
|
|
285
|
+
wrap('pinned_message', Message)
|
|
286
|
+
wrap_array('new_chat_members', User)
|
|
287
|
+
|
|
288
|
+
# media and other nested types
|
|
289
|
+
wrap('contact', Contact)
|
|
290
|
+
wrap('location', Location)
|
|
291
|
+
wrap('venue', Venue)
|
|
292
|
+
wrap('dice', Dice)
|
|
293
|
+
wrap('poll', Poll)
|
|
294
|
+
wrap('proximity_alert_triggered', ProximityAlertTriggered)
|
|
295
|
+
wrap('web_app_data', WebAppData)
|
|
296
|
+
|
|
297
|
+
wrap('animation', Animation)
|
|
298
|
+
wrap('audio', Audio)
|
|
299
|
+
wrap('document', Document)
|
|
300
|
+
wrap('video', Video)
|
|
301
|
+
wrap('voice', Voice)
|
|
302
|
+
wrap('video_note', VideoNote)
|
|
303
|
+
wrap('sticker', Sticker)
|
|
304
|
+
|
|
305
|
+
wrap('invoice', Invoice)
|
|
306
|
+
wrap('successful_payment', SuccessfulPayment)
|
|
307
|
+
wrap('reply_markup', BaseType)
|
|
308
|
+
|
|
309
|
+
wrap('passport_data', PassportData)
|
|
310
|
+
|
|
311
|
+
wrap('video_chat_scheduled', VideoChatScheduled)
|
|
312
|
+
wrap('video_chat_started', VideoChatStarted)
|
|
313
|
+
wrap('video_chat_ended', VideoChatEnded)
|
|
314
|
+
wrap('video_chat_participants_invited', VideoChatParticipantsInvited)
|
|
315
|
+
wrap('video_chat_location', VideoChatLocation)
|
|
316
|
+
|
|
317
|
+
# new message event objects introduced in later API versions
|
|
318
|
+
wrap('message_auto_delete_timer_changed', MessageAutoDeleteTimerChanged)
|
|
319
|
+
wrap('forum_topic_created', ForumTopicCreated)
|
|
320
|
+
wrap('forum_topic_edited', ForumTopicEdited)
|
|
321
|
+
wrap('forum_topic_closed', ForumTopicClosed)
|
|
322
|
+
wrap('forum_topic_reopened', ForumTopicReopened)
|
|
323
|
+
wrap('general_forum_topic_hidden', GeneralForumTopicHidden)
|
|
324
|
+
wrap('general_forum_topic_unhidden', GeneralForumTopicUnhidden)
|
|
325
|
+
wrap('write_access_allowed', WriteAccessAllowed)
|
|
326
|
+
|
|
327
|
+
# arrays of sizes and photos
|
|
328
|
+
wrap_array('photo', PhotoSize)
|
|
329
|
+
wrap_array('new_chat_photo', PhotoSize)
|
|
330
|
+
|
|
331
|
+
# fall back to original media wrapper for backward compatibility
|
|
332
|
+
wrap_media_objects
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def wrap_media_objects
|
|
336
|
+
# Media files (fall‑back to generic types if no specific class defined)
|
|
337
|
+
@_raw_data['document'] = Document.new(@_raw_data['document']) if @_raw_data['document'] && !@_raw_data['document'].is_a?(Document)
|
|
338
|
+
@_raw_data['animation'] = Animation.new(@_raw_data['animation']) if @_raw_data['animation'] && !@_raw_data['animation'].is_a?(Animation)
|
|
339
|
+
@_raw_data['audio'] = Audio.new(@_raw_data['audio']) if @_raw_data['audio'] && !@_raw_data['audio'].is_a?(Audio)
|
|
340
|
+
@_raw_data['video'] = Video.new(@_raw_data['video']) if @_raw_data['video'] && !@_raw_data['video'].is_a?(Video)
|
|
341
|
+
@_raw_data['voice'] = Voice.new(@_raw_data['voice']) if @_raw_data['voice'] && !@_raw_data['voice'].is_a?(Voice)
|
|
342
|
+
@_raw_data['video_note'] = VideoNote.new(@_raw_data['video_note']) if @_raw_data['video_note'] && !@_raw_data['video_note'].is_a?(VideoNote)
|
|
343
|
+
@_raw_data['sticker'] = Sticker.new(@_raw_data['sticker']) if @_raw_data['sticker'] && !@_raw_data['sticker'].is_a?(Sticker)
|
|
344
|
+
|
|
345
|
+
# Photo array
|
|
346
|
+
if @_raw_data['photo'] && @_raw_data['photo'].is_a?(Array)
|
|
347
|
+
@_raw_data['photo'] = @_raw_data['photo'].map do |p|
|
|
348
|
+
p.is_a?(PhotoSize) ? p : PhotoSize.new(p)
|
|
281
349
|
end
|
|
282
350
|
end
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if @_raw_data['
|
|
293
|
-
|
|
294
|
-
|
|
351
|
+
|
|
352
|
+
# Contact, location, venue
|
|
353
|
+
@_raw_data['contact'] = Contact.new(@_raw_data['contact']) if @_raw_data['contact'] && !@_raw_data['contact'].is_a?(Contact)
|
|
354
|
+
@_raw_data['location'] = Location.new(@_raw_data['location']) if @_raw_data['location'] && !@_raw_data['location'].is_a?(Location)
|
|
355
|
+
@_raw_data['venue'] = Venue.new(@_raw_data['venue']) if @_raw_data['venue'] && !@_raw_data['venue'].is_a?(Venue)
|
|
356
|
+
|
|
357
|
+
# Payment & other
|
|
358
|
+
@_raw_data['invoice'] = Invoice.new(@_raw_data['invoice']) if @_raw_data['invoice'] && !@_raw_data['invoice'].is_a?(Invoice)
|
|
359
|
+
@_raw_data['successful_payment'] = SuccessfulPayment.new(@_raw_data['successful_payment']) if @_raw_data['successful_payment'] && !@_raw_data['successful_payment'].is_a?(SuccessfulPayment)
|
|
360
|
+
@_raw_data['reply_markup'] = BaseType.new(@_raw_data['reply_markup']) if @_raw_data['reply_markup'] && !@_raw_data['reply_markup'].is_a?(BaseType)
|
|
361
|
+
|
|
362
|
+
# Chat photo array
|
|
363
|
+
if @_raw_data['new_chat_photo'] && @_raw_data['new_chat_photo'].is_a?(Array)
|
|
364
|
+
@_raw_data['new_chat_photo'] = @_raw_data['new_chat_photo'].map do |p|
|
|
365
|
+
p.is_a?(PhotoSize) ? p : PhotoSize.new(p)
|
|
295
366
|
end
|
|
296
367
|
end
|
|
297
368
|
end
|
|
@@ -392,15 +463,218 @@ module Telegem
|
|
|
392
463
|
private
|
|
393
464
|
|
|
394
465
|
def convert_update_objects
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
466
|
+
wrap('message', Message)
|
|
467
|
+
wrap('edited_message', Message)
|
|
468
|
+
wrap('channel_post', Message)
|
|
469
|
+
wrap('edited_channel_post', Message)
|
|
470
|
+
|
|
471
|
+
wrap('inline_query', InlineQuery)
|
|
472
|
+
wrap('chosen_inline_result', ChosenInlineResult)
|
|
473
|
+
wrap('callback_query', CallbackQuery)
|
|
474
|
+
wrap('shipping_query', ShippingQuery)
|
|
475
|
+
wrap('pre_checkout_query', PreCheckoutQuery)
|
|
476
|
+
wrap('poll', Poll)
|
|
477
|
+
wrap('poll_answer', PollAnswer)
|
|
478
|
+
wrap('my_chat_member', ChatMemberUpdated)
|
|
479
|
+
wrap('chat_member', ChatMemberUpdated)
|
|
480
|
+
wrap('chat_join_request', ChatJoinRequest)
|
|
481
|
+
wrap('forum_topic_created', ForumTopicCreated)
|
|
482
|
+
wrap('forum_topic_edited', ForumTopicEdited)
|
|
483
|
+
wrap('forum_topic_closed', ForumTopicClosed)
|
|
484
|
+
wrap('forum_topic_reopened', ForumTopicReopened)
|
|
485
|
+
wrap('general_forum_topic_hidden', GeneralForumTopicHidden)
|
|
486
|
+
wrap('general_forum_topic_unhidden', GeneralForumTopicUnhidden)
|
|
487
|
+
wrap('write_access_allowed', WriteAccessAllowed)
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
# additional types returned by various methods / updates
|
|
492
|
+
class PhotoSize < BaseType; end
|
|
493
|
+
class Audio < BaseType; end
|
|
494
|
+
class Document < BaseType; end
|
|
495
|
+
class Video < BaseType; end
|
|
496
|
+
class Voice < BaseType; end
|
|
497
|
+
class VideoNote < BaseType; end
|
|
498
|
+
class Animation < BaseType; end
|
|
499
|
+
class Sticker < BaseType; end
|
|
500
|
+
class Contact < BaseType; end
|
|
501
|
+
class Dice < BaseType; end
|
|
502
|
+
|
|
503
|
+
class Location < BaseType; end
|
|
504
|
+
class Venue < BaseType; end
|
|
505
|
+
class ProximityAlertTriggered < BaseType; end
|
|
506
|
+
class WebAppData < BaseType; end
|
|
507
|
+
class PassportData < BaseType; end
|
|
508
|
+
|
|
509
|
+
class Invoice < BaseType; end
|
|
510
|
+
class SuccessfulPayment < BaseType; end
|
|
511
|
+
class ShippingAddress < BaseType; end
|
|
512
|
+
class OrderInfo < BaseType; end
|
|
513
|
+
|
|
514
|
+
class ShippingQuery < BaseType
|
|
515
|
+
def initialize(data)
|
|
516
|
+
super(data)
|
|
517
|
+
wrap('from', User)
|
|
518
|
+
wrap('shipping_address', ShippingAddress)
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
class PreCheckoutQuery < BaseType
|
|
523
|
+
def initialize(data)
|
|
524
|
+
super(data)
|
|
525
|
+
wrap('from', User)
|
|
526
|
+
wrap('shipping_address', ShippingAddress)
|
|
527
|
+
wrap('order_info', OrderInfo)
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
class PollOption < BaseType; end
|
|
532
|
+
class PollAnswer < BaseType; end
|
|
533
|
+
|
|
534
|
+
class Poll < BaseType
|
|
535
|
+
def initialize(data)
|
|
536
|
+
super(data)
|
|
537
|
+
wrap_array('options', PollOption)
|
|
538
|
+
wrap_array('explanation_entities', MessageEntity)
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
class ChatPermissions < BaseType; end
|
|
543
|
+
class ChatPhoto < BaseType; end
|
|
544
|
+
class ChatInviteLink < BaseType; end
|
|
545
|
+
|
|
546
|
+
# status-specific chat member objects. they inherit from ChatMember
|
|
547
|
+
class ChatMember < BaseType; end
|
|
548
|
+
class ChatMemberOwner < ChatMember; end
|
|
549
|
+
class ChatMemberAdministrator < ChatMember; end
|
|
550
|
+
class ChatMemberMember < ChatMember; end
|
|
551
|
+
class ChatMemberRestricted < ChatMember; end
|
|
552
|
+
class ChatMemberLeft < ChatMember; end
|
|
553
|
+
class ChatMemberBanned < ChatMember; end
|
|
554
|
+
|
|
555
|
+
class ChatAdministratorRights < BaseType; end
|
|
556
|
+
|
|
557
|
+
class ChatMemberUpdated < BaseType
|
|
558
|
+
def initialize(data)
|
|
559
|
+
super(data)
|
|
560
|
+
wrap('chat', Chat)
|
|
561
|
+
wrap('from', User)
|
|
562
|
+
wrap_member('old_chat_member')
|
|
563
|
+
wrap_member('new_chat_member')
|
|
564
|
+
wrap('invite_link', ChatInviteLink)
|
|
565
|
+
if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
|
|
566
|
+
@_raw_data['date'] = Time.at(@_raw_data['date'])
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
private
|
|
571
|
+
|
|
572
|
+
def wrap_member(key)
|
|
573
|
+
return unless @_raw_data[key]
|
|
574
|
+
status = @_raw_data[key]['status']
|
|
575
|
+
klass = case status
|
|
576
|
+
when 'creator' then ChatMemberOwner
|
|
577
|
+
when 'administrator' then ChatMemberAdministrator
|
|
578
|
+
when 'member' then ChatMemberMember
|
|
579
|
+
when 'restricted' then ChatMemberRestricted
|
|
580
|
+
when 'left' then ChatMemberLeft
|
|
581
|
+
when 'kicked' then ChatMemberBanned
|
|
582
|
+
else ChatMember
|
|
583
|
+
end
|
|
584
|
+
@_raw_data[key] = klass.new(@_raw_data[key])
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
class ChatJoinRequest < BaseType
|
|
589
|
+
def initialize(data)
|
|
590
|
+
super(data)
|
|
591
|
+
wrap('chat', Chat)
|
|
592
|
+
wrap('from', User)
|
|
593
|
+
wrap('invite_link', ChatInviteLink)
|
|
594
|
+
if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
|
|
595
|
+
@_raw_data['date'] = Time.at(@_raw_data['date'])
|
|
402
596
|
end
|
|
403
597
|
end
|
|
404
598
|
end
|
|
599
|
+
|
|
600
|
+
class InlineQuery < BaseType
|
|
601
|
+
def initialize(data)
|
|
602
|
+
super(data)
|
|
603
|
+
wrap('from', User)
|
|
604
|
+
wrap('location', Location)
|
|
605
|
+
end
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
class ChosenInlineResult < BaseType
|
|
609
|
+
def initialize(data)
|
|
610
|
+
super(data)
|
|
611
|
+
wrap('from', User)
|
|
612
|
+
wrap('location', Location)
|
|
613
|
+
end
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
class InlineQueryResult < BaseType; end
|
|
617
|
+
class InlineQueryResultArticle < InlineQueryResult; end
|
|
618
|
+
class InlineQueryResultPhoto < InlineQueryResult; end
|
|
619
|
+
class InlineQueryResultGif < InlineQueryResult; end
|
|
620
|
+
class InlineQueryResultMpeg4Gif < InlineQueryResult; end
|
|
621
|
+
class InlineQueryResultVideo < InlineQueryResult; end
|
|
622
|
+
class InlineQueryResultAudio < InlineQueryResult; end
|
|
623
|
+
class InlineQueryResultVoice < InlineQueryResult; end
|
|
624
|
+
class InlineQueryResultDocument < InlineQueryResult; end
|
|
625
|
+
class InlineQueryResultLocation < InlineQueryResult; end
|
|
626
|
+
class InlineQueryResultVenue < InlineQueryResult; end
|
|
627
|
+
class InlineQueryResultContact < InlineQueryResult; end
|
|
628
|
+
class InlineQueryResultGame < InlineQueryResult; end
|
|
629
|
+
class InlineQueryResultSticker < InlineQueryResult; end
|
|
630
|
+
class InlineQueryResultCachedPhoto < InlineQueryResult; end
|
|
631
|
+
class InlineQueryResultCachedGif < InlineQueryResult; end
|
|
632
|
+
class InlineQueryResultCachedMpeg4Gif < InlineQueryResult; end
|
|
633
|
+
class InlineQueryResultCachedSticker < InlineQueryResult; end
|
|
634
|
+
class InlineQueryResultCachedDocument < InlineQueryResult; end
|
|
635
|
+
class InlineQueryResultCachedVideo < InlineQueryResult; end
|
|
636
|
+
class InlineQueryResultCachedAudio < InlineQueryResult; end
|
|
637
|
+
class InlineQueryResultCachedVoice < InlineQueryResult; end
|
|
638
|
+
|
|
639
|
+
class UserProfilePhotos < BaseType
|
|
640
|
+
def initialize(data)
|
|
641
|
+
super(data)
|
|
642
|
+
wrap_array('photos', PhotoSize)
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
class UserProfileAudios < BaseType
|
|
647
|
+
def initialize(data)
|
|
648
|
+
super(data)
|
|
649
|
+
wrap_array('audios', Audio)
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
# generic utility objects returned by the API
|
|
654
|
+
class File < BaseType; end
|
|
655
|
+
class ResponseParameters < BaseType; end
|
|
656
|
+
class MaskPosition < BaseType; end
|
|
657
|
+
class StickerSet < BaseType; end
|
|
658
|
+
|
|
659
|
+
# new message event payloads (each a simple wrapper)
|
|
660
|
+
class MessageAutoDeleteTimerChanged < BaseType; end
|
|
661
|
+
class ForumTopicCreated < BaseType; end
|
|
662
|
+
class ForumTopicEdited < BaseType; end
|
|
663
|
+
class ForumTopicClosed < BaseType; end
|
|
664
|
+
class ForumTopicReopened < BaseType; end
|
|
665
|
+
class GeneralForumTopicHidden < BaseType; end
|
|
666
|
+
class GeneralForumTopicUnhidden < BaseType; end
|
|
667
|
+
class WriteAccessAllowed < BaseType; end
|
|
668
|
+
|
|
669
|
+
class BotCommand < BaseType; end
|
|
670
|
+
class BotCommandScope < BaseType; end
|
|
671
|
+
class WebhookInfo < BaseType; end
|
|
672
|
+
|
|
673
|
+
class VideoChatScheduled < BaseType; end
|
|
674
|
+
class VideoChatStarted < BaseType; end
|
|
675
|
+
class VideoChatEnded < BaseType; end
|
|
676
|
+
class VideoChatParticipantsInvited < BaseType; end
|
|
677
|
+
class VideoChatLocation < BaseType; end
|
|
678
|
+
|
|
405
679
|
end
|
|
406
680
|
end
|