Ruby private app access to Shopify Resources

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: _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: _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.

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

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?

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

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

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

Hello,
thanks for sharing!

Is this method is still working in October 2024 ?

thanks for your help

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
#file lib/api_shopify.rb

class ApiShopify

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

  end

  def store_url
    return _url
  end

  def get_header
    return _header
  end

  def get_change_header
    return _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