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.
- checksums.yaml +4 -4
- data/.rubocop.yml +57 -0
- data/CHANGELOG.md +121 -0
- data/Gemfile +1 -1
- data/README.md +147 -0
- data/bin/telegem-ssl +71 -25
- data/contributing.md +375 -0
- data/docs/api.md +663 -0
- data/docs/bot.md +332 -0
- data/docs/changelog.md +182 -0
- data/docs/context.md +554 -0
- data/docs/core_concepts.md +218 -0
- data/docs/deployment.md +702 -0
- data/docs/error_handling.md +435 -0
- data/docs/examples.md +752 -0
- data/docs/getting_started.md +151 -0
- data/docs/handlers.md +580 -0
- data/docs/keyboards.md +446 -0
- data/docs/middleware.md +536 -0
- data/docs/plugins.md +384 -0
- data/docs/scenes.md +517 -0
- data/docs/sessions.md +544 -0
- data/docs/testing.md +612 -0
- data/docs/troubleshooting.md +574 -0
- data/docs/types.md +538 -0
- data/docs/webhooks.md +456 -0
- data/lib/api/client.rb +38 -10
- data/lib/api/types.rb +433 -172
- data/lib/core/composer.rb +3 -3
- data/lib/core/context.rb +17 -11
- data/lib/plugins/cc +3 -0
- data/lib/plugins/file_extract.rb +2 -2
- data/lib/plugins/translate.rb +43 -0
- data/lib/session/memory_store.rb +90 -103
- data/lib/session/redis.rb +91 -0
- data/lib/telegem.rb +4 -4
- data/lib/webhook/server.rb +5 -3
- metadata +51 -35
- data/CHANGELOG +0 -95
- data/Contributing.md +0 -161
- data/Readme.md +0 -302
- data/examples/.gitkeep +0 -0
- data/public/.gitkeep +0 -0
data/docs/types.md
ADDED
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
# Type System
|
|
2
|
+
|
|
3
|
+
Telegem provides Ruby classes for all Telegram API objects, offering type safety and convenient access methods.
|
|
4
|
+
|
|
5
|
+
## Base Type Class
|
|
6
|
+
|
|
7
|
+
All Telegram types inherit from `Telegem::Types::BaseType`.
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- **Dynamic accessors**: Access any field as a method
|
|
12
|
+
- **Snake_case conversion**: API fields become Ruby methods
|
|
13
|
+
- **Type conversion**: Automatic conversion of nested objects
|
|
14
|
+
- **JSON serialization**: Convert to hash or JSON
|
|
15
|
+
|
|
16
|
+
### Usage
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
# Access fields dynamically
|
|
20
|
+
user = Telegem::Types::User.new(api_response)
|
|
21
|
+
puts user.first_name
|
|
22
|
+
puts user.username
|
|
23
|
+
|
|
24
|
+
# Convert back to hash
|
|
25
|
+
user_hash = user.to_h
|
|
26
|
+
|
|
27
|
+
# Serialize to JSON
|
|
28
|
+
user_json = user.to_json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Available Types
|
|
32
|
+
|
|
33
|
+
### User
|
|
34
|
+
|
|
35
|
+
Represents a Telegram user.
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
user = Telegem::Types::User.new(data)
|
|
39
|
+
|
|
40
|
+
# Basic info
|
|
41
|
+
user.id # Integer
|
|
42
|
+
user.first_name # String
|
|
43
|
+
user.last_name # String (optional)
|
|
44
|
+
user.username # String (optional)
|
|
45
|
+
user.language_code # String (optional)
|
|
46
|
+
|
|
47
|
+
# Status
|
|
48
|
+
user.is_bot # Boolean
|
|
49
|
+
user.is_premium # Boolean (optional)
|
|
50
|
+
user.added_to_attachment_menu # Boolean (optional)
|
|
51
|
+
|
|
52
|
+
# Methods
|
|
53
|
+
user.full_name # "First Last"
|
|
54
|
+
user.mention # "@username" or "First"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Chat
|
|
58
|
+
|
|
59
|
+
Represents a chat (private, group, supergroup, channel).
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
chat = Telegem::Types::Chat.new(data)
|
|
63
|
+
|
|
64
|
+
# Basic info
|
|
65
|
+
chat.id # Integer
|
|
66
|
+
chat.type # "private", "group", "supergroup", "channel"
|
|
67
|
+
chat.title # String (for groups/channels)
|
|
68
|
+
chat.username # String (for public chats)
|
|
69
|
+
chat.first_name # String (for private chats)
|
|
70
|
+
chat.last_name # String (for private chats)
|
|
71
|
+
|
|
72
|
+
# Features
|
|
73
|
+
chat.description # String (optional)
|
|
74
|
+
chat.invite_link # String (optional)
|
|
75
|
+
chat.photo # ChatPhoto object (optional)
|
|
76
|
+
|
|
77
|
+
# Permissions
|
|
78
|
+
chat.permissions # ChatPermissions object
|
|
79
|
+
|
|
80
|
+
# Type checking
|
|
81
|
+
chat.private? # chat.type == 'private'
|
|
82
|
+
chat.group? # chat.type == 'group'
|
|
83
|
+
chat.supergroup? # chat.type == 'supergroup'
|
|
84
|
+
chat.channel? # chat.type == 'channel'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Message
|
|
88
|
+
|
|
89
|
+
Represents a message in a chat.
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
message = Telegem::Types::Message.new(data)
|
|
93
|
+
|
|
94
|
+
# Basic info
|
|
95
|
+
message.message_id # Integer
|
|
96
|
+
message.date # Time object
|
|
97
|
+
message.edit_date # Time object (if edited)
|
|
98
|
+
message.text # String (optional)
|
|
99
|
+
message.caption # String (optional)
|
|
100
|
+
|
|
101
|
+
# Entities
|
|
102
|
+
message.entities # Array of MessageEntity
|
|
103
|
+
message.caption_entities # Array of MessageEntity
|
|
104
|
+
|
|
105
|
+
# Sender and chat
|
|
106
|
+
message.from # User object
|
|
107
|
+
message.chat # Chat object
|
|
108
|
+
|
|
109
|
+
# Reply info
|
|
110
|
+
message.reply_to_message # Message object (optional)
|
|
111
|
+
|
|
112
|
+
# Media
|
|
113
|
+
message.photo # Array of PhotoSize (optional)
|
|
114
|
+
message.document # Document object (optional)
|
|
115
|
+
message.audio # Audio object (optional)
|
|
116
|
+
message.video # Video object (optional)
|
|
117
|
+
message.voice # Voice object (optional)
|
|
118
|
+
message.sticker # Sticker object (optional)
|
|
119
|
+
|
|
120
|
+
# Methods
|
|
121
|
+
message.command? # Boolean: is command?
|
|
122
|
+
message.command_name # String: command name
|
|
123
|
+
message.command_args # String: command arguments
|
|
124
|
+
message.reply? # Boolean: is reply?
|
|
125
|
+
message.has_media? # Boolean: has media?
|
|
126
|
+
message.media_type # Symbol: :photo, :document, etc.
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### MessageEntity
|
|
130
|
+
|
|
131
|
+
Represents formatted text in messages.
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
entity = Telegem::Types::MessageEntity.new(data)
|
|
135
|
+
|
|
136
|
+
entity.type # "bold", "italic", "code", etc.
|
|
137
|
+
entity.offset # Integer: start position
|
|
138
|
+
entity.length # Integer: length
|
|
139
|
+
entity.url # String (for links)
|
|
140
|
+
entity.user # User object (for mentions)
|
|
141
|
+
entity.language # String (for code blocks)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Update
|
|
145
|
+
|
|
146
|
+
Represents an update from Telegram.
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
update = Telegem::Types::Update.new(data)
|
|
150
|
+
|
|
151
|
+
update.update_id # Integer
|
|
152
|
+
|
|
153
|
+
# Update types (only one will be present)
|
|
154
|
+
update.message # Message object
|
|
155
|
+
update.edited_message # Message object
|
|
156
|
+
update.channel_post # Message object
|
|
157
|
+
update.edited_channel_post # Message object
|
|
158
|
+
update.inline_query # InlineQuery object
|
|
159
|
+
update.chosen_inline_result # ChosenInlineResult object
|
|
160
|
+
update.callback_query # CallbackQuery object
|
|
161
|
+
update.shipping_query # ShippingQuery object
|
|
162
|
+
update.pre_checkout_query # PreCheckoutQuery object
|
|
163
|
+
update.poll # Poll object
|
|
164
|
+
update.poll_answer # PollAnswer object
|
|
165
|
+
|
|
166
|
+
# Type detection
|
|
167
|
+
update.type # :message, :callback_query, etc.
|
|
168
|
+
update.from # User object (sender)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### CallbackQuery
|
|
172
|
+
|
|
173
|
+
Represents a callback query from inline keyboard.
|
|
174
|
+
|
|
175
|
+
```ruby
|
|
176
|
+
query = Telegem::Types::CallbackQuery.new(data)
|
|
177
|
+
|
|
178
|
+
query.id # String
|
|
179
|
+
query.from # User object
|
|
180
|
+
query.message # Message object (optional)
|
|
181
|
+
query.inline_message_id # String (optional)
|
|
182
|
+
query.chat_instance # String
|
|
183
|
+
query.data # String (callback data)
|
|
184
|
+
|
|
185
|
+
# Type checking
|
|
186
|
+
query.from_user? # query.from.present?
|
|
187
|
+
query.message? # query.message.present?
|
|
188
|
+
query.inline_message? # query.inline_message_id.present?
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### InlineQuery
|
|
192
|
+
|
|
193
|
+
Represents an inline query.
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
query = Telegem::Types::InlineQuery.new(data)
|
|
197
|
+
|
|
198
|
+
query.id # String
|
|
199
|
+
query.from # User object
|
|
200
|
+
query.query # String (search query)
|
|
201
|
+
query.offset # String (pagination offset)
|
|
202
|
+
query.chat_type # String (optional)
|
|
203
|
+
query.location # Location object (optional)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Poll
|
|
207
|
+
|
|
208
|
+
Represents a poll.
|
|
209
|
+
|
|
210
|
+
```ruby
|
|
211
|
+
poll = Telegem::Types::Poll.new(data)
|
|
212
|
+
|
|
213
|
+
poll.id # String
|
|
214
|
+
poll.question # String
|
|
215
|
+
poll.options # Array of PollOption
|
|
216
|
+
poll.total_voter_count # Integer
|
|
217
|
+
poll.is_closed # Boolean
|
|
218
|
+
poll.is_anonymous # Boolean
|
|
219
|
+
poll.allows_multiple_answers # Boolean
|
|
220
|
+
poll.correct_option_id # Integer (optional)
|
|
221
|
+
poll.explanation # String (optional)
|
|
222
|
+
poll.explanation_entities # Array of MessageEntity (optional)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### ChatMember
|
|
226
|
+
|
|
227
|
+
Represents a chat member.
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
member = Telegem::Types::ChatMember.new(data)
|
|
231
|
+
|
|
232
|
+
member.user # User object
|
|
233
|
+
member.status # "creator", "administrator", "member", "restricted", "left", "kicked"
|
|
234
|
+
|
|
235
|
+
# Status-specific fields
|
|
236
|
+
member.custom_title # String (for admins)
|
|
237
|
+
member.is_anonymous # Boolean (for admins)
|
|
238
|
+
member.can_be_edited # Boolean (for admins)
|
|
239
|
+
member.can_manage_chat # Boolean (for admins)
|
|
240
|
+
member.can_delete_messages # Boolean (for admins)
|
|
241
|
+
member.can_manage_video_chats # Boolean (for admins)
|
|
242
|
+
member.can_restrict_members # Boolean (for admins)
|
|
243
|
+
member.can_promote_members # Boolean (for admins)
|
|
244
|
+
member.can_change_info # Boolean (for admins)
|
|
245
|
+
member.can_invite_users # Boolean (for admins)
|
|
246
|
+
member.can_post_messages # Boolean (for admins)
|
|
247
|
+
member.can_edit_messages # Boolean (for admins)
|
|
248
|
+
member.can_pin_messages # Boolean (for admins)
|
|
249
|
+
member.can_manage_topics # Boolean (for admins)
|
|
250
|
+
|
|
251
|
+
# Restrictions (for restricted users)
|
|
252
|
+
member.is_member # Boolean
|
|
253
|
+
member.can_send_messages # Boolean
|
|
254
|
+
member.can_send_media_messages # Boolean
|
|
255
|
+
member.can_send_polls # Boolean
|
|
256
|
+
member.can_send_other_messages # Boolean
|
|
257
|
+
member.can_add_web_page_previews # Boolean
|
|
258
|
+
member.can_change_info # Boolean
|
|
259
|
+
member.can_invite_users # Boolean
|
|
260
|
+
member.can_pin_messages # Boolean
|
|
261
|
+
member.can_manage_topics # Boolean
|
|
262
|
+
member.until_date # Time (restriction end)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Media Types
|
|
266
|
+
|
|
267
|
+
### PhotoSize
|
|
268
|
+
|
|
269
|
+
```ruby
|
|
270
|
+
photo = Telegem::Types::PhotoSize.new(data)
|
|
271
|
+
|
|
272
|
+
photo.file_id # String
|
|
273
|
+
photo.file_unique_id # String
|
|
274
|
+
photo.width # Integer
|
|
275
|
+
photo.height # Integer
|
|
276
|
+
photo.file_size # Integer (optional)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Document
|
|
280
|
+
|
|
281
|
+
```ruby
|
|
282
|
+
doc = Telegem::Types::Document.new(data)
|
|
283
|
+
|
|
284
|
+
doc.file_id # String
|
|
285
|
+
doc.file_unique_id # String
|
|
286
|
+
doc.file_name # String (optional)
|
|
287
|
+
doc.mime_type # String (optional)
|
|
288
|
+
doc.file_size # Integer (optional)
|
|
289
|
+
doc.thumbnail # PhotoSize (optional)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Audio
|
|
293
|
+
|
|
294
|
+
```ruby
|
|
295
|
+
audio = Telegem::Types::Audio.new(data)
|
|
296
|
+
|
|
297
|
+
audio.file_id # String
|
|
298
|
+
audio.file_unique_id # String
|
|
299
|
+
audio.duration # Integer
|
|
300
|
+
audio.performer # String (optional)
|
|
301
|
+
audio.title # String (optional)
|
|
302
|
+
audio.file_name # String (optional)
|
|
303
|
+
audio.mime_type # String (optional)
|
|
304
|
+
audio.file_size # Integer (optional)
|
|
305
|
+
audio.thumbnail # PhotoSize (optional)
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Video
|
|
309
|
+
|
|
310
|
+
```ruby
|
|
311
|
+
video = Telegem::Types::Video.new(data)
|
|
312
|
+
|
|
313
|
+
video.file_id # String
|
|
314
|
+
video.file_unique_id # String
|
|
315
|
+
video.width # Integer
|
|
316
|
+
video.height # Integer
|
|
317
|
+
video.duration # Integer
|
|
318
|
+
video.file_name # String (optional)
|
|
319
|
+
video.mime_type # String (optional)
|
|
320
|
+
video.file_size # Integer (optional)
|
|
321
|
+
video.thumbnail # PhotoSize (optional)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Voice
|
|
325
|
+
|
|
326
|
+
```ruby
|
|
327
|
+
voice = Telegem::Types::Voice.new(data)
|
|
328
|
+
|
|
329
|
+
voice.file_id # String
|
|
330
|
+
voice.file_unique_id # String
|
|
331
|
+
voice.duration # Integer
|
|
332
|
+
voice.mime_type # String (optional)
|
|
333
|
+
voice.file_size # Integer (optional)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Animation
|
|
337
|
+
|
|
338
|
+
```ruby
|
|
339
|
+
anim = Telegem::Types::Animation.new(data)
|
|
340
|
+
|
|
341
|
+
anim.file_id # String
|
|
342
|
+
anim.file_unique_id # String
|
|
343
|
+
anim.width # Integer
|
|
344
|
+
anim.height # Integer
|
|
345
|
+
anim.duration # Integer
|
|
346
|
+
anim.file_name # String (optional)
|
|
347
|
+
anim.mime_type # String (optional)
|
|
348
|
+
anim.file_size # Integer (optional)
|
|
349
|
+
anim.thumbnail # PhotoSize (optional)
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Sticker
|
|
353
|
+
|
|
354
|
+
```ruby
|
|
355
|
+
sticker = Telegem::Types::Sticker.new(data)
|
|
356
|
+
|
|
357
|
+
sticker.file_id # String
|
|
358
|
+
sticker.file_unique_id # String
|
|
359
|
+
sticker.type # "regular", "mask", "custom_emoji"
|
|
360
|
+
sticker.width # Integer
|
|
361
|
+
sticker.height # Integer
|
|
362
|
+
sticker.is_animated # Boolean
|
|
363
|
+
sticker.is_video # Boolean
|
|
364
|
+
sticker.emoji # String (optional)
|
|
365
|
+
sticker.set_name # String (optional)
|
|
366
|
+
sticker.premium_animation # File (optional)
|
|
367
|
+
sticker.mask_position # MaskPosition (optional)
|
|
368
|
+
sticker.custom_emoji_id # String (optional)
|
|
369
|
+
sticker.needs_repainting # Boolean (optional)
|
|
370
|
+
sticker.file_size # Integer (optional)
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Utility Types
|
|
374
|
+
|
|
375
|
+
### Contact
|
|
376
|
+
|
|
377
|
+
```ruby
|
|
378
|
+
contact = Telegem::Types::Contact.new(data)
|
|
379
|
+
|
|
380
|
+
contact.phone_number # String
|
|
381
|
+
contact.first_name # String
|
|
382
|
+
contact.last_name # String (optional)
|
|
383
|
+
contact.user_id # Integer (optional)
|
|
384
|
+
contact.vcard # String (optional)
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Location
|
|
388
|
+
|
|
389
|
+
```ruby
|
|
390
|
+
location = Telegem::Types::Location.new(data)
|
|
391
|
+
|
|
392
|
+
location.latitude # Float
|
|
393
|
+
location.longitude # Float
|
|
394
|
+
location.horizontal_accuracy # Float (optional)
|
|
395
|
+
location.live_period # Integer (optional)
|
|
396
|
+
location.heading # Integer (optional)
|
|
397
|
+
location.proximity_alert_radius # Integer (optional)
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Venue
|
|
401
|
+
|
|
402
|
+
```ruby
|
|
403
|
+
venue = Telegem::Types::Venue.new(data)
|
|
404
|
+
|
|
405
|
+
venue.location # Location object
|
|
406
|
+
venue.title # String
|
|
407
|
+
venue.address # String
|
|
408
|
+
venue.foursquare_id # String (optional)
|
|
409
|
+
venue.foursquare_type # String (optional)
|
|
410
|
+
venue.google_place_id # String (optional)
|
|
411
|
+
venue.google_place_type # String (optional)
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### WebAppData
|
|
415
|
+
|
|
416
|
+
```ruby
|
|
417
|
+
web_app = Telegem::Types::WebAppData.new(data)
|
|
418
|
+
|
|
419
|
+
web_app.data # String
|
|
420
|
+
web_app.button_text # String
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Inline Query Result Types
|
|
424
|
+
|
|
425
|
+
### InlineQueryResultArticle
|
|
426
|
+
|
|
427
|
+
```ruby
|
|
428
|
+
article = Telegem::Types::InlineQueryResultArticle.new(data)
|
|
429
|
+
|
|
430
|
+
article.id # String
|
|
431
|
+
article.title # String
|
|
432
|
+
article.input_message_content # InputMessageContent
|
|
433
|
+
article.reply_markup # InlineKeyboardMarkup (optional)
|
|
434
|
+
article.url # String (optional)
|
|
435
|
+
article.hide_url # Boolean (optional)
|
|
436
|
+
article.description # String (optional)
|
|
437
|
+
article.thumbnail_url # String (optional)
|
|
438
|
+
article.thumbnail_width # Integer (optional)
|
|
439
|
+
article.thumbnail_height # Integer (optional)
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### InlineQueryResultPhoto
|
|
443
|
+
|
|
444
|
+
```ruby
|
|
445
|
+
photo = Telegem::Types::InlineQueryResultPhoto.new(data)
|
|
446
|
+
|
|
447
|
+
photo.id # String
|
|
448
|
+
photo.photo_url # String
|
|
449
|
+
photo.thumbnail_url # String
|
|
450
|
+
photo.photo_width # Integer (optional)
|
|
451
|
+
photo.photo_height # Integer (optional)
|
|
452
|
+
photo.title # String (optional)
|
|
453
|
+
photo.description # String (optional)
|
|
454
|
+
photo.caption # String (optional)
|
|
455
|
+
photo.parse_mode # String (optional)
|
|
456
|
+
photo.caption_entities # Array of MessageEntity (optional)
|
|
457
|
+
photo.reply_markup # InlineKeyboardMarkup (optional)
|
|
458
|
+
photo.input_message_content # InputMessageContent (optional)
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Type Conversion
|
|
462
|
+
|
|
463
|
+
Types automatically convert nested objects:
|
|
464
|
+
|
|
465
|
+
```ruby
|
|
466
|
+
# Message with user and chat
|
|
467
|
+
message = Telegem::Types::Message.new(data)
|
|
468
|
+
message.from # Automatically a User object
|
|
469
|
+
message.chat # Automatically a Chat object
|
|
470
|
+
message.entities # Array of MessageEntity objects
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Custom Types
|
|
474
|
+
|
|
475
|
+
Extend existing types or create new ones:
|
|
476
|
+
|
|
477
|
+
```ruby
|
|
478
|
+
class CustomUser < Telegem::Types::User
|
|
479
|
+
def display_name
|
|
480
|
+
username || full_name
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
def admin?
|
|
484
|
+
# Custom logic
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
# Use in conversions
|
|
489
|
+
Telegem::Types::Message.class_eval do
|
|
490
|
+
def from
|
|
491
|
+
CustomUser.new(@_raw_data['from']) if @_raw_data['from']
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
## Error Handling
|
|
497
|
+
|
|
498
|
+
Type access may raise errors for missing fields:
|
|
499
|
+
|
|
500
|
+
```ruby
|
|
501
|
+
begin
|
|
502
|
+
username = user.username
|
|
503
|
+
rescue NoMethodError
|
|
504
|
+
# Field not present or nil
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
# Safe access
|
|
508
|
+
username = user.respond_to?(:username) ? user.username : nil
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
## Serialization
|
|
512
|
+
|
|
513
|
+
Convert types to various formats:
|
|
514
|
+
|
|
515
|
+
```ruby
|
|
516
|
+
user = Telegem::Types::User.new(data)
|
|
517
|
+
|
|
518
|
+
# To hash
|
|
519
|
+
user.to_h
|
|
520
|
+
|
|
521
|
+
# To JSON
|
|
522
|
+
user.to_json
|
|
523
|
+
|
|
524
|
+
# Pretty print
|
|
525
|
+
puts user.inspect
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## Best Practices
|
|
529
|
+
|
|
530
|
+
1. **Use type checking** before accessing optional fields
|
|
531
|
+
2. **Handle nil values** gracefully
|
|
532
|
+
3. **Leverage helper methods** on types
|
|
533
|
+
4. **Extend types** for custom logic
|
|
534
|
+
5. **Use inspect** for debugging
|
|
535
|
+
6. **Convert to hash/JSON** for storage
|
|
536
|
+
|
|
537
|
+
The type system provides a Ruby-friendly interface to Telegram's API objects, making bot development more intuitive and type-safe.</content>
|
|
538
|
+
<parameter name="filePath">/home/slick/telegem/docs/types.md
|