1
0
зеркало из https://github.com/glebtv/telegram-bot.git synced 2026-09-03 17:55:52 +03:00

Fix sending File objects in nested objects in sendMediaGroup

Этот коммит содержится в:
Max Melentiev
2021-09-08 20:05:31 +01:00
родитель 2d73d1c879
Коммит 5b9706ed47
5 изменённых файлов: 115 добавлений и 30 удалений

Просмотреть файл

@@ -1,5 +1,4 @@
require 'active_support/core_ext/hash/keys'
require 'json'
require 'httpclient'
module Telegram
@@ -8,7 +7,9 @@ module Telegram
SERVER = 'https://api.telegram.org'.freeze
URL_TEMPLATE = '%<server>s/bot%<token>s/'.freeze
autoload :RequestBodyFormatter, 'telegram/bot/client/request_body_formatter'
autoload :TypedResponse, 'telegram/bot/client/typed_response'
prepend Async
include DebugClient
@@ -35,16 +36,8 @@ module Telegram
prepend TypedResponse
end
# Encodes nested hashes as json.
def prepare_body(body)
body = body.dup
body.each do |k, val|
body[k] = val.to_json if val.is_a?(Hash) || val.is_a?(Array)
end
end
def prepare_async_args(action, body = {})
[action.to_s, Async.prepare_hash(prepare_body(body))]
[action.to_s, Async.prepare_hash(RequestBodyFormatter.format(body))]
end
def error_for_response(response)
@@ -70,7 +63,7 @@ module Telegram
end
def request(action, body = {})
response = http_request("#{base_uri}#{action}", self.class.prepare_body(body))
response = http_request("#{base_uri}#{action}", RequestBodyFormatter.format(body))
raise self.class.error_for_response(response) if response.status >= 300
JSON.parse(response.body)
end

Просмотреть файл

@@ -0,0 +1,48 @@
require 'json'
module Telegram
module Bot
class Client
# Encodes nested hashes and arrays as json and extract File objects from them
# to the top level. Top-level File objects are handled by httpclient.
# More details: https://core.telegram.org/bots/api#sending-files
module RequestBodyFormatter
extend self
def format(body, action)
body = body.dup
if action.to_s == 'sendMediaGroup'
body = extract_files_from_array!(body, :media)
end
body.each do |key, val|
body[key] = val.to_json if val.is_a?(Hash) || val.is_a?(Array)
end
end
private
def extract_files_from_array!(body, field_name)
field_name = [field_name.to_sym, field_name.to_s].find { |x| body.key?(x) }
return body unless field_name && body[field_name].is_a?(Array)
files = {}
body[field_name] = body[field_name].map { |x| extract_files_from_hash(x, files) }
body.merge!(files)
end
# Replace File objects with `attach` URIs. File objects are added into `files` hash.
def extract_files_from_hash(hash, files)
return hash unless hash.is_a?(Hash)
hash.transform_values do |value|
if value.is_a?(File)
arg_name = "_file#{files.size}"
files[arg_name] = value
"attach://#{arg_name}"
else
value
end
end
end
end
end
end
end