telegem 2.0.0 → 2.0.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/lib/api/client.rb +9 -26
- data/lib/telegem.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac41d0622154fd92c57bbd5b86a6d5209914233e1be586180f399912d093f0ea
|
|
4
|
+
data.tar.gz: 6225d0dd673a63b03d595a58c4260f462c12ac63715338bc8c95413ed69b9e86
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f1aa5e8fc79c6198afe4a5c47fdd53b3c947b4fd48c8cb3ec6f96bc3320201d152645c00ab63a0568fb242e95106455bd95b904e57adf26c682a00b44a971c3
|
|
7
|
+
data.tar.gz: 4355cd40167abbe6593a65fe2e736190a16aefde8b541b8cd679950a9cd10e5d764c9a72de328cce4f3439694875cf29e54d077169a5a47406a88cab3dae384d
|
data/lib/api/client.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# lib/api/client.rb - V2.0.0 (
|
|
1
|
+
# lib/api/client.rb - V2.0.0 (FIXED)
|
|
2
2
|
require 'httpx'
|
|
3
3
|
require 'json'
|
|
4
4
|
|
|
@@ -9,11 +9,12 @@ module Telegem
|
|
|
9
9
|
|
|
10
10
|
attr_reader :token, :logger, :http, :connection_pool
|
|
11
11
|
|
|
12
|
-
def initialize(token,
|
|
12
|
+
def initialize(token, **options)
|
|
13
13
|
@token = token
|
|
14
|
-
@logger = logger || Logger.new($stdout)
|
|
14
|
+
@logger = options[:logger] || Logger.new($stdout)
|
|
15
|
+
timeout = options[:timeout] || 30
|
|
16
|
+
pool_size = options[:pool_size] || 10
|
|
15
17
|
|
|
16
|
-
# HTTPX with proper async configuration
|
|
17
18
|
@http = HTTPX.plugin(:persistent)
|
|
18
19
|
.with(
|
|
19
20
|
timeout: {
|
|
@@ -26,60 +27,49 @@ module Telegem
|
|
|
26
27
|
'Content-Type' => 'application/json',
|
|
27
28
|
'User-Agent' => "Telegem/#{Telegem::VERSION} (Ruby #{RUBY_VERSION}; #{RUBY_PLATFORM})"
|
|
28
29
|
},
|
|
29
|
-
max_requests: pool_size
|
|
30
|
+
max_requests: pool_size
|
|
30
31
|
)
|
|
31
32
|
|
|
32
|
-
# Add retry plugin if available
|
|
33
33
|
if HTTPX.plugins.key?(:retries)
|
|
34
34
|
@http = @http.plugin(:retries, max_retries: 3, retry_on: [500, 502, 503, 504])
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
# Ensure proper cleanup
|
|
38
37
|
ObjectSpace.define_finalizer(self, proc { close })
|
|
39
38
|
end
|
|
40
39
|
|
|
41
|
-
# PRIMARY API: Async call - returns HTTPX request (promise-like)
|
|
42
40
|
def call(method, params = {})
|
|
43
41
|
url = "#{BASE_URL}/bot#{@token}/#{method}"
|
|
44
42
|
|
|
45
43
|
@logger.debug("🚀 Async API: #{method}") if @logger
|
|
46
44
|
|
|
47
|
-
# Pure async - returns immediately
|
|
48
45
|
@http.post(url, json: params.compact)
|
|
49
46
|
.then(&method(:handle_response_async))
|
|
50
47
|
.on_error(&method(:handle_error_async))
|
|
51
48
|
end
|
|
52
49
|
|
|
53
|
-
# SYNC WRAPPER: For when you absolutely need blocking
|
|
54
50
|
def call!(method, params = {}, timeout: nil)
|
|
55
51
|
timeout ||= @http.options.timeout[:read_timeout]
|
|
56
52
|
|
|
57
|
-
# Start async request
|
|
58
53
|
request = call(method, params)
|
|
59
54
|
|
|
60
|
-
# Wait with timeout
|
|
61
55
|
begin
|
|
62
56
|
wait_result = request.wait(timeout)
|
|
63
57
|
|
|
64
58
|
if request.error
|
|
65
|
-
# Error already logged by handle_error_async
|
|
66
59
|
raise APIError, request.error.message
|
|
67
60
|
elsif !wait_result
|
|
68
61
|
raise NetworkError, "Request timeout after #{timeout}s"
|
|
69
62
|
end
|
|
70
63
|
|
|
71
|
-
# Return the actual result (not the request object)
|
|
72
64
|
request.instance_variable_get(:@result) || request.response
|
|
73
65
|
rescue Timeout::Error
|
|
74
66
|
raise NetworkError, "Request timeout after #{timeout}s"
|
|
75
67
|
end
|
|
76
68
|
end
|
|
77
69
|
|
|
78
|
-
# File upload - also async
|
|
79
70
|
def upload(method, params)
|
|
80
71
|
url = "#{BASE_URL}/bot#{@token}/#{method}"
|
|
81
72
|
|
|
82
|
-
# Build multipart form
|
|
83
73
|
form = build_multipart_form(params)
|
|
84
74
|
|
|
85
75
|
@logger.debug("📤 Async Upload: #{method}") if @logger
|
|
@@ -89,7 +79,6 @@ module Telegem
|
|
|
89
79
|
.on_error(&method(:handle_error_async))
|
|
90
80
|
end
|
|
91
81
|
|
|
92
|
-
# Convenience method for getUpdates with proper async handling
|
|
93
82
|
def get_updates(offset: nil, timeout: 30, limit: 100, allowed_updates: nil)
|
|
94
83
|
params = { timeout: timeout, limit: limit }
|
|
95
84
|
params[:offset] = offset if offset
|
|
@@ -98,19 +87,17 @@ module Telegem
|
|
|
98
87
|
call('getUpdates', params)
|
|
99
88
|
end
|
|
100
89
|
|
|
101
|
-
# Close connections gracefully
|
|
102
90
|
def close
|
|
103
91
|
@http.close
|
|
104
92
|
end
|
|
105
93
|
|
|
106
94
|
private
|
|
107
95
|
|
|
108
|
-
# Async response handler - stores result on request object
|
|
109
96
|
def handle_response_async(response)
|
|
110
97
|
response.raise_for_status unless response.status == 200
|
|
111
98
|
|
|
112
99
|
case response.status
|
|
113
|
-
when 429
|
|
100
|
+
when 429
|
|
114
101
|
retry_after = response.headers['retry-after']&.to_i || 1
|
|
115
102
|
raise RateLimitError.new("Rate limited", retry_after)
|
|
116
103
|
when 200
|
|
@@ -125,7 +112,6 @@ module Telegem
|
|
|
125
112
|
end
|
|
126
113
|
|
|
127
114
|
if json['ok']
|
|
128
|
-
# Store result on request for sync access
|
|
129
115
|
response.request.instance_variable_set(:@result, json['result'])
|
|
130
116
|
json['result']
|
|
131
117
|
else
|
|
@@ -136,7 +122,6 @@ module Telegem
|
|
|
136
122
|
end
|
|
137
123
|
end
|
|
138
124
|
|
|
139
|
-
# Async error handler
|
|
140
125
|
def handle_error_async(error)
|
|
141
126
|
case error
|
|
142
127
|
when HTTPX::TimeoutError
|
|
@@ -150,7 +135,7 @@ module Telegem
|
|
|
150
135
|
raise APIError, "HTTP #{error.response.status}: #{error.message}"
|
|
151
136
|
when RateLimitError
|
|
152
137
|
@logger.error("🚦 Rate limit: retry after #{error.retry_after}s") if @logger
|
|
153
|
-
raise error
|
|
138
|
+
raise error
|
|
154
139
|
else
|
|
155
140
|
@logger.error("💥 Unexpected: #{error.class}: #{error.message}") if @logger
|
|
156
141
|
raise APIError, error.message
|
|
@@ -174,9 +159,8 @@ module Telegem
|
|
|
174
159
|
when Pathname
|
|
175
160
|
obj.exist? && obj.readable?
|
|
176
161
|
when String
|
|
177
|
-
# Check if it's a local file (not URL)
|
|
178
162
|
if obj.start_with?('http://', 'https://', 'ftp://')
|
|
179
|
-
false
|
|
163
|
+
false
|
|
180
164
|
else
|
|
181
165
|
File.exist?(obj) && File.readable?(obj)
|
|
182
166
|
end
|
|
@@ -186,7 +170,6 @@ module Telegem
|
|
|
186
170
|
end
|
|
187
171
|
end
|
|
188
172
|
|
|
189
|
-
# Custom Errors
|
|
190
173
|
class APIError < StandardError
|
|
191
174
|
attr_reader :code
|
|
192
175
|
|
data/lib/telegem.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: telegem
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- sick_phantom
|
|
@@ -198,7 +198,7 @@ metadata:
|
|
|
198
198
|
bug_tracker_uri: https://gitlab.com/ruby-telegem/telegem/-/issues
|
|
199
199
|
documentation_uri: https://gitlab.com/ruby-telegem/telegem/-/blob/main/README.md
|
|
200
200
|
rubygems_mfa_required: 'false'
|
|
201
|
-
post_install_message: "Thanks for installing Telegem 2.0.
|
|
201
|
+
post_install_message: "Thanks for installing Telegem 2.0.1!\n\nQuick start:\n bot
|
|
202
202
|
= Telegem.new(\"YOUR_TOKEN\")\n bot.on(:message) { |ctx| ctx.reply(\"Hello!\")
|
|
203
203
|
}\n bot.start_polling\n\nDocumentation: https://gitlab.com/ruby-telegem/telegem\nHappy
|
|
204
204
|
bot building! \U0001F916\n"
|