module MeApi class Client < Ac::Base BASE_URL = "https://melhorenvio.com.br" SAVE_RESPONSES = true Rate = Data.define(:id, :from, :to, :price, :min_delivery_time, :max_delivery_time, :service_name, :carrier_name, :carrier_logo_url) attr_reader :default_height, :default_width, :default_length def initialize(access_token = nil, default_height: 24, default_width: 16, default_length: 10) @default_height = default_height @default_width = default_width @default_length = default_length super access_token end def rates(from:, to:, weight_kg:, contents_value_brl:, height_cm: default_height, width_cm: default_width, length_cm: default_length) body = { "from" => { "postal_code" => from }, "to" => { "postal_code" => to }, "package" => { "weight" => weight_kg, "height" => height_cm, "width" => width_cm, "length" => length_cm }, "options" => { "insurance_value" => contents_value_brl, "receipt" => false, "own_hand" => false }, "services" => "1,2,3,4,17,33" } response = post("api/v2/me/shipment/calculate", body: JSON.dump(body)) { |response| validate_response(response, [0, "id"]) } response.json.map do |rate| Rate.new( id: rate["id"], from: from, to: to, price: rate["price"].to_f, min_delivery_time: rate.dig("delivery_range", "min"), max_delivery_time: rate.dig("delivery_range", "max"), service_name: rate["name"], carrier_name: rate["company"]["name"], carrier_logo_url: rate["company"]["picture"] ) end end def refresh_token(client_id:, client_secret:, refresh_token:) body = { grant_type: "refresh_token", client_id: client_id, client_secret: client_secret, refresh_token: refresh_token } post("/oauth/token", body: JSON.dump(body), headers: {"Content-Type": "application/json"}) { |response| validate_response(response, "access_token") } end def authorize client_id:, client_secret:, code:, redirect_url: body = { grant_type: "authorization_code", client_id: client_id, client_secret: client_secret, code: code, redirect_uri: redirect_url } post("/oauth/token", body: JSON.dump(body), headers: {"Content-Type": "application/json"}) { |response| validate_response(response, "access_token") } end private def validate_response(response, required_response_key) puts response.json unless response.success? ![500, 429].include?(response.code) || response.json.dig(*required_response_key) end end end