Skip to content

Instantly share code, notes, and snippets.

@AnDyro751
Created December 5, 2025 20:26
Show Gist options
  • Select an option

  • Save AnDyro751/b29681dcbcf7dae5199e7916fbe52668 to your computer and use it in GitHub Desktop.

Select an option

Save AnDyro751/b29681dcbcf7dae5199e7916fbe52668 to your computer and use it in GitHub Desktop.
require "net/http"
require "json"
require "uri"
# Cliente HTTP genérico, reutilizable para cualquier API REST
class HttpClient
class RequestError < StandardError; end
def initialize(open_timeout: 5, read_timeout: 10, logger: nil)
@open_timeout = open_timeout
@read_timeout = read_timeout
@logger = logger # Opcional: un callable para loggear las peticiones, actualmente es puts pero si se necesita cambiar a logger tipo Rails.logger, pues se cambia y ya
end
# Hace un GET y regresa el response crudo
def get(uri, headers = {})
uri = URI(uri) unless uri.is_a?(URI)
log("GET #{uri}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true # Siempre se usa SSL, sino da error 400 -> EasyBroker API error: Request failed with code 400
request = Net::HTTP::Get.new(uri)
headers.each { |key, value| request[key] = value }
http.request(request)
end
# Hace un GET y te regresa el JSON ya parseado
def get_json(uri, headers = {})
response = get(uri, headers)
unless response.code.to_i.between?(200, 299)
raise RequestError, "Request failed with code #{response.code}"
end
JSON.parse(response.body)
rescue JSON::ParserError => e
raise RequestError, "Invalid JSON response: #{e.message}"
end
private
def log(message)
@logger&.call(message)
end
end
# Cliente específico para EB
# Se puede inyectar otro http_client si se quiere usar otra lib (HTTParty, etc), (dejo un ejemplo en el gist)
class EasyBrokerClient
API_BASE_URL = ENV.fetch("EASYBROKER_API_BASE_URL") { "https://api.stagingeb.com/v1" }
DEFAULT_PAGE_SIZE = 20
def initialize(api_key:, page_size: DEFAULT_PAGE_SIZE, base_url: API_BASE_URL, http_client: nil, logger: nil)
raise ArgumentError, "api_key is required" if api_key&.to_s&.strip&.empty?
@api_key = api_key
@page_size = page_size
@base_url = base_url.chomp("/")
@http_client = http_client || HttpClient.new(logger: logger)
end
# Trae todas las propiedades iterando por las páginas
# Por cada pagina se hace un log de las propiedades
def fetch_all_properties
page_ref = 1
properties = []
loop do
payload = fetch_properties_page(page_ref)
properties.concat(payload.fetch("content", []))
yield payload if block_given? # Se puede hacer lo que se quiera con el payload por si se necesita, util para imprimir los datos o hacer algo con ellos
next_page = payload.dig("pagination", "next_page")
break unless next_page # Si no hay next_page, ya terminamos
# next_page puede ser número o URL completa, lo normalizamos
page_ref = next_page.is_a?(String) && next_page.start_with?("http") ? URI(next_page) : next_page
end
properties
end
private
attr_reader :api_key, :page_size, :base_url, :http_client
# Trae una página de propiedade
def fetch_properties_page(page_or_uri)
uri = page_or_uri.is_a?(URI) ? page_or_uri : build_uri("/properties", page: page_or_uri, limit: page_size)
http_client.get_json(uri, default_headers)
rescue HttpClient::RequestError => e
raise HttpClient::RequestError, "EasyBroker API error: #{e.message}"
end
def build_uri(path, params)
uri = URI("#{base_url}#{path}")
uri.query = URI.encode_www_form(params)
uri
end
# Headers que pide EB
def default_headers
{ "X-Authorization" => api_key, "accept" => "application/json" }
end
end
if __FILE__ == $PROGRAM_NAME
api_key = ENV.fetch("EASYBROKER_API_KEY") { "l7u502p8v46ba3ppgvj5y2aad50lb9" }
logger = ->(msg) { puts msg }
begin
client = EasyBrokerClient.new(api_key: api_key, logger: logger)
client.fetch_all_properties do |payload|
# Imprimimos los titles
payload.fetch("content", []).each do |property|
puts property["title"] if property["title"]
end
end
rescue HttpClient::RequestError => e
puts "--------------------------------"
puts "e: #{e.message}"
puts "--------------------------------"
exit 1
rescue StandardError => e
puts "--------------------------------"
puts "e: #{e.message}"
puts "--------------------------------"
exit 1
end
end
class HttpPartyClient
def get_json(uri, headers = {})
response = HTTParty.get(uri.to_s, headers: headers)
raise "Request failed" unless response.success?
response.parsed_response
end
end
client = EasyBrokerClient.new(api_key: "api_key", http_client: HttpPartyClient.new)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment