rubymagentosavonmagento-soap-api

How do I correctly call Magento SOAP API with Ruby Savon for Category Product Links?


I am trying to call the catalog_product_link.list API method using Savon. However, I keep receiving the error Error cannot find parameter.

Here is what I am using, though I have tried several variations of the call and still cannot get it to go through correctly:

client = Savon.client(wsdl: 'http://localhost/index.php/api/soap/?wsdl')
response = client.call(:login){message(username: 'user', apiKey: 'key')}
session = response.body[:login_response][:login_return]

#These all do not work
client.call(:call){message(:session => session, :method => 'catalog_product_link.list', :type => 'up_sell', :productId => '166')}
client.call(:call){message(:session => session, :method => 'catalog_product_link.list', :type => 'up_sell', :product => '166')}
client.call(:call){message(:sessionId => session, :resourcePath => 'catalog_product_link.list', :args => {:type => 'up_sell', :product => '166'})}
client.call(:call){message(:sessionId => session, :resourcePath => 'catalog_product_link.list', :args => {:type => 'up_sell', :productId => '166'})}
client.call(:call){message(:sessionId => session, :resourcePath => 'catalog_product_link.list', :arguments => {:type => 'up_sell', :product => '166'})}

Is there a different way to format to get this to work?

UPDATE: If I try removing the type parameter, it gives the error Given invalid link type, so it appears it does not like something about multiple parameters.

response = client.call(:call){message(:session => session, :method => 'catalog_product_link.list', :product => '166')}

Solution

  • I was able to get this to work using Builder:

    class ServiceRequest
      def initialize(session, type, product)
        @session = session
        @type = type
        @product = product
      end
    
      def to_s
        builder = Builder::XmlMarkup.new()
        builder.instruct!(:xml, encoding: "UTF-8")
    
        builder.tag!(
          "env:Envelope",
          "xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/",
          "xmlns:ns1" => "urn:Magento",
          "xmlns:ns2" => "http://xml.apache.org/xml-soap",
          "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", 
          "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
        ) do |envelope|
          envelope.tag!("env:Body") do |body|
            body.tag!("ns1:call") do |call|
              builder.sessionId(@session, "xsi:type" => "xsd:string")
              builder.resourcePath("catalog_product_link.list", "xsi:type" => "xsd:string")
              builder.args("xsi:type" => "ns2:Map") do |args|
                args.item do |item|
                  item.key("type", "xsi:type" => "xsd:string")
                  item.value(@type, "xsi:type" => "xsd:string")
                end
                args.item do |item|
                  item.key("product", "xsi:type" => "xsd:string")
                  item.value(@product, "xsi:type" => "xsd:string")
                end
              end
            end
          end
        end
    
        builder.target!
      end
    end
    
    client.call(:call, xml: ServiceRequest.new(session, 'up_sell', '166').to_s)
    

    Thanks to @rubiii for the direction.