-
Notifications
You must be signed in to change notification settings - Fork 118
/
client.rb
85 lines (70 loc) · 2.71 KB
/
client.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# frozen_string_literal: true
require 'active_support/core_ext/hash/keys'
require 'httpclient'
module Telegram
module Bot
class Client
SERVER = 'https://api.telegram.org'
URL_TEMPLATE = '%<server>s/bot%<token>s/'
autoload :RequestBodyFormatter, 'telegram/bot/client/request_body_formatter'
autoload :TypedResponse, 'telegram/bot/client/typed_response'
prepend Async
include DebugClient
require 'telegram/bot/client/api_helper'
include ApiHelper
class << self
# Accepts different options to initialize bot.
def wrap(input, **options)
case input
when Symbol then by_id(input) or raise "#{name} #{input.inspect} not configured"
when self then input
when Hash then new(**input.symbolize_keys, **options)
else new(input, **options)
end
end
def by_id(id)
Telegram.bots[id]
end
# Prepend TypedResponse module.
def typed_response!
prepend TypedResponse
end
def prepare_async_args(action, body = {})
[action.to_s, Async.prepare_hash(RequestBodyFormatter.format(body, action))]
end
def error_for_response(response)
result = JSON.parse(response.body) rescue nil # rubocop:disable Style/RescueModifier
return Error.new(response.reason) unless result
message = result['description'] || '-'
# This errors are raised only for valid responses from Telegram
case response.status
when 403 then Forbidden.new(message)
when 404 then NotFound.new(message)
else Error.new("#{response.reason}: #{message}")
end
end
end
attr_reader :client, :token, :username, :base_uri
def initialize(token = nil, username = nil, server: SERVER, **options)
@client = HTTPClient.new
@token = token || options[:token]
@username = username || options[:username]
@base_uri = format(URL_TEMPLATE, server: server, token: self.token)
end
def request(action, body = {})
response = http_request("#{base_uri}#{action}", RequestBodyFormatter.format(body, action))
raise self.class.error_for_response(response) if response.status >= 300
JSON.parse(response.body)
end
# Endpoint for low-level request. For easy host highjacking & instrumentation.
# Params are not used directly but kept for instrumentation purpose.
# You probably don't want to use this method directly.
def http_request(uri, body)
client.post(uri, body)
end
def inspect
"#<#{self.class.name}##{object_id}(#{@username})>"
end
end
end
end