Have your say in Community Polls: What was/is your greatest motivation to start your own business?
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Ruby private app access to Shopify Resources

Ruby private app access to Shopify Resources

fwallace
Shopify Partner
45 1 4

You want a private app, simple REST Shopify script in Ruby using the latest shopify_api gem to download resources like orders, customers, products etc. [Maybe to store in a Database, do something with them].

 

After much trial/error and reading the official docs on Rubydoc.info, here is what works for me:

 

def get_orders
        puts "Starting ..."

        ShopifyAPI::Context.setup(
            api_key: "DUMMY",
            api_secret_key: @app_token,
            scope: "DUMMY",
            host_name: "DUMMY",
            private_shop: "#{@shopname}.myshopify.com",
            #session_storage: ShopifyAPI::Auth::FileSessionStorage.new,
            #session_storage: CustomSessionStorage.new,
            is_embedded: false, 
            is_private: true, 
            api_version: "2023-07"
        
        )

        

        session = ShopifyAPI::Auth::Session.new(shop: "#{@shopname}.myshopify.com", access_token: @app_token)

        puts session.inspect

        client = ShopifyAPI::Clients::Rest::Admin.new(session: session)

        


        

        response = client.get(path: "orders", query: { created_at_min: '2023-05-01T00:59:59-08:00', created_at_max: '2023-07-18T23:59:59-08:00', status: 'any', limit: 250 })

        response.body['orders'].each do |myr|
            puts "-----------"
            puts myr.inspect
            puts "-----------"
        end

        loop do
            puts "sleeping 10 seconds ..."
            sleep 10

            break unless response.next_page_info
            response = client.get(path: "orders", query: {  limit: 250, page_info: response.next_page_info })

            response.body['orders'].each do |myr|
                puts "-----------"
                puts myr.inspect
                puts "-----------"
            end

        end



    end

 

 

Hope this helps someone.

Replies 7 (7)

fwallace
Shopify Partner
45 1 4

Forgot to add, works with shopify_api (13.1.0), ruby 3.2.2

 

caffeinesync
Shopify Partner
7 0 1

Hello @fwallace I am trying to replicate your code, but IM getting an weird error when fetching the data: 

eval error: {"errors":"[API] Invalid API key or access token (unrecognized login or wrong password)","error_reference":"If you report this error, please include this id: 4bb181fe-6d59-4377-893a-c70bdea43fef."}

The data into  api_key: "DUMMY", api_secret_key: @app_token,

 

is the one here right? 

Screenshot 2023-07-31 at 17.36.18.png

fwallace
Shopify Partner
45 1 4

Hi, the @app_token is the app token in setting up a private app:

 

access_token.png

 

You can find it when you add a private app in the API credentials sections of creating the app.

caffeinesync
Shopify Partner
7 0 1

Thanks FWallace. I really cant find where I can create those private apps. It doesnt appears for me on my Admin screen. 

Screenshot 2023-07-31 at 22.28.00.png

Get_Quark
Shopify Partner
16 1 7

Hello, 
thanks for sharing! 

Is this method is still working in October 2024 ? 

thanks for your help

Explore the world of pegboards and wall shelving at get-quark.com
Transform your space with modular solutions that blend function and style! 
fwallace
Shopify Partner
45 1 4

Hi! I really don't know, there were so many breaking changes in the shopify_api gem that I ended up redoing the code using just the REST api no ruby gems:

 

store_url = ApiShopify.new(ENV['SHOPIFY_SHOP_NAME']).store_url
      store_header = ApiShopify.new(ENV['SHOPIFY_SHOP_NAME']).get_header
      store_url = store_url + "products.json?limit=250"

      time_start = Time.now

      my_products = HTTParty.get(store_url, :headers => store_header)

      #puts my_products.inspect

      my_products.parsed_response['products'].each do |myp|
        puts "-----------"
        puts myp.inspect
        puts "-------------"
        product_array.push(create_product_hash(myp))
        my_variants = myp['variants']
        my_variants.each do |myvar|
          puts "    **************"
          puts "       #{myvar.inspect}"
          variant_array.push(create_variant_hash(myvar))
          puts "    *************"
        end
        

      end

ApiShopify.determine_sleep(my_products.headers['x-shopify-shop-api-call-limit'])

      if my_products.headers.key?('link')
        local_next_page = LinkParser.parse_next_page(my_products.headers['link'])

        loop do
          my_products = HTTParty.get(local_next_page, :headers => store_header)
          ApiShopify.determine_sleep(my_products.headers['x-shopify-shop-api-call-limit'])
          puts "---- subsequent runs -----------"
          my_products.parsed_response['products'].each do |myp|
            puts "-----------"
            puts myp.inspect
            puts "-------------"
            product_array.push(create_product_hash(myp))
            my_variants = myp['variants']
            my_variants.each do |myvar|
              puts "    **************"
              puts "       #{myvar.inspect}"
              puts "    *************"
              variant_array.push(create_variant_hash(myvar))
            end
            
    
          end
            
    
          # end
          puts "*******************************"
          if my_products.headers['link'] !~ /rel="next"/i
            break
          else
            puts "next_page info = #{my_products.headers['link']}"
            local_next_page = LinkParser.parse_next_page_subsequent(my_products.headers['link'])
            puts "||||||| #{local_next_page} ||||||||||"
            
          end

        end        


      else
        puts "No more products"
      end
fwallace
Shopify Partner
45 1 4
#file lib/api_shopify.rb

class ApiShopify

  def initialize(shop_name)
    @Store_url = "https://#{shop_name}.myshopify.com/admin/api/#{ENV['API_VERSION']}/"
    @token = ENV['SHOPIFY_API_TOKEN']
    @New_header = {"X-Shopify-Access-Token" => @token}
    @CHANGE_header = {"X-Shopify-Access-Token" => @token, 
      "Content-Type" => "application/json"}

  end

  def store_url
    return @Store_url
  end

  def get_header
    return @New_header
  end

  def get_change_header
    return @CHANGE_header
  end

  def self.determine_sleep(header)
    # puts "received header #{header}"
    # puts header.inspect
    parts_of_header = header.split("/")
    # puts parts_of_header.inspect
    numerator = parts_of_header[0].to_i
    denominator = parts_of_header[1].to_f
    percentage_used = (numerator/denominator)*100
    puts "percentage_used = #{percentage_used}"
    if percentage_used > 65.0
      puts "sleeping 10 secs"
      sleep 10

    else
      puts "not sleeping"
    end
    

  end
  
end