telegram-bot-ruby 2.4.0 → 2.6.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/.claude/skills/update-api/SKILL.md +70 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +19 -0
- data/CHANGELOG.md +16 -0
- data/README.md +40 -23
- data/lib/telegram/bot/api/endpoints.rb +110 -62
- data/lib/telegram/bot/api.rb +13 -1
- data/lib/telegram/bot/configuration.rb +2 -1
- data/lib/telegram/bot/types/accepted_gift_types.rb +15 -0
- data/lib/telegram/bot/types/business_bot_rights.rb +24 -0
- data/lib/telegram/bot/types/business_connection.rb +1 -1
- data/lib/telegram/bot/types/callback_query.rb +4 -0
- data/lib/telegram/bot/types/chat.rb +1 -0
- data/lib/telegram/bot/types/chat_administrator_rights.rb +2 -0
- data/lib/telegram/bot/types/chat_full_info.rb +7 -1
- data/lib/telegram/bot/types/chat_member_administrator.rb +2 -0
- data/lib/telegram/bot/types/chat_member_member.rb +1 -0
- data/lib/telegram/bot/types/chat_member_restricted.rb +2 -0
- data/lib/telegram/bot/types/chat_owner_changed.rb +11 -0
- data/lib/telegram/bot/types/chat_owner_left.rb +11 -0
- data/lib/telegram/bot/types/chat_permissions.rb +1 -0
- data/lib/telegram/bot/types/checklist.rb +15 -0
- data/lib/telegram/bot/types/checklist_task.rb +16 -0
- data/lib/telegram/bot/types/checklist_tasks_added.rb +12 -0
- data/lib/telegram/bot/types/checklist_tasks_done.rb +13 -0
- data/lib/telegram/bot/types/direct_message_price_changed.rb +12 -0
- data/lib/telegram/bot/types/direct_messages_topic.rb +12 -0
- data/lib/telegram/bot/types/external_reply_info.rb +1 -0
- data/lib/telegram/bot/types/forum_topic.rb +1 -0
- data/lib/telegram/bot/types/forum_topic_created.rb +1 -0
- data/lib/telegram/bot/types/gift.rb +7 -0
- data/lib/telegram/bot/types/gift_background.rb +13 -0
- data/lib/telegram/bot/types/gift_info.rb +20 -0
- data/lib/telegram/bot/types/inline_keyboard_button.rb +2 -0
- data/lib/telegram/bot/types/input_checklist.rb +16 -0
- data/lib/telegram/bot/types/input_checklist_task.rb +14 -0
- data/lib/telegram/bot/types/input_file.rb +10 -0
- data/lib/telegram/bot/types/input_profile_photo.rb +15 -0
- data/lib/telegram/bot/types/input_profile_photo_animated.rb +13 -0
- data/lib/telegram/bot/types/input_profile_photo_static.rb +12 -0
- data/lib/telegram/bot/types/input_story_content.rb +15 -0
- data/lib/telegram/bot/types/input_story_content_photo.rb +12 -0
- data/lib/telegram/bot/types/input_story_content_video.rb +15 -0
- data/lib/telegram/bot/types/keyboard_button.rb +2 -0
- data/lib/telegram/bot/types/location_address.rb +14 -0
- data/lib/telegram/bot/types/message.rb +24 -1
- data/lib/telegram/bot/types/message_entity.rb +2 -0
- data/lib/telegram/bot/types/owned_gift.rb +15 -0
- data/lib/telegram/bot/types/owned_gift_regular.rb +25 -0
- data/lib/telegram/bot/types/owned_gift_unique.rb +19 -0
- data/lib/telegram/bot/types/owned_gifts.rb +13 -0
- data/lib/telegram/bot/types/paid_message_price_changed.rb +11 -0
- data/lib/telegram/bot/types/reply_parameters.rb +1 -0
- data/lib/telegram/bot/types/star_amount.rb +12 -0
- data/lib/telegram/bot/types/story_area.rb +12 -0
- data/lib/telegram/bot/types/story_area_position.rb +16 -0
- data/lib/telegram/bot/types/story_area_type.rb +18 -0
- data/lib/telegram/bot/types/story_area_type_link.rb +12 -0
- data/lib/telegram/bot/types/story_area_type_location.rb +14 -0
- data/lib/telegram/bot/types/story_area_type_suggested_reaction.rb +14 -0
- data/lib/telegram/bot/types/story_area_type_unique_gift.rb +12 -0
- data/lib/telegram/bot/types/story_area_type_weather.rb +14 -0
- data/lib/telegram/bot/types/suggested_post_approval_failed.rb +12 -0
- data/lib/telegram/bot/types/suggested_post_approved.rb +13 -0
- data/lib/telegram/bot/types/suggested_post_declined.rb +12 -0
- data/lib/telegram/bot/types/suggested_post_info.rb +13 -0
- data/lib/telegram/bot/types/suggested_post_paid.rb +14 -0
- data/lib/telegram/bot/types/suggested_post_parameters.rb +12 -0
- data/lib/telegram/bot/types/suggested_post_price.rb +12 -0
- data/lib/telegram/bot/types/suggested_post_refunded.rb +12 -0
- data/lib/telegram/bot/types/transaction_partner_user.rb +2 -0
- data/lib/telegram/bot/types/unique_gift.rb +22 -0
- data/lib/telegram/bot/types/unique_gift_backdrop.rb +13 -0
- data/lib/telegram/bot/types/unique_gift_backdrop_colors.rb +14 -0
- data/lib/telegram/bot/types/unique_gift_colors.rb +16 -0
- data/lib/telegram/bot/types/unique_gift_info.rb +17 -0
- data/lib/telegram/bot/types/unique_gift_model.rb +14 -0
- data/lib/telegram/bot/types/unique_gift_symbol.rb +13 -0
- data/lib/telegram/bot/types/user.rb +2 -0
- data/lib/telegram/bot/types/user_profile_audios.rb +12 -0
- data/lib/telegram/bot/types/user_rating.rb +14 -0
- data/lib/telegram/bot/types/video.rb +1 -0
- data/lib/telegram/bot/types/video_quality.rb +16 -0
- data/lib/telegram/bot/version.rb +1 -1
- data/rakelib/builders/endpoints_builder.rb +51 -0
- data/rakelib/builders/type_builder.rb +140 -0
- data/rakelib/parse.rake +31 -0
- data/rakelib/parsers/methods_parser.rb +115 -0
- data/rakelib/parsers/types_parser.rb +273 -0
- data/rakelib/rebuild.rake +30 -0
- data/rakelib/templates/endpoints.erb +13 -0
- metadata +65 -9
- data/rakelib/parse_schema.rake +0 -73
- data/rakelib/rebuild_types.rake +0 -90
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
|
|
6
|
+
module Parsers
|
|
7
|
+
class MethodsParser
|
|
8
|
+
API_URL = 'https://core.telegram.org/bots/api'
|
|
9
|
+
|
|
10
|
+
def parse
|
|
11
|
+
doc = fetch_document
|
|
12
|
+
result = {}
|
|
13
|
+
|
|
14
|
+
method_headers(doc).each do |header|
|
|
15
|
+
method_name = extract_method_name(header)
|
|
16
|
+
next unless method_name
|
|
17
|
+
|
|
18
|
+
return_type = extract_return_type(header)
|
|
19
|
+
result[method_name] = return_type if return_type
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
result
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def fetch_document
|
|
28
|
+
uri = URI.parse(API_URL)
|
|
29
|
+
response = Net::HTTP.get(uri)
|
|
30
|
+
Nokogiri::HTML(response)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def method_headers(doc)
|
|
34
|
+
doc.css('h4')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def extract_method_name(header)
|
|
38
|
+
name = header.text.strip
|
|
39
|
+
# Methods start with lowercase letter (camelCase)
|
|
40
|
+
# Types start with uppercase (PascalCase) - skip those
|
|
41
|
+
return nil unless name.match?(/\A[a-z][a-zA-Z0-9]*\z/)
|
|
42
|
+
|
|
43
|
+
name
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def extract_return_type(header)
|
|
47
|
+
# Find description paragraphs after the header
|
|
48
|
+
sibling = header.next_element
|
|
49
|
+
|
|
50
|
+
while sibling
|
|
51
|
+
break if sibling.name == 'h4' # Next section
|
|
52
|
+
|
|
53
|
+
if sibling.name == 'p'
|
|
54
|
+
return_type = parse_return_statement(sibling)
|
|
55
|
+
return return_type if return_type
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
sibling = sibling.next_element
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def parse_return_statement(paragraph)
|
|
65
|
+
html = paragraph.inner_html
|
|
66
|
+
|
|
67
|
+
# Pattern: Returns an Array of <a>Type</a>
|
|
68
|
+
if (match = html.match(%r{Returns an Array of <a[^>]*>([^<]+)</a>}i))
|
|
69
|
+
return "Array<#{match[1]}>"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Pattern: On success, an array of <a>Type</a> (lowercase)
|
|
73
|
+
if (match = html.match(%r{On success,? an array of <a[^>]*>([^<]+)</a>}i))
|
|
74
|
+
return "Array<#{match[1]}>"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Pattern: Returns a <a>Type</a> or Returns the <a>Type</a>
|
|
78
|
+
if (match = html.match(%r{Returns (?:a |the )?.*?<a[^>]*>([^<]+)</a>}i))
|
|
79
|
+
return match[1]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Pattern: Returns basic information ... in form of a <a>Type</a>
|
|
83
|
+
if (match = html.match(%r{in form of a <a[^>]*>([^<]+)</a>}i))
|
|
84
|
+
return match[1]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Pattern: <a>Type</a> is returned, otherwise True is returned (union type)
|
|
88
|
+
# e.g., "the edited Message is returned, otherwise True is returned"
|
|
89
|
+
if (match = html.match(%r{<a[^>]*>([^<]+)</a> is returned,? otherwise <em>True</em> is returned}i))
|
|
90
|
+
return "#{match[1]} | Boolean"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Pattern: Returns <em>True</em> or On success, <em>True</em> is returned
|
|
94
|
+
return 'Boolean' if html.match?(%r{<em>True</em>(?:\s+(?:is|on)|\s*\.)}i)
|
|
95
|
+
|
|
96
|
+
# Pattern: On success, a <a>Type</a> object is returned
|
|
97
|
+
if (match = html.match(%r{On success,? a <a[^>]*>([^<]+)</a> object is returned}i))
|
|
98
|
+
return match[1]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Pattern: On success, the <a>Type</a> is returned / the edited/sent/stopped <a>X</a> is returned
|
|
102
|
+
if (match = html.match(%r{the (?:sent |edited |stopped )?<a[^>]*>([^<]+)</a> is returned}i))
|
|
103
|
+
return match[1]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Pattern: Returns <em>Int</em> or Integer
|
|
107
|
+
return 'Integer' if html.match?(%r{Returns <em>Int</em>}i)
|
|
108
|
+
|
|
109
|
+
# Pattern: Returns ... as <em>String</em>
|
|
110
|
+
return 'String' if html.match?(%r{as <em>String</em>}i)
|
|
111
|
+
|
|
112
|
+
nil
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
|
|
6
|
+
module Parsers
|
|
7
|
+
class TypesParser
|
|
8
|
+
API_URL = 'https://core.telegram.org/bots/api'
|
|
9
|
+
|
|
10
|
+
PRIMITIVE_TYPES = {
|
|
11
|
+
'String' => 'string',
|
|
12
|
+
'Integer' => 'integer',
|
|
13
|
+
'Boolean' => 'boolean',
|
|
14
|
+
'Float' => 'number',
|
|
15
|
+
'True' => 'boolean'
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
def parse
|
|
19
|
+
doc = fetch_document
|
|
20
|
+
result = {}
|
|
21
|
+
|
|
22
|
+
type_headers(doc).each do |header|
|
|
23
|
+
type_name = extract_type_name(header)
|
|
24
|
+
next unless type_name
|
|
25
|
+
|
|
26
|
+
type_data = parse_type(header, type_name)
|
|
27
|
+
result[type_name] = type_data if type_data
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
result
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def fetch_document
|
|
36
|
+
uri = URI.parse(API_URL)
|
|
37
|
+
response = Net::HTTP.get(uri)
|
|
38
|
+
Nokogiri::HTML(response)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def type_headers(doc)
|
|
42
|
+
doc.css('h4')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def extract_type_name(header)
|
|
46
|
+
name = header.text.strip
|
|
47
|
+
# Types start with uppercase letter (CapitalCase)
|
|
48
|
+
# Methods start with lowercase (camelCase) - skip those
|
|
49
|
+
return nil unless name.match?(/\A[A-Z][a-zA-Z0-9]*\z/)
|
|
50
|
+
|
|
51
|
+
name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def parse_type(header, _type_name)
|
|
55
|
+
# Check if this is a union type (list of types without a table)
|
|
56
|
+
next_sibling = find_next_significant_sibling(header)
|
|
57
|
+
|
|
58
|
+
if union_type?(next_sibling)
|
|
59
|
+
parse_union_type(next_sibling)
|
|
60
|
+
else
|
|
61
|
+
parse_table_type(header)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def find_next_significant_sibling(header)
|
|
66
|
+
sibling = header.next_element
|
|
67
|
+
# Skip description paragraphs
|
|
68
|
+
sibling = sibling.next_element while sibling && sibling.name == 'p'
|
|
69
|
+
sibling
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def union_type?(element)
|
|
73
|
+
element&.name == 'ul'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def parse_union_type(ul_element)
|
|
77
|
+
types = ul_element.css('li a').map { |a| a.text.strip }
|
|
78
|
+
{ 'type' => types }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def parse_table_type(header)
|
|
82
|
+
table = find_attribute_table(header)
|
|
83
|
+
return {} unless table
|
|
84
|
+
|
|
85
|
+
attributes = {}
|
|
86
|
+
table.css('tbody tr').each do |row|
|
|
87
|
+
cells = row.css('td')
|
|
88
|
+
next unless cells.length >= 3
|
|
89
|
+
|
|
90
|
+
field_name = cells[0].text.strip
|
|
91
|
+
type_info = cells[1]
|
|
92
|
+
description_cell = cells[2]
|
|
93
|
+
|
|
94
|
+
attributes[field_name] = parse_attribute(type_info, description_cell)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
attributes
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def find_attribute_table(header)
|
|
101
|
+
sibling = header.next_element
|
|
102
|
+
while sibling
|
|
103
|
+
return sibling if sibling.name == 'table'
|
|
104
|
+
# Stop if we hit another h4 (next type/method)
|
|
105
|
+
break if sibling.name == 'h4'
|
|
106
|
+
|
|
107
|
+
sibling = sibling.next_element
|
|
108
|
+
end
|
|
109
|
+
nil
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def parse_attribute(type_cell, description_cell)
|
|
113
|
+
attribute = {}
|
|
114
|
+
raw_type = type_cell.text.strip
|
|
115
|
+
description = description_cell.text.strip
|
|
116
|
+
description_html = description_cell.inner_html
|
|
117
|
+
|
|
118
|
+
# Parse type
|
|
119
|
+
type_value = parse_type_value(type_cell)
|
|
120
|
+
if type_value.is_a?(Hash)
|
|
121
|
+
attribute.merge!(type_value)
|
|
122
|
+
else
|
|
123
|
+
attribute['type'] = type_value
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Parse required (absence of "Optional" at start of description)
|
|
127
|
+
attribute['required'] = true unless description.start_with?('Optional')
|
|
128
|
+
|
|
129
|
+
# Parse required_value (always "X" or must be <em>X</em>)
|
|
130
|
+
required_value = extract_required_value(description, description_html)
|
|
131
|
+
if required_value
|
|
132
|
+
attribute['required_value'] = required_value
|
|
133
|
+
attribute['default'] = required_value
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Parse size constraints (N-M characters or must be between)
|
|
137
|
+
min_size, max_size = extract_size_constraints(description)
|
|
138
|
+
attribute['min_size'] = min_size if min_size
|
|
139
|
+
attribute['max_size'] = max_size if max_size
|
|
140
|
+
|
|
141
|
+
# Parse default value (Defaults to X)
|
|
142
|
+
# If HTML type is 'True' (not 'Boolean'), it means the field only exists when true
|
|
143
|
+
if raw_type == 'True' && !attribute.key?('default')
|
|
144
|
+
attribute['default'] = true
|
|
145
|
+
elsif !attribute.key?('default')
|
|
146
|
+
default = extract_default_value(description, description_html, attribute['type'])
|
|
147
|
+
attribute['default'] = default unless default.nil?
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Clean up: remove required if false
|
|
151
|
+
attribute.delete('required') unless attribute['required']
|
|
152
|
+
|
|
153
|
+
attribute
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def parse_type_value(type_cell)
|
|
157
|
+
text = type_cell.text.strip
|
|
158
|
+
links = type_cell.css('a')
|
|
159
|
+
|
|
160
|
+
# Check for "Array of X"
|
|
161
|
+
if text.start_with?('Array of')
|
|
162
|
+
items_type = parse_array_items(type_cell, text)
|
|
163
|
+
return { 'type' => 'array', 'items' => items_type }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Check for union type "X or Y"
|
|
167
|
+
if text.include?(' or ')
|
|
168
|
+
types = parse_union_types(type_cell, text)
|
|
169
|
+
return types.length == 1 ? normalize_type(types.first) : types.map { |t| normalize_type(t) }
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Single type
|
|
173
|
+
if links.any?
|
|
174
|
+
normalize_type(links.first.text.strip)
|
|
175
|
+
else
|
|
176
|
+
normalize_type(text)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def parse_array_items(type_cell, text)
|
|
181
|
+
# Handle "Array of Array of X"
|
|
182
|
+
if text.include?('Array of Array of')
|
|
183
|
+
inner_type = type_cell.css('a').last&.text&.strip || text.split('Array of Array of').last.strip
|
|
184
|
+
return { 'type' => 'array', 'items' => normalize_type(inner_type) }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Regular "Array of X"
|
|
188
|
+
link = type_cell.css('a').first
|
|
189
|
+
if link
|
|
190
|
+
normalize_type(link.text.strip)
|
|
191
|
+
else
|
|
192
|
+
# Primitive array like "Array of String"
|
|
193
|
+
items_text = text.sub('Array of ', '').strip
|
|
194
|
+
normalize_type(items_text)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def parse_union_types(type_cell, text)
|
|
199
|
+
links = type_cell.css('a')
|
|
200
|
+
if links.any?
|
|
201
|
+
links.map { |l| l.text.strip }
|
|
202
|
+
else
|
|
203
|
+
text.split(' or ').map(&:strip)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def normalize_type(type)
|
|
208
|
+
PRIMITIVE_TYPES[type] || type
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def extract_required_value(description, description_html)
|
|
212
|
+
# Pattern: always "X" or always "X" (smart quotes)
|
|
213
|
+
match = description.match(/always ["\u201c]([^"\u201d]+)["\u201d]/i)
|
|
214
|
+
return match[1].delete('\\') if match
|
|
215
|
+
|
|
216
|
+
# Pattern: must be <em>X</em> (check inner HTML)
|
|
217
|
+
match = description_html.match(%r{must be <em>([^<]+)</em>}i)
|
|
218
|
+
return match[1] if match
|
|
219
|
+
|
|
220
|
+
nil
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def extract_size_constraints(description)
|
|
224
|
+
min_size = nil
|
|
225
|
+
max_size = nil
|
|
226
|
+
|
|
227
|
+
# Pattern: N-M characters (covers 0-N and 1-N cases)
|
|
228
|
+
if (match = description.match(/(\d+)-(\d+) characters/))
|
|
229
|
+
min_val = match[1].to_i
|
|
230
|
+
max_size = match[2].to_i
|
|
231
|
+
min_size = min_val if min_val.positive?
|
|
232
|
+
# Pattern: must be between N and M
|
|
233
|
+
elsif (match = description.match(/must be between (\d+) and (\d+)/))
|
|
234
|
+
min_size = match[1].to_i
|
|
235
|
+
max_size = match[2].to_i
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
[min_size, max_size]
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def extract_default_value(description, description_html, type)
|
|
242
|
+
# Pattern: Defaults to "X" (with smart quotes U+201C/U+201D)
|
|
243
|
+
if (match = description.match(/Defaults to \u201c([^\u201d]+)\u201d/i))
|
|
244
|
+
return cast_default_value(match[1], type)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Pattern: Defaults to <em>X</em> (check inner HTML for em-wrapped values)
|
|
248
|
+
if (match = description_html.match(%r{Defaults to <em>([^<]+)</em>}i))
|
|
249
|
+
return cast_default_value(match[1], type)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Pattern: Defaults to <number> (plain numeric values)
|
|
253
|
+
if (match = description.match(/Defaults to (\d+)/i))
|
|
254
|
+
return cast_default_value(match[1], type)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
nil
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def cast_default_value(value, type)
|
|
261
|
+
case type
|
|
262
|
+
when 'integer'
|
|
263
|
+
value.to_i
|
|
264
|
+
when 'boolean'
|
|
265
|
+
value.downcase == 'true'
|
|
266
|
+
when 'number'
|
|
267
|
+
value.to_f
|
|
268
|
+
else
|
|
269
|
+
value
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require_relative 'builders/type_builder'
|
|
5
|
+
require_relative 'builders/endpoints_builder'
|
|
6
|
+
|
|
7
|
+
namespace :rebuild do
|
|
8
|
+
desc 'Rebuild types from type_attributes.json'
|
|
9
|
+
task :types do
|
|
10
|
+
types = JSON.parse(File.read("#{__dir__}/../data/types.json"), symbolize_names: true)
|
|
11
|
+
templates_dir = "#{__dir__}/templates"
|
|
12
|
+
|
|
13
|
+
types.each_pair do |name, attributes|
|
|
14
|
+
builder = Builders::TypeBuilder.new(name.to_s, attributes, templates_dir: templates_dir)
|
|
15
|
+
output_path = "#{__dir__}/../lib/telegram/bot/types/#{Builders::TypeBuilder.underscore(name)}.rb"
|
|
16
|
+
|
|
17
|
+
File.write(output_path, builder.build)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc 'Rebuild API endpoints from method_return_types.json'
|
|
22
|
+
task :methods do
|
|
23
|
+
methods = JSON.parse(File.read("#{__dir__}/../data/methods.json"))
|
|
24
|
+
templates_dir = "#{__dir__}/templates"
|
|
25
|
+
|
|
26
|
+
builder = Builders::EndpointsBuilder.new(methods, templates_dir: templates_dir)
|
|
27
|
+
|
|
28
|
+
File.write "#{__dir__}/../lib/telegram/bot/api/endpoints.rb", builder.build
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Telegram
|
|
4
|
+
module Bot
|
|
5
|
+
class Api
|
|
6
|
+
ENDPOINTS = {
|
|
7
|
+
<%- methods.each_with_index do |(name, return_type), index| -%>
|
|
8
|
+
'<%= name %>' => <%= return_type %><%= index == methods.size - 1 ? '' : ',' %>
|
|
9
|
+
<%- end -%>
|
|
10
|
+
}.freeze
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: telegram-bot-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander Tipugin
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: dry-struct
|
|
@@ -66,13 +65,13 @@ dependencies:
|
|
|
66
65
|
- - "~>"
|
|
67
66
|
- !ruby/object:Gem::Version
|
|
68
67
|
version: '2.6'
|
|
69
|
-
description:
|
|
70
68
|
email:
|
|
71
69
|
- atipugin@gmail.com
|
|
72
70
|
executables: []
|
|
73
71
|
extensions: []
|
|
74
72
|
extra_rdoc_files: []
|
|
75
73
|
files:
|
|
74
|
+
- ".claude/skills/update-api/SKILL.md"
|
|
76
75
|
- ".editorconfig"
|
|
77
76
|
- ".env.sample"
|
|
78
77
|
- ".github/workflows/ci.yml"
|
|
@@ -97,6 +96,7 @@ files:
|
|
|
97
96
|
- lib/telegram/bot/exceptions/response_error.rb
|
|
98
97
|
- lib/telegram/bot/null_logger.rb
|
|
99
98
|
- lib/telegram/bot/types.rb
|
|
99
|
+
- lib/telegram/bot/types/accepted_gift_types.rb
|
|
100
100
|
- lib/telegram/bot/types/affiliate_info.rb
|
|
101
101
|
- lib/telegram/bot/types/animation.rb
|
|
102
102
|
- lib/telegram/bot/types/audio.rb
|
|
@@ -123,6 +123,7 @@ files:
|
|
|
123
123
|
- lib/telegram/bot/types/bot_description.rb
|
|
124
124
|
- lib/telegram/bot/types/bot_name.rb
|
|
125
125
|
- lib/telegram/bot/types/bot_short_description.rb
|
|
126
|
+
- lib/telegram/bot/types/business_bot_rights.rb
|
|
126
127
|
- lib/telegram/bot/types/business_connection.rb
|
|
127
128
|
- lib/telegram/bot/types/business_intro.rb
|
|
128
129
|
- lib/telegram/bot/types/business_location.rb
|
|
@@ -154,14 +155,22 @@ files:
|
|
|
154
155
|
- lib/telegram/bot/types/chat_member_owner.rb
|
|
155
156
|
- lib/telegram/bot/types/chat_member_restricted.rb
|
|
156
157
|
- lib/telegram/bot/types/chat_member_updated.rb
|
|
158
|
+
- lib/telegram/bot/types/chat_owner_changed.rb
|
|
159
|
+
- lib/telegram/bot/types/chat_owner_left.rb
|
|
157
160
|
- lib/telegram/bot/types/chat_permissions.rb
|
|
158
161
|
- lib/telegram/bot/types/chat_photo.rb
|
|
159
162
|
- lib/telegram/bot/types/chat_shared.rb
|
|
163
|
+
- lib/telegram/bot/types/checklist.rb
|
|
164
|
+
- lib/telegram/bot/types/checklist_task.rb
|
|
165
|
+
- lib/telegram/bot/types/checklist_tasks_added.rb
|
|
166
|
+
- lib/telegram/bot/types/checklist_tasks_done.rb
|
|
160
167
|
- lib/telegram/bot/types/chosen_inline_result.rb
|
|
161
168
|
- lib/telegram/bot/types/compactable.rb
|
|
162
169
|
- lib/telegram/bot/types/contact.rb
|
|
163
170
|
- lib/telegram/bot/types/copy_text_button.rb
|
|
164
171
|
- lib/telegram/bot/types/dice.rb
|
|
172
|
+
- lib/telegram/bot/types/direct_message_price_changed.rb
|
|
173
|
+
- lib/telegram/bot/types/direct_messages_topic.rb
|
|
165
174
|
- lib/telegram/bot/types/document.rb
|
|
166
175
|
- lib/telegram/bot/types/encrypted_credentials.rb
|
|
167
176
|
- lib/telegram/bot/types/encrypted_passport_element.rb
|
|
@@ -179,6 +188,8 @@ files:
|
|
|
179
188
|
- lib/telegram/bot/types/general_forum_topic_hidden.rb
|
|
180
189
|
- lib/telegram/bot/types/general_forum_topic_unhidden.rb
|
|
181
190
|
- lib/telegram/bot/types/gift.rb
|
|
191
|
+
- lib/telegram/bot/types/gift_background.rb
|
|
192
|
+
- lib/telegram/bot/types/gift_info.rb
|
|
182
193
|
- lib/telegram/bot/types/gifts.rb
|
|
183
194
|
- lib/telegram/bot/types/giveaway.rb
|
|
184
195
|
- lib/telegram/bot/types/giveaway_completed.rb
|
|
@@ -210,7 +221,10 @@ files:
|
|
|
210
221
|
- lib/telegram/bot/types/inline_query_result_video.rb
|
|
211
222
|
- lib/telegram/bot/types/inline_query_result_voice.rb
|
|
212
223
|
- lib/telegram/bot/types/inline_query_results_button.rb
|
|
224
|
+
- lib/telegram/bot/types/input_checklist.rb
|
|
225
|
+
- lib/telegram/bot/types/input_checklist_task.rb
|
|
213
226
|
- lib/telegram/bot/types/input_contact_message_content.rb
|
|
227
|
+
- lib/telegram/bot/types/input_file.rb
|
|
214
228
|
- lib/telegram/bot/types/input_invoice_message_content.rb
|
|
215
229
|
- lib/telegram/bot/types/input_location_message_content.rb
|
|
216
230
|
- lib/telegram/bot/types/input_media.rb
|
|
@@ -224,7 +238,13 @@ files:
|
|
|
224
238
|
- lib/telegram/bot/types/input_paid_media_photo.rb
|
|
225
239
|
- lib/telegram/bot/types/input_paid_media_video.rb
|
|
226
240
|
- lib/telegram/bot/types/input_poll_option.rb
|
|
241
|
+
- lib/telegram/bot/types/input_profile_photo.rb
|
|
242
|
+
- lib/telegram/bot/types/input_profile_photo_animated.rb
|
|
243
|
+
- lib/telegram/bot/types/input_profile_photo_static.rb
|
|
227
244
|
- lib/telegram/bot/types/input_sticker.rb
|
|
245
|
+
- lib/telegram/bot/types/input_story_content.rb
|
|
246
|
+
- lib/telegram/bot/types/input_story_content_photo.rb
|
|
247
|
+
- lib/telegram/bot/types/input_story_content_video.rb
|
|
228
248
|
- lib/telegram/bot/types/input_text_message_content.rb
|
|
229
249
|
- lib/telegram/bot/types/input_venue_message_content.rb
|
|
230
250
|
- lib/telegram/bot/types/invoice.rb
|
|
@@ -235,6 +255,7 @@ files:
|
|
|
235
255
|
- lib/telegram/bot/types/labeled_price.rb
|
|
236
256
|
- lib/telegram/bot/types/link_preview_options.rb
|
|
237
257
|
- lib/telegram/bot/types/location.rb
|
|
258
|
+
- lib/telegram/bot/types/location_address.rb
|
|
238
259
|
- lib/telegram/bot/types/login_url.rb
|
|
239
260
|
- lib/telegram/bot/types/mask_position.rb
|
|
240
261
|
- lib/telegram/bot/types/maybe_inaccessible_message.rb
|
|
@@ -254,12 +275,17 @@ files:
|
|
|
254
275
|
- lib/telegram/bot/types/message_reaction_count_updated.rb
|
|
255
276
|
- lib/telegram/bot/types/message_reaction_updated.rb
|
|
256
277
|
- lib/telegram/bot/types/order_info.rb
|
|
278
|
+
- lib/telegram/bot/types/owned_gift.rb
|
|
279
|
+
- lib/telegram/bot/types/owned_gift_regular.rb
|
|
280
|
+
- lib/telegram/bot/types/owned_gift_unique.rb
|
|
281
|
+
- lib/telegram/bot/types/owned_gifts.rb
|
|
257
282
|
- lib/telegram/bot/types/paid_media.rb
|
|
258
283
|
- lib/telegram/bot/types/paid_media_info.rb
|
|
259
284
|
- lib/telegram/bot/types/paid_media_photo.rb
|
|
260
285
|
- lib/telegram/bot/types/paid_media_preview.rb
|
|
261
286
|
- lib/telegram/bot/types/paid_media_purchased.rb
|
|
262
287
|
- lib/telegram/bot/types/paid_media_video.rb
|
|
288
|
+
- lib/telegram/bot/types/paid_message_price_changed.rb
|
|
263
289
|
- lib/telegram/bot/types/passport_data.rb
|
|
264
290
|
- lib/telegram/bot/types/passport_element_error.rb
|
|
265
291
|
- lib/telegram/bot/types/passport_element_error_data_field.rb
|
|
@@ -299,12 +325,29 @@ files:
|
|
|
299
325
|
- lib/telegram/bot/types/shipping_address.rb
|
|
300
326
|
- lib/telegram/bot/types/shipping_option.rb
|
|
301
327
|
- lib/telegram/bot/types/shipping_query.rb
|
|
328
|
+
- lib/telegram/bot/types/star_amount.rb
|
|
302
329
|
- lib/telegram/bot/types/star_transaction.rb
|
|
303
330
|
- lib/telegram/bot/types/star_transactions.rb
|
|
304
331
|
- lib/telegram/bot/types/sticker.rb
|
|
305
332
|
- lib/telegram/bot/types/sticker_set.rb
|
|
306
333
|
- lib/telegram/bot/types/story.rb
|
|
334
|
+
- lib/telegram/bot/types/story_area.rb
|
|
335
|
+
- lib/telegram/bot/types/story_area_position.rb
|
|
336
|
+
- lib/telegram/bot/types/story_area_type.rb
|
|
337
|
+
- lib/telegram/bot/types/story_area_type_link.rb
|
|
338
|
+
- lib/telegram/bot/types/story_area_type_location.rb
|
|
339
|
+
- lib/telegram/bot/types/story_area_type_suggested_reaction.rb
|
|
340
|
+
- lib/telegram/bot/types/story_area_type_unique_gift.rb
|
|
341
|
+
- lib/telegram/bot/types/story_area_type_weather.rb
|
|
307
342
|
- lib/telegram/bot/types/successful_payment.rb
|
|
343
|
+
- lib/telegram/bot/types/suggested_post_approval_failed.rb
|
|
344
|
+
- lib/telegram/bot/types/suggested_post_approved.rb
|
|
345
|
+
- lib/telegram/bot/types/suggested_post_declined.rb
|
|
346
|
+
- lib/telegram/bot/types/suggested_post_info.rb
|
|
347
|
+
- lib/telegram/bot/types/suggested_post_paid.rb
|
|
348
|
+
- lib/telegram/bot/types/suggested_post_parameters.rb
|
|
349
|
+
- lib/telegram/bot/types/suggested_post_price.rb
|
|
350
|
+
- lib/telegram/bot/types/suggested_post_refunded.rb
|
|
308
351
|
- lib/telegram/bot/types/switch_inline_query_chosen_chat.rb
|
|
309
352
|
- lib/telegram/bot/types/text_quote.rb
|
|
310
353
|
- lib/telegram/bot/types/transaction_partner.rb
|
|
@@ -315,10 +358,19 @@ files:
|
|
|
315
358
|
- lib/telegram/bot/types/transaction_partner_telegram_ads.rb
|
|
316
359
|
- lib/telegram/bot/types/transaction_partner_telegram_api.rb
|
|
317
360
|
- lib/telegram/bot/types/transaction_partner_user.rb
|
|
361
|
+
- lib/telegram/bot/types/unique_gift.rb
|
|
362
|
+
- lib/telegram/bot/types/unique_gift_backdrop.rb
|
|
363
|
+
- lib/telegram/bot/types/unique_gift_backdrop_colors.rb
|
|
364
|
+
- lib/telegram/bot/types/unique_gift_colors.rb
|
|
365
|
+
- lib/telegram/bot/types/unique_gift_info.rb
|
|
366
|
+
- lib/telegram/bot/types/unique_gift_model.rb
|
|
367
|
+
- lib/telegram/bot/types/unique_gift_symbol.rb
|
|
318
368
|
- lib/telegram/bot/types/update.rb
|
|
319
369
|
- lib/telegram/bot/types/user.rb
|
|
320
370
|
- lib/telegram/bot/types/user_chat_boosts.rb
|
|
371
|
+
- lib/telegram/bot/types/user_profile_audios.rb
|
|
321
372
|
- lib/telegram/bot/types/user_profile_photos.rb
|
|
373
|
+
- lib/telegram/bot/types/user_rating.rb
|
|
322
374
|
- lib/telegram/bot/types/users_shared.rb
|
|
323
375
|
- lib/telegram/bot/types/venue.rb
|
|
324
376
|
- lib/telegram/bot/types/video.rb
|
|
@@ -327,22 +379,27 @@ files:
|
|
|
327
379
|
- lib/telegram/bot/types/video_chat_scheduled.rb
|
|
328
380
|
- lib/telegram/bot/types/video_chat_started.rb
|
|
329
381
|
- lib/telegram/bot/types/video_note.rb
|
|
382
|
+
- lib/telegram/bot/types/video_quality.rb
|
|
330
383
|
- lib/telegram/bot/types/voice.rb
|
|
331
384
|
- lib/telegram/bot/types/web_app_data.rb
|
|
332
385
|
- lib/telegram/bot/types/web_app_info.rb
|
|
333
386
|
- lib/telegram/bot/types/webhook_info.rb
|
|
334
387
|
- lib/telegram/bot/types/write_access_allowed.rb
|
|
335
388
|
- lib/telegram/bot/version.rb
|
|
336
|
-
- rakelib/
|
|
337
|
-
- rakelib/
|
|
389
|
+
- rakelib/builders/endpoints_builder.rb
|
|
390
|
+
- rakelib/builders/type_builder.rb
|
|
391
|
+
- rakelib/parse.rake
|
|
392
|
+
- rakelib/parsers/methods_parser.rb
|
|
393
|
+
- rakelib/parsers/types_parser.rb
|
|
394
|
+
- rakelib/rebuild.rake
|
|
338
395
|
- rakelib/templates/empty_type.erb
|
|
396
|
+
- rakelib/templates/endpoints.erb
|
|
339
397
|
- rakelib/templates/type.erb
|
|
340
398
|
- telegram-bot-ruby.gemspec
|
|
341
399
|
homepage: https://github.com/atipugin/telegram-bot
|
|
342
400
|
licenses: []
|
|
343
401
|
metadata:
|
|
344
402
|
rubygems_mfa_required: 'true'
|
|
345
|
-
post_install_message:
|
|
346
403
|
rdoc_options: []
|
|
347
404
|
require_paths:
|
|
348
405
|
- lib
|
|
@@ -357,8 +414,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
357
414
|
- !ruby/object:Gem::Version
|
|
358
415
|
version: '0'
|
|
359
416
|
requirements: []
|
|
360
|
-
rubygems_version: 3.
|
|
361
|
-
signing_key:
|
|
417
|
+
rubygems_version: 3.6.9
|
|
362
418
|
specification_version: 4
|
|
363
419
|
summary: Ruby wrapper for Telegram's Bot API
|
|
364
420
|
test_files: []
|