How to do a basic GraphQL query to Shopify with Ruby - ruby

I'm trying to do a basic GraphQL query to a Shopify store with Sinatra. Could someone help me figure out what I'm doing wrong? I looked at their API to do this:
require 'shopify_api'
require 'sinatra'
class App < Sinatra::Base
get '/' do
shop = 'xxxx.myshopify.com'
token = 'shpat_xxxxxxxxxxxxxxxxxxxxxx'
session = ShopifyAPI::Session.new(domain: shop, token: token, api_version: "2021-04")
ShopifyAPI::Base.activate_session(session)
ShopifyAPI::GraphQL.initialize_clients
client = ShopifyAPI::GraphQL.client
SHOP_NAME_QUERY = client.parse <<-'GRAPHQL'
{
shop {
name
}
}
GRAPHQL
result = client.query(SHOP_NAME_QUERY)
result.data.shop.name
end
end
Which gives this error but I don't want to use Rake or Rails. Is it possible to do a GraphQL query to Shopify with Ruby?
ShopifyAPI::GraphQL::InvalidClient at /
Client for API version 2021-04 does not exist because no schema file exists at `shopify_graphql_schemas/2021-04.json`. To dump the schema file, use the `rake shopify_api:graphql:dump` task

As the error states, you need to first dump the schema (see this link: https://github.com/Shopify/shopify_api/blob/v9/docs/graphql.md#dump-the-schema).
Then you create a shopify_graphql_schemas directory in the same root as your ruby script, and put the generated JSON there.
Like stated in the comments, this requires a Rake task, so you need to be using Rails.
If your project doesn't use Rails, you need to do a quick workaround.
You create a temporary barebones Rails project, then generate the dump using that project (you can delete the project when you're done with this).
It's a bit hacky, but it's the only thing I can see that would work.

New link to schema dump
https://github.com/Shopify/shopify_api/blob/v9/docs/graphql.md#dump-the-schema
You need to use something like this
rake shopify_api:graphql:dump SHOP_DOMAIN="SHOP_NAME.myshopify.com" ACCESS_TOKEN="SHOP_TOKEN" API_VERSION=2022-04
Old one doesn't work anymore

Related

Get Wordpress posts by tag in Ruby

We have a Wordpress instance with the XML-RPC API enabled and a Ruby on Rails website we want to display Wordpress posts on. I need to get posts by "tag". Looking at Rubypress it seems as though I have to wp.getPosts and parse out the correct ones. This is inefficient as we add new posts and have to keep updating.
Is there a way to get posts from a Wordpress instance via the API by tag?
Thank you.
We solved this with the wp_api_client gem and using the tags?slug=TAG endpoint. e.g.
require 'wp_api_client'
WpApiClient.configure do |api_client|
api_client.endpoint = "yourwordpress.com/wp-json/wp/v2"
api_client.basic_auth = {username: username, password: password}
end
client = WpApiClient.get_client
client.get("tags?slug=#{tag_you_want}").each do |tag|
client.get("posts?tags=#{tag.id}")
end

Ruby Script using Octokit: Making API Calls

I am trying to create a script that gets a list of all repositories from GitHub. GitHub has a ruby gem called Octokit that I am trying to utilize, but I am a little lost.
The API has a reference here. It shows that I can get this response using a GET request. I am trying to figure out how to perform this using the Octokit Gem.
I may be completely off base with this question as I am new to Ruby, but I'd appreciate some steps showing how this can be completed. If I should not be using Octokit for this, a recommendation for creating HTTP Requests and Parsing the appropriate JSON response would be appreciated as well.
The Code I have so far:
#!/usr/bin/ruby
require 'Octokit'
client = Octokit::Client.new \
:login => '',
:password => ''
user = client.user
user.login
Following along with the code you already wrote, you can get all of the repositories for the user who's credentials you're using when authenticating the client with:
client.repositories
You can also get the public repositories of another user by passing their login as an argument:
client.repositories('username_here')

Shopify API Search Parameters

I'm trying to get all of my customers that don't accept marketing but nothing seems to be working that I'm trying.
ShopifyAPI::Customer.find(:all, :params => { accepts_marketing: false})
I'm using the shopify_api Ruby gem.
The search endpoint is a little different than the usual. As you point out, your issue has nothing to do with Rails. Instead, just provide the endpoint with a little more information and you'll be fine. Try this:
ShopifyAPI::Customer.all( from: :search, params: {q: "accepts_marketing:true"})
You can search on customer email, whatever you need when you specify the endpoint as search on the Customer.

Jekyll site via Sinatra and Heroku - can't route to new posts

I created a 'Hello, World' app using Sinatra and then pushed to Heroku and all worked.
I've since created a basic Jekyll blog, and am trying to access it via Heroku using the following routes:
get '/?' do
file.read("_site/index.html")
end
get '/.*.*' do
file.read("_site/#{params[:splat]}")
end
not_found do
file.read("_site/error/index.html")
end
The route to the index works fine link to my site
but as soon as I click to the first post it always fails.
I have tried so many variations of different routes for the :splat and get, just can't seem to get it to work? Any ideas?
In the route that's failing, before the file.read statement, add warn "splat = #{params[:splat]}" and that will output the result to the terminal, and you can see what it's actually getting, e.g.
get '/.*.*' do
warn "splat = #{params[:splat]}"
file.read("_site/#{params[:splat]}")
end
You could also try using an absolute path to the files, though if you're getting the index page then it suggests it's not needed:
config do
set :statics, File.expand_path(File.join(settings.root, "_site"))
end
get '/.*.*' do
file.read( File.join settings.statics, params[:splat] )
end
Unless there's something else you were planning to use Sinatra's routes for, you could probably remove the Sinatra routes entirely and just make the "_site" folder the public_folder, and then Sinatra will do the serving of the static files for you:
config do
set :public_folder, File.expand_path(File.join(settings.root, "_site"))
end
# no more to do...

Fetching signed_request in a Facebook App with Ruby/Sinatra and the Rest-Graph gem

I've built a Facebook app using Sinatra and the Rest-Graph gem. Now I would like to embed the app as an iframe tab in a Facebook Page.
To do that, I need to fetch data from the signed_request sent to my app by Facebook.
The Rest-Graph gem states the following feature on its Github page:
Utility to extract access_token and
check sig in cookies/signed_request
I couldn't find any documentation on how to use this "utility". Can you point me to some documentation or even better, give me an example on how this is used with Ruby/Sinatra?
Nearly all of the Graph API libraries that are available deal with signed_request in a similar way. Rest-Graph has a parse_signed_request method (Rest-Graph/lib/core.rb) that you can call in Sinatra.
I'm using Koala for this with Sinatra, and it works as advertised:
oauth = Koala::Facebook::OAuth.new(APP_ID, APP_CODE)
signed_request = oauth.parse_signed_request(params["signed_request"])
You get back a hash of the JSON object that Facebook posts:
{
"algorithm"=>"HMAC-SHA256",
"issued_at"=>1303883452,
"user"=>
{
"country"=>"us",
"locale"=>"en_US"
},
"user_id"=>"100002364226618"
}
rest-graph makes it pretty easy, too. Just tested this in a Sinatra app. Works perfectly:
rg = RestGraph.new( :app_id => APP_ID, :secret => APP_SECRET)
parsed_request = rg.parse_signed_request!(params["signed_request"])
Lemme know if that doesn't work for you.
I just got a response to this question from "cardinalblue", the developer of the Rest-Graph gem. This little example was exactly what I was looking for:
require 'sinatra'
require 'rest-graph'
app_id = '123'
secret = 'abc'
config = {:app_id => app_id,
:secret => secret}
post '/' do
rg = RestGraph.new(config)
rg.parse_signed_request!(params['signed_request'])
"#{rg.get('me').inspect.gsub('<', '<')}\n"
end
run Sinatra::Application
Sidenote: In case you're building something similar, please note the post '/' do. Facebook Pages fetch your page using a POST request instead of a GET.

Resources