grammerb 0.1.0-x86_64-linux
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 +7 -0
- data/README.md +554 -0
- data/lib/grammerb/client.rb +802 -0
- data/lib/grammerb/conversation.rb +81 -0
- data/lib/grammerb/errors.rb +108 -0
- data/lib/grammerb/events.rb +438 -0
- data/lib/grammerb/grammerb.so +0 -0
- data/lib/grammerb/types.rb +530 -0
- data/lib/grammerb/version.rb +4 -0
- data/lib/grammerb.rb +19 -0
- data/sig/grammerb/client.rbs +145 -0
- data/sig/grammerb/conversation.rbs +20 -0
- data/sig/grammerb/errors.rbs +50 -0
- data/sig/grammerb/events.rbs +238 -0
- data/sig/grammerb/types.rbs +246 -0
- data/sig/grammerb.rbs +13 -0
- metadata +118 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7e0a2199adf7c1a5140d3b584391bd015d2a900af94e0f4e363a83ceaa28703a
|
|
4
|
+
data.tar.gz: 67dd66363f2f48aabea7c8455d54c4ab0fe7b191b81342c70d04ec81036d5f96
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 20afead47786b1a6f0c780d79d6e2a36c2303efccb15e5ebeeaf9516fd94664b5d0a94d2adfe1e4d66f75f6770c52ca6c6955d5165956e5db34f8ce36b2bbc02
|
|
7
|
+
data.tar.gz: 5ec252049f8f9a360720266b4438b53997e1e034a501a57a9b1266d967978df924b097c557447c59457078ced114adae3c6680b2640767baddc1e902ccd10833
|
data/README.md
ADDED
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
# Grammerb
|
|
2
|
+
|
|
3
|
+
Grammerb -- as in (Tele)**gramme.rb** -- is a Telegram MTProto client library for Ruby. It wraps the Rust [grammers](https://github.com/Lonami/grammers) crate via native extensions, giving you a direct MTProto connection instead of going through the Bot HTTP API.
|
|
4
|
+
|
|
5
|
+
It works for both user accounts and bots.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Ruby >= 3.1
|
|
10
|
+
- Rust toolchain (for compiling the native extension)
|
|
11
|
+
- `libclang-dev` and `ruby-dev` system packages
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Add to your Gemfile:
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
gem "grammerb", path: "/path/to/grammerb"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then build the native extension:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bundle install
|
|
25
|
+
rake compile
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
### Bot login
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
require "grammerb"
|
|
34
|
+
|
|
35
|
+
client = Grammerb::Client.new(
|
|
36
|
+
api_id: ENV["API_ID"].to_i,
|
|
37
|
+
api_hash: ENV["API_HASH"],
|
|
38
|
+
session: "bot.session"
|
|
39
|
+
)
|
|
40
|
+
client.bot_start(token: ENV["BOT_TOKEN"])
|
|
41
|
+
|
|
42
|
+
client.on(Grammerb::Events::NewMessage, pattern: /^\/start/) do |event|
|
|
43
|
+
event.reply("Hello!")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
client.run
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### User login
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
client = Grammerb::Client.new(
|
|
53
|
+
api_id: ENV["API_ID"].to_i,
|
|
54
|
+
api_hash: ENV["API_HASH"],
|
|
55
|
+
session: "user.session"
|
|
56
|
+
)
|
|
57
|
+
client.start(phone: "+1234567890")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You can pass callbacks instead of reading from stdin:
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
client.start(
|
|
64
|
+
phone: "+1234567890",
|
|
65
|
+
code_callback: -> { get_code_from_somewhere },
|
|
66
|
+
password_callback: -> { get_2fa_password }
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The session file is saved after authentication, so you only need to log in once.
|
|
71
|
+
|
|
72
|
+
## Client options
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
client = Grammerb::Client.new(
|
|
76
|
+
api_id: 12345,
|
|
77
|
+
api_hash: "abc123",
|
|
78
|
+
session: "grammerb.session", # session file path (default: "grammerb.session")
|
|
79
|
+
proxy: "socks5://host:port", # SOCKS5 proxy (optional)
|
|
80
|
+
logger: Logger.new($stdout), # custom logger (optional, defaults to stderr at WARN level)
|
|
81
|
+
pool_size: 20 # handler thread pool size (default: 20)
|
|
82
|
+
)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## API
|
|
86
|
+
|
|
87
|
+
### Connection
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
client.connect
|
|
91
|
+
client.disconnect
|
|
92
|
+
client.authorized?
|
|
93
|
+
client.save_session
|
|
94
|
+
client.sign_out
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Messages
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
# Send with all options
|
|
101
|
+
client.send_message(chat, "text",
|
|
102
|
+
reply_to: msg_id,
|
|
103
|
+
parse_mode: "html", # "html" or "markdown"
|
|
104
|
+
silent: true, # no notification
|
|
105
|
+
link_preview: false, # disable link preview
|
|
106
|
+
schedule: Time.now + 3600, # scheduled message (unix timestamp)
|
|
107
|
+
buttons: buttons # inline keyboard (see below)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
client.edit_message(chat, message_id, "new text", parse_mode: "html", buttons: buttons)
|
|
111
|
+
client.delete_messages(chat, msg_id1, msg_id2, msg_id3)
|
|
112
|
+
client.forward_messages(from_chat, [msg_id], to_chat)
|
|
113
|
+
client.get_messages(chat, limit: 20)
|
|
114
|
+
client.get_messages_by_id(chat, 123, 456)
|
|
115
|
+
client.search_messages(chat, query: "keyword", limit: 100)
|
|
116
|
+
client.search_all_messages(query: "keyword", limit: 100)
|
|
117
|
+
client.pin_message(chat, message_id)
|
|
118
|
+
client.unpin_message(chat, message_id)
|
|
119
|
+
client.unpin_all_messages(chat)
|
|
120
|
+
client.get_pinned_message(chat)
|
|
121
|
+
client.get_reply_to_message(chat, message_id)
|
|
122
|
+
client.send_reactions(chat, message_id, "thumbs_up")
|
|
123
|
+
client.send_chat_action(chat, "typing")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Inline keyboards
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
buttons = [
|
|
130
|
+
[
|
|
131
|
+
{ text: "Click me", callback_data: "btn1" },
|
|
132
|
+
{ text: "Open link", url: "https://example.com" },
|
|
133
|
+
{ text: "Switch inline", switch_inline: "query" }
|
|
134
|
+
]
|
|
135
|
+
]
|
|
136
|
+
client.send_message(chat, "Pick one:", buttons: buttons)
|
|
137
|
+
client.edit_message(chat, msg_id, "Updated", buttons: buttons)
|
|
138
|
+
client.send_file(chat, "/path/to/file.pdf", caption: "Doc", buttons: buttons)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Reply keyboards
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
keys = [
|
|
145
|
+
["Option A", "Option B"],
|
|
146
|
+
[{ text: "Share Phone", request_phone: true }]
|
|
147
|
+
]
|
|
148
|
+
client.send_reply_keyboard(chat, "Choose:", keys,
|
|
149
|
+
resize: true,
|
|
150
|
+
single_use: false,
|
|
151
|
+
placeholder: "Pick an option..."
|
|
152
|
+
)
|
|
153
|
+
client.remove_keyboard(chat)
|
|
154
|
+
client.remove_keyboard(chat, "Custom removal text")
|
|
155
|
+
client.force_reply(chat, "What is your name?")
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Files and media
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
client.send_file(chat, "/path/to/file.pdf", caption: "Document", parse_mode: "html")
|
|
162
|
+
client.send_photo(chat, "/path/to/image.jpg", caption: "Photo", parse_mode: "html")
|
|
163
|
+
client.send_video(chat, "/path/to/video.mp4",
|
|
164
|
+
caption: "Video", parse_mode: "html",
|
|
165
|
+
duration: 30, width: 1920, height: 1080, supports_streaming: true
|
|
166
|
+
)
|
|
167
|
+
client.send_audio(chat, "/path/to/song.mp3",
|
|
168
|
+
caption: "Song", parse_mode: "html",
|
|
169
|
+
duration: 180, title: "Song Title", performer: "Artist"
|
|
170
|
+
)
|
|
171
|
+
client.send_voice(chat, "/path/to/voice.ogg", caption: "Voice", duration: 5)
|
|
172
|
+
|
|
173
|
+
# Albums (grouped media)
|
|
174
|
+
client.send_album(chat, "/path/a.jpg", "/path/b.jpg")
|
|
175
|
+
client.send_album(chat, { path: "/a.jpg" }, { path: "/b.jpg" })
|
|
176
|
+
|
|
177
|
+
# Download
|
|
178
|
+
client.download_media(chat, message_id, "/path/to/save")
|
|
179
|
+
|
|
180
|
+
# Download with progress
|
|
181
|
+
client.download_media(chat, message_id, "/path/to/save") do |downloaded, total|
|
|
182
|
+
puts "#{downloaded}/#{total} bytes"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Upload management
|
|
186
|
+
idx = client.upload_file("/path/to/file")
|
|
187
|
+
client.clear_uploaded(idx)
|
|
188
|
+
client.clear_all_uploads
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Polls
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
client.send_poll(chat, "Favorite color?", ["Red", "Blue", "Green"])
|
|
195
|
+
client.send_poll(chat, "Capital of France?", ["London", "Paris", "Berlin"], quiz: true, correct_option: 1)
|
|
196
|
+
client.get_poll_results(chat, message_id)
|
|
197
|
+
client.get_poll_votes(chat, message_id, option: 0, limit: 100)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Dialogs
|
|
201
|
+
|
|
202
|
+
```ruby
|
|
203
|
+
dialogs = client.iter_dialogs(limit: 100) # alias: get_dialogs
|
|
204
|
+
dialogs.each do |d|
|
|
205
|
+
puts "#{d.name} (#{d.peer_type}) - #{d.unread_count} unread"
|
|
206
|
+
puts " Last: #{d.last_message_text}"
|
|
207
|
+
end
|
|
208
|
+
client.delete_dialog(chat)
|
|
209
|
+
client.mark_as_read(chat)
|
|
210
|
+
client.clear_mentions(chat)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Users and chats
|
|
214
|
+
|
|
215
|
+
```ruby
|
|
216
|
+
me = client.get_me # => Types::User
|
|
217
|
+
me.id, me.first_name, me.last_name, me.username, me.phone, me.bot?
|
|
218
|
+
|
|
219
|
+
peer = client.resolve_username("durov") # => Types::Peer
|
|
220
|
+
peer.id, peer.name, peer.peer_type
|
|
221
|
+
|
|
222
|
+
results = client.search_peer("query", limit: 10)
|
|
223
|
+
|
|
224
|
+
participants = client.iter_participants(chat, limit: 200) # alias: get_participants
|
|
225
|
+
participants.each { |p| puts "#{p.full_name} (@#{p.username})" }
|
|
226
|
+
|
|
227
|
+
client.kick_participant(chat, user_id)
|
|
228
|
+
client.set_admin_rights(chat, user_id, post_messages: true)
|
|
229
|
+
client.set_banned_rights(chat, user_id, send_messages: true)
|
|
230
|
+
|
|
231
|
+
perms = client.get_permissions(chat, user_id)
|
|
232
|
+
perms.admin?, perms.creator?, perms.banned?, perms.has_default_permissions
|
|
233
|
+
|
|
234
|
+
client.join_chat("https://t.me/+invite_link")
|
|
235
|
+
link = client.export_invite_link(chat)
|
|
236
|
+
client.block_user(user_id)
|
|
237
|
+
client.unblock_user(user_id)
|
|
238
|
+
client.iter_profile_photos(peer_id, limit: 10)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Bots
|
|
242
|
+
|
|
243
|
+
```ruby
|
|
244
|
+
client.inline_query("@bot", "search term", limit: 20)
|
|
245
|
+
client.answer_callback_query(query_id, text: "Done!", alert: false, cache_time: 60)
|
|
246
|
+
client.answer_inline_query(query_id, results,
|
|
247
|
+
cache_time: 300,
|
|
248
|
+
is_personal: false,
|
|
249
|
+
next_offset: "page2"
|
|
250
|
+
)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Sessions
|
|
254
|
+
|
|
255
|
+
```ruby
|
|
256
|
+
encoded = client.export_session
|
|
257
|
+
Grammerb::Client.import_session(encoded, path: "copy.session")
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Raw TL
|
|
261
|
+
|
|
262
|
+
```ruby
|
|
263
|
+
response_bytes = client.invoke_raw(request_bytes)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Events
|
|
267
|
+
|
|
268
|
+
Register handlers with `client.on` and call `client.run` to start the event loop.
|
|
269
|
+
|
|
270
|
+
```ruby
|
|
271
|
+
# All new messages
|
|
272
|
+
client.on(Grammerb::Events::NewMessage) { |e| puts e.text }
|
|
273
|
+
|
|
274
|
+
# Pattern matching
|
|
275
|
+
client.on(Grammerb::Events::NewMessage, pattern: /^\/help/) { |e| e.reply("Help text") }
|
|
276
|
+
|
|
277
|
+
# Filter by chat
|
|
278
|
+
client.on(Grammerb::Events::NewMessage, chats: ["mychannel", -100123456]) { |e| ... }
|
|
279
|
+
|
|
280
|
+
# Callback queries (inline button presses)
|
|
281
|
+
client.on(Grammerb::Events::CallbackQuery) do |e|
|
|
282
|
+
e.answer(text: "Button pressed", alert: true, cache_time: 60)
|
|
283
|
+
puts e.data_str # callback_data as UTF-8 string
|
|
284
|
+
puts e.chat_id
|
|
285
|
+
puts e.sender_id
|
|
286
|
+
puts e.message_id
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Message edits
|
|
290
|
+
client.on(Grammerb::Events::MessageEdited) { |e| puts "Edited: #{e.text}" }
|
|
291
|
+
|
|
292
|
+
# Message deletions
|
|
293
|
+
client.on(Grammerb::Events::MessageDeleted) do |e|
|
|
294
|
+
puts "Deleted: #{e.deleted_ids}"
|
|
295
|
+
puts "In chat: #{e.chat_id}"
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# Inline queries
|
|
299
|
+
client.on(Grammerb::Events::InlineQuery) do |e|
|
|
300
|
+
puts e.query, e.offset, e.sender_id
|
|
301
|
+
e.answer(results, cache_time: 300, is_personal: false, next_offset: "2")
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# Inline send (when user picks an inline result)
|
|
305
|
+
client.on(Grammerb::Events::InlineSend) { |e| puts e.sender_id }
|
|
306
|
+
|
|
307
|
+
# Albums (grouped media) -- automatically buffered from individual messages
|
|
308
|
+
client.on(Grammerb::Events::Album) do |e|
|
|
309
|
+
puts "Album with #{e.messages.size} items in #{e.chat_name}"
|
|
310
|
+
puts e.texts
|
|
311
|
+
e.reply("Nice album!")
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# Raw/unhandled updates
|
|
315
|
+
client.on(Grammerb::Events::RawUpdate) { |e| puts e.raw }
|
|
316
|
+
|
|
317
|
+
# Update errors
|
|
318
|
+
client.on(Grammerb::Events::UpdateError) { |e| puts e.message }
|
|
319
|
+
|
|
320
|
+
# Remove a handler
|
|
321
|
+
handler = client.on(Grammerb::Events::NewMessage) { |e| ... }
|
|
322
|
+
client.off(handler)
|
|
323
|
+
|
|
324
|
+
# Stop the event loop
|
|
325
|
+
client.stop
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Alternative event loop
|
|
329
|
+
|
|
330
|
+
Instead of handler registration, you can iterate updates directly:
|
|
331
|
+
|
|
332
|
+
```ruby
|
|
333
|
+
client.each_update do |event|
|
|
334
|
+
case event
|
|
335
|
+
when Grammerb::Events::NewMessage
|
|
336
|
+
puts event.text
|
|
337
|
+
when Grammerb::Events::CallbackQuery
|
|
338
|
+
event.answer(text: "ok")
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Event fields
|
|
344
|
+
|
|
345
|
+
NewMessage and MessageEdited events share these fields:
|
|
346
|
+
|
|
347
|
+
```ruby
|
|
348
|
+
event.message_id
|
|
349
|
+
event.text
|
|
350
|
+
event.chat_id
|
|
351
|
+
event.chat_name
|
|
352
|
+
event.sender_id
|
|
353
|
+
event.sender_name
|
|
354
|
+
event.date # Time object
|
|
355
|
+
event.chat_type # "user", "chat", or "channel"
|
|
356
|
+
event.grouped_id # non-nil for album messages
|
|
357
|
+
event.sender_is_bot
|
|
358
|
+
event.private? # chat_type == "user"
|
|
359
|
+
event.group? # chat_type == "chat"
|
|
360
|
+
event.channel? # chat_type == "channel"
|
|
361
|
+
event.bot? # sender is a bot
|
|
362
|
+
event.album? # part of a grouped album
|
|
363
|
+
event.reply("text")
|
|
364
|
+
event.edit("new text", parse_mode: "html")
|
|
365
|
+
event.delete
|
|
366
|
+
event.forward(other_chat)
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Types
|
|
370
|
+
|
|
371
|
+
### Message
|
|
372
|
+
|
|
373
|
+
Returned by `get_messages`, `get_messages_by_id`, `search_messages`, etc.
|
|
374
|
+
|
|
375
|
+
```ruby
|
|
376
|
+
msg.id
|
|
377
|
+
msg.text
|
|
378
|
+
msg.chat_id
|
|
379
|
+
msg.chat_name
|
|
380
|
+
msg.sender_id
|
|
381
|
+
msg.sender_name
|
|
382
|
+
msg.date # Time object
|
|
383
|
+
msg.chat_type # "user", "chat", "channel"
|
|
384
|
+
msg.grouped_id
|
|
385
|
+
msg.reply_to_message_id
|
|
386
|
+
|
|
387
|
+
# Media
|
|
388
|
+
msg.has_media?
|
|
389
|
+
msg.media_type # "photo", "document", "sticker", "poll", "contact",
|
|
390
|
+
# "geo", "venue", "dice", "geo_live", "web_page"
|
|
391
|
+
msg.photo?
|
|
392
|
+
msg.document?
|
|
393
|
+
msg.sticker?
|
|
394
|
+
msg.poll?
|
|
395
|
+
msg.album?
|
|
396
|
+
msg.media_id
|
|
397
|
+
msg.media_file_name
|
|
398
|
+
msg.media_mime_type
|
|
399
|
+
msg.media_size
|
|
400
|
+
msg.media_duration
|
|
401
|
+
msg.media_width
|
|
402
|
+
msg.media_height
|
|
403
|
+
msg.media_sticker_emoji
|
|
404
|
+
|
|
405
|
+
# Buttons
|
|
406
|
+
msg.has_buttons?
|
|
407
|
+
msg.buttons # array of rows, each row is array of Types::Button
|
|
408
|
+
|
|
409
|
+
# Actions
|
|
410
|
+
msg.reply("text")
|
|
411
|
+
msg.edit("new text", parse_mode: "html", buttons: buttons)
|
|
412
|
+
msg.delete
|
|
413
|
+
msg.forward(other_chat)
|
|
414
|
+
msg.pin
|
|
415
|
+
msg.download("/path/to/save") { |downloaded, total| ... }
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Button
|
|
419
|
+
|
|
420
|
+
```ruby
|
|
421
|
+
button.text
|
|
422
|
+
button.callback_data # raw bytes
|
|
423
|
+
button.data_str # callback_data as UTF-8 string
|
|
424
|
+
button.url
|
|
425
|
+
button.switch_inline
|
|
426
|
+
button.callback?
|
|
427
|
+
button.url?
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### User
|
|
431
|
+
|
|
432
|
+
```ruby
|
|
433
|
+
user.id
|
|
434
|
+
user.first_name
|
|
435
|
+
user.last_name
|
|
436
|
+
user.username
|
|
437
|
+
user.phone
|
|
438
|
+
user.bot?
|
|
439
|
+
user.full_name # "first last"
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Dialog
|
|
443
|
+
|
|
444
|
+
```ruby
|
|
445
|
+
dialog.id
|
|
446
|
+
dialog.name
|
|
447
|
+
dialog.peer_type
|
|
448
|
+
dialog.unread_count
|
|
449
|
+
dialog.last_message_text
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Participant
|
|
453
|
+
|
|
454
|
+
```ruby
|
|
455
|
+
participant.id
|
|
456
|
+
participant.first_name
|
|
457
|
+
participant.last_name
|
|
458
|
+
participant.username
|
|
459
|
+
participant.full_name
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Peer
|
|
463
|
+
|
|
464
|
+
```ruby
|
|
465
|
+
peer.id
|
|
466
|
+
peer.name
|
|
467
|
+
peer.peer_type
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### Permissions
|
|
471
|
+
|
|
472
|
+
```ruby
|
|
473
|
+
perms.is_admin
|
|
474
|
+
perms.is_creator
|
|
475
|
+
perms.is_banned
|
|
476
|
+
perms.has_default_permissions
|
|
477
|
+
perms.admin?
|
|
478
|
+
perms.creator?
|
|
479
|
+
perms.banned?
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## Errors
|
|
483
|
+
|
|
484
|
+
All errors inherit from `Grammerb::Errors::Error`.
|
|
485
|
+
|
|
486
|
+
```
|
|
487
|
+
Grammerb::Errors::Error
|
|
488
|
+
Grammerb::Errors::ConnectionError
|
|
489
|
+
Grammerb::Errors::AuthError
|
|
490
|
+
Grammerb::Errors::NotConnectedError
|
|
491
|
+
Grammerb::Errors::RPCError
|
|
492
|
+
Grammerb::Errors::FloodWait
|
|
493
|
+
Grammerb::Errors::UserNotFound
|
|
494
|
+
Grammerb::Errors::ChatWriteForbidden
|
|
495
|
+
Grammerb::Errors::PhoneNumberInvalid
|
|
496
|
+
Grammerb::Errors::SessionPasswordNeeded
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
RPCError has `code`, `message_text`, and `value` attributes. FloodWait has a `seconds` attribute with the wait time.
|
|
500
|
+
|
|
501
|
+
FloodWait errors inside event handlers are automatically caught and slept on.
|
|
502
|
+
|
|
503
|
+
```ruby
|
|
504
|
+
begin
|
|
505
|
+
client.send_message(chat, "hello")
|
|
506
|
+
rescue Grammerb::Errors::FloodWait => e
|
|
507
|
+
sleep e.seconds
|
|
508
|
+
retry
|
|
509
|
+
rescue Grammerb::Errors::ChatWriteForbidden
|
|
510
|
+
puts "Can't write to this chat"
|
|
511
|
+
rescue Grammerb::Errors::RPCError => e
|
|
512
|
+
puts "RPC error #{e.code}: #{e.message_text}"
|
|
513
|
+
end
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
## Not yet implemented
|
|
517
|
+
|
|
518
|
+
The following Telegram features are not currently supported:
|
|
519
|
+
|
|
520
|
+
- Creating groups, channels, or supergroups
|
|
521
|
+
- Editing chat title, description, or photo
|
|
522
|
+
- Slow mode
|
|
523
|
+
- Forum topics / threads
|
|
524
|
+
- Message threads and replies-to-threads
|
|
525
|
+
- Scheduled message management (listing, deleting scheduled messages)
|
|
526
|
+
- Drafts
|
|
527
|
+
- Voice and video calls
|
|
528
|
+
- Stories
|
|
529
|
+
- Contacts (import, add, delete, get contacts list)
|
|
530
|
+
- Account management (update profile, change username, set privacy)
|
|
531
|
+
- Two-factor authentication setup/management
|
|
532
|
+
- Notification settings
|
|
533
|
+
- Chat folders / filters
|
|
534
|
+
- Sticker set management (create, add, remove sticker packs)
|
|
535
|
+
- GIF search and saved GIFs
|
|
536
|
+
- Payments and invoices
|
|
537
|
+
- Bot menu button and commands management
|
|
538
|
+
- Channel and group statistics
|
|
539
|
+
- Sponsored messages
|
|
540
|
+
- Message translations
|
|
541
|
+
- Custom emoji
|
|
542
|
+
- Takeout / data export
|
|
543
|
+
- Telegram Premium features
|
|
544
|
+
- Usernames (collectible usernames, multiple usernames)
|
|
545
|
+
- Reactions list (who reacted)
|
|
546
|
+
- Chat event log / admin log
|
|
547
|
+
- Nearby users and chats
|
|
548
|
+
- Password hint and recovery email
|
|
549
|
+
|
|
550
|
+
These can still be accessed via `client.invoke_raw(request_bytes)` if you construct the TL request manually.
|
|
551
|
+
|
|
552
|
+
## License
|
|
553
|
+
|
|
554
|
+
MIT
|