Giter Club home page Giter Club logo

shopify-node-api's People

Contributors

bknights avatar chris-milliano avatar davemackintosh avatar dlebech avatar frehner avatar granteagon avatar gridmechanic avatar halcarleton avatar jarofghosts avatar lastobelus avatar mariusa avatar mozeryansky avatar nodeit avatar rcky avatar rfink avatar richter-alex avatar rickcraig avatar vizjerai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shopify-node-api's Issues

Invalid API key or access token (unrecognized login or wrong password

Received the following error: BODY: {"errors":"[API] Invalid API key or access token (unrecognized login or wrong password)"}

My code

 var Shopify = new shopifyAPI({
                 shop: 'SHOP_NAME', 
                 shopify_api_key: 'API_KEY', // Your API key
                 shopify_shared_secret: 'API_SHARED_SECRET'// Your Shared Secret
             });

// More secure if we get the user email through the server
var activeUserEmail         = getCurentUser.email;
var findCustomerByEmailURL  = "/admin/customers/search.json?query=" + activeUserEmail;

Shopify.get(findCustomerByEmailURL, function(err, data, headers){
     console.log(data); // Data contains customer json information

 });`

Pretty sure I have the correct API_KEY and API_SHARED_SECRET. Im guessing this has something to do with the customer endpoint, I'm trying to find a customer by email.

Callback inside try-catch block

You invoke a callback inside a try-catch block on line 160 which catches errors thrown by passed callbacks. As a consequence errors occurring in the callback appear to be errors from the API calls and your code invokes the callback a second time passing the error thrown by themselves.

Invalid API key or access token

Hi Chris,

Thanks for setting up this module. It's been great so far, however, I have an issue using it.

Once I get my permanent token (it's automatically saved to the access_token property in the config object), I try the following code:


var Shopify = new shopifyAPI(config)

Shopify.get('/admin/products.json', function(err, data, headers){
console.log(data)
})

config is:
{ shop: 'second-opinions-store',
shopify_api_key: '167922d6d9ace8e71795cb4c10074cf4',
shopify_shared_secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
shopify_scope: 'write_products',
redirect_uri: 'http://localhost:5000/finish_auth',
nonce: '150281256017000',
verbose: true,
access_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxx' }

I'm sure api_key, shared_secret and access_token are correct for my store, but I get a 401 error:
"[API] Invalid API key or access token (unrecognized login or wrong password)"

What am I doing wrong??

Send data from inner-most API call to another to send response back to client?

Hi there again...
Sorry for making another issue.. This is more a logic problem on my side, but wondering if shopify-node-api has anything built in that could help me.

I'm trying to grab all customers + each customer's metafield.
Shopify doesn't have an API that I could easily grab all at once with,so I need multiple calls sadly.

I'm using express + need to get my data from my innermost for loop API call, and send it to the outer API call so I can bundle it all up and send it as a response to the client.
Here's my code

router.get('/customers', (req, res) => {
	Shopify.get('/admin/customers.json', function(err, data, headers){
		for (var i = 0; i < data.customers.length; i++) {
			Shopify.get('/admin/metafields.json?metafield[owner_id]=' + data.customers[i].id + '&metafield[owner_resource]=customer', function(err, data, headers){	
				for (var i = 0; i < data.metafields.length; i++) {
					console.log(data.metafields[i]);
					//THIS WORKS!!!
					// return callback(data.metafields[i]);
				}
			});
		}
	});
});

Any helpers here?
I'm trying to just show a list of all customers with ther metafields.Anyone have a better solution?

Not able to redirect to auth_url

Hi, I am new to shopify and node as well. I have successfully created auth url. Now i am stuck in res.redirect(url). I guess it needs login credentials of my shop. When i am hitting this auth url on browser, it is redirecting to login page.

GET + Options

I'm trying to put a get to the products.json based on its documentation and passing the options but it's not working.

Shopify API products.json endpoint

    Shopify.get('/admin/products.json', {fields: 'id, title', page: 1, limit: 5 }, function(err, data, headers){
            console.log(data); // Data contains product json information
            console.log(headers); // Headers returned from request
        });

This return ALL the products, not only 5 from page 1. What am I doing wrong?

If i do the below, it works.

Shopify.get('/admin/products.json?limit=5', function(err, data, headers){
    console.log(data); // Data contains product json information
    console.log(headers); // Headers returned from request
}))

Thanks

Shopify’s OAuth flow is changing

Is this change taken into account on the lib?

Shopify’s OAuth flow is changing

This is a reminder about a change that we are making to Shopify’s OAuth functionality.

Effective tomorrow, June 1, the signature URL parameter will not be included in OAuth redirects that come from Shopify. We announced this deprecation in December, 2013 because of security problems with the MD5 algorithm.

Please take a moment to make sure that your app uses the newer HMAC URL parameter to verify OAuth requests.

You can find more information about this change in our OAuth documentation and in Shopify’s API Announcements forum.

If you have any questions or feedback, just reply to this message and we’ll be glad to help.

Thanks for reading,
Shopify Apps Team

thanks for the best shopify node module

exchange_temporary_token requires state parameter to be present

Sometimes, Shopify doesn't pass the state parameter as a query string, even though it is set in the authorize call.
Several others reported this:
https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/oauth2-state-parameter-is-not-passed-262706
https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/oauth-state-parameter-207445

In this case, it's impossible to use exchange_temporary_token(), as that forces check of the state

   if (!self.is_valid_signature(query_params)) {
        return callback(new Error("Signature is not authentic!"));
    }

Would it be possible to ignore that instead, e.g.

   if (!self.is_valid_signature(query_params, true)) {

and let developers call is_valid_signature(query_params) if desired?

Thanks

webpack error, module not found

I am usingversion : 2.1.0
Module not found: Error: Cannot resolve 'file' or 'directory' ./package in /Users/Path/to/Project/node_modules/shopify-api-node
@ ./~/shopify-api-node/index.js 10:12-32

Shouldnt it specially use json extension? I am missing something in my webpack config?

var webpack = require('webpack');

module.exports = {
    entry: "./index.js",
	target:"node",
    output: {
        path: __dirname,
        filename: "bundle.js"
    },
	resolve: {
		extensions: ['', '.js'],
		modules: [
			'node_modules'
		],
	},
    module: {
        loaders: [
		{test: /\.js$/,
			exclude: [/node_modules/, /.+\.config.js/],
			loader: 'babel-loader',
			query: {
				presets: ['es2015']
			}
		},
		{test: /\.json$/,loader:'json-loader'},
		]
	}
};

minor example mistake

README has

Shopify.post('/admin/products/1234567.json', post_data, function(err, data, headers){
  console.log(data);
});

should be

Shopify.post('/admin/products.json', ... )

Using the checkout uri requires work when a 202 status code is returned

The checkout URI makes use of a 202 response.statusCode and a location header.

shopify-node-api appears to swallow non-error codes.

a simple "fix" would be to add a header in your response.on('end') event handler

var headers = response.headers; headers.x-shopify-status = response.statusCode; callback(error, json, headers, options);

JSON parsing big integers can fail

Using the stock JSON.parse can fail, since shopify uses bigint types for its ids, and javascript can only natively handle 2^53 - 1, whereas the bigint can go to 2^64 - 1. As such is the case, a number larger than Number.MAX_SAFE_INTEGER would be incorrectly parsed as a different, smaller number, and would cause untold issues. I have not seen them send back such a large number yet, but I want to plan for the future.

I'm sending a pull request to use https://github.com/sidorares/json-bigint as the JSON parsing library, it turns numbers larger than the max safe integer into "BigNumber" objects, which can easily be represented as strings. Coming shortly.

enhancement: simpler error handling

When making API requests, one has to check both err and data.errors to verify if there was an error.

What do you think about making it simpler for clients by checking only err?

To make it possible, this

var json = JSON.parse(body);
callback(null, json, response.headers);

should be changed to

var json = JSON.parse(body);
if (typeof json.errors != "undefined") {
    callback(JSON.stringify(json.errors)); //could be string or array?
} else {
    callback(null, json, response.headers);
}

Not using an Error object

Hello,

Great module, very helpful. One question, is there a reason you don't use the native "Error" object? This module doesn't play well with koa.js, since it expects a native Error object. Would you be opposed to a P.R. that uses a native Error object? I would still attach the same properties. Thanks!

Access Token Exchange always returns 'Error: Signature not authentic!'

I have been pulling my hair out for the past day trying to figure out where I am going wrong, but when i try to get my app setup for public use I just get errors when I try to finish doing the auth, see the relevant code below..

router.get('/install', function(req, res, next) {
    shop = req.param('shop');
    Shopify = new shopifyAPI({
        shop: shop, // MYSHOP.myshopify.com
        shopify_api_key: apikey, // Your API key
        shopify_shared_secret: sharedkey, // Your Shared Secret
        shopify_scope: 'read_orders,read_products,read_customers',
        redirect_uri: appurl + '/finish_auth',
        nonce: n() // you must provide a randomly selected value unique for each authorization request
    });
    writeConfigData(shop, Shopify.config); //writes the config to firebase, worried the config was wrong
    var auth_url = Shopify.buildAuthURL();
    res.redirect(auth_url);
});

router.get('/finish_auth', function(req, res){
    var theshop = req.param('shop').replace(/\./g, "_"); //this is just to find the saved shopconfig in firebase
    database.ref('configs/' + theshop).once('value').then(function(snapshot) {
        var config = snapshot.val();
        var Shopify = new shopifyAPI(config), // You need to pass in your config here
            query_params = req.query;
        Shopify.exchange_temporary_token(query_params, function (err, data) {
            // This will return successful if the request was authentic from Shopify
            // Otherwise err will be non-null.
            // The module will automatically update your config with the new access token
            // It is also available here as data['access_token']
            console.log("HERE IS THE EXCHANGE: " + err + data);
        });
    });

});

The current Docs are a little fuzzy with is_valid_signature and the way that Shopify uses hmac now instead, I have tried about a thousand different workarounds but always get that same error... I am starting to think it might actually be Shopify.

Any help with this issue would be awesome

Umlauts not working

Requests to the shopify api which contain umlauts (äüö) do not work.

795: unexpected token at '{"product":{"title":"Bl��d"}'

As far as i can tell, the encoding is fine up to the point where you pass it to the request from the https module. This is not a problem of the api itself, it works using other clients such as Postman.

Question about temp tokens.

Hello again,

I am getting stuck on what to pass in for config in

app.get('/finish_auth', function(req, res){

  var Shopify = new shopifyAPI(config), // You need to pass in your config here
    query_params = req.query;

  Shopify.exchange_temporary_token(query_params, function(err, data){
    // This will return successful if the request was authentic from Shopify
    // Otherwise err will be non-null.
    // The module will automatically update your config with the new access token
    // It is also available here as data['access_token']
  });

});

Thank you for your help.

webhooks SyntaxError: Unexpected token <

Hi,

Does anyone ever had this error : "SyntaxError: Unexpected token <" in the callback "err" after trying to
create a webhook? Here's my code

var topics = ['app/uninstalled', 'orders/fulfilled', 'orders/paid'];
var requesturl = "https://THESHOPURL/admin/webhooks";
Shopify.post(requesturl, { webhook : { address : config.shopify_webhook_url + topics[0] , topic : topics[0]}},
                function(err, data, headers) {
                    if(err) {
                        console.log("HEADERS : ", headers);
                        console.error("ERROR IN CREATING SHOPIFY WEBHOOKS FOR THE SHOP: ", shop.url);
                        console.error("ERR : ", err);
                    } else {
                        console.log("webhook created with ", shop.url);
                        shop.webhooks.push(data.webhook);
                    }
                }
})

ERROR IN CREATING SHOPIFY WEBHOOKS FOR THE SHOP: kollectionk.com
ERR : SyntaxError: Unexpected token <

Helper functions

I've used your API to do some cool things, and some of them are things everybody might want. I'm wondering if you want me to create a pull request to implement them into the api.

For example, I have a function which gets all the products on a store:

function getAllProducts() {
    let products = [];

    function getpage(pagenum) {
        return new Promise((resolve, reject) => {
            Shopify.get('/admin/products.json', {limit: 250, page: pagenum}, function (err, data, headers) {
                if (err) {
                    reject(err);
                }
                resolve(data.products);
            });
        });
    }

    let pagenum = 1;
    return new Promise((resolve, reject) => {
        function getNextPage() {
            getpage(pagenum)
                .then((data) => {
                    products = products.concat(data);

                    if (data.length < 250) {
                        resolve(products);
                    } else {
                        pagenum += 1;
                        getNextPage();
                    }
                })
        }

        getNextPage();
    });
}

If you like I can work on implementing this into a pull request. Let me know 😄

Embedded App Authentication

I'm creating an embedded app and this wrapper is working well. I don't see any special instructions in the documentation about escaping the iframe. Does this app automatically handle the oAuth redirect for embedded apps through the function res.redirect(auth_url)? Or do I need to add code within my app to escape the iframe?

Per Shopify's documentation "it is critical that the initial OAuth request redirect escapes the iframe to make the requests."

Error code 404, not found

HI,

In my application, when a shop download my app, I create some webhooks. Sometimes it works, sometimes not. I recently had this error with a shop that I tried to create webhook { error: 'Not Found', code: 404 }. I don't know why I receive this because I have the correct access_token. I'm using this var to make request.

var Shopify = new shopifyAPI({
shopify_api_key: process.env.SHOPIFY_API_KEY, // Your API key
shopify_shared_secret: process.env.SHOPIFY_SHARED_SECRET, // Your Shared Secret
access_token: shop.access_token,
shop: shopGoodUrl,
verbose: false
});

I think the problem is when in the library, when I make a request, the method "hostname()" is called and this method add .myshopify to the shop. For example "whatyouvape" download my app and www.whatyouvap.com works but not www.whatyouvape.myshopify.com. When I type that in the url it's says "Sorry, this shop is currently unavailable."

If someone could help me with this. This would be very appreciated.

Thank you very much.

CORS error

Hi ! I've installed this module to my local app built on angular. I am trying to get some data from my shopify store ( Private App ) to my local http://localhost:4200 . I get this error in console :

"Fetch API cannot load https://mephistoshoesseattle.myshopify.com/admin/products.json. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 404. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."

I've read a tonn of doc about CORS , but nothing helped.
You are my only hope, please help!

CORS issue #2

Thanks a lot for advice to use proxy on my local server! It works, now i can get the data from the remote server.
There is one more question : after i will build my app on local and push site files to some hosting, how can i setup that proxy there? is that possible?
It will be great if you can give me an advice, thanks for you time!

Include is_valid_signature() in Docs

is_valid_signature() should get a spot in the Docs. It's a very helpful method. I've been using my own, until I just noticed that it was included in shopify-node-api.

Send GET request with spaces in query

Hi there, not sure if this is specific to your library... but I'm trying to query customers with a certain tag.

I can do the following -
/admin/customers/search.json?query=tag:singleWord

But obviously, once I try and add a tag with spaces in it I get errors -
/admin/customers/search.json?query=tag:Waiting - 5kg Single Bag

TypeError: Request path contains unescaped characters

So I figured, okay - I'll escape the spaces and turn it into something like this:

Waiting%20-%205kg%20Single%20Bag

The request then goes through, but no customer is returned.

Is this something on the library end, or on Shopify's end?

Thanks so much! Love the library.

Getting Shop Details

Hi,

In this module, seems like you are setting the Shop: 'MYSHOP' when you create a new shopifyAPI object. However, for a public app, how and where does the application get the shop name of the actual shop trying to install the app? I would assume the buildAuthURL function, exchange temporary token and all of the requests would require the actual shop name, not a hardcoded one?

Thanks for your help.
A

include error_description in thrown error messages

This is just a feature request.
I could not find an official error response format from Shopify, but the error responses I receive look like this:

{"error":"invalid_request","error_description":"Could not find Shopify API application with api_key: "}

Currently the library uses the 'error' param as the error message when thrown. I believe all 400 requests are 'invalid_request' errors, and it would be a more descriptive message if it contained the 'error_description' if available.

Need a way to have the original request URL in the Shopify.get() response

Sometimes Shopify errors on Shopify.get() responses (e.g. a HTML page saying Something went wrong), and we need to re-try that.

However, as we issue multiple Shopify.get() calls asynchronously, we can't tell which of the original requests failed once we get the response, as the included data doesn't mention the original url.

In
ShopifyAPI.prototype.makeRequest
only the headers are passed to callback:
callback(null, json, response.headers);

Would you please pass the original request URL too?

Thanks

is_valid_signature() should be idempotent

Hi,

I'm using is_valid_signature() before doing API calls with shopify-node-api. But it won't work multiple times, since it deletes the "signature" parameter from req.query array.

Instead of

    delete params['signature']; // Not needed to build hash

    for (var key in params){
        calculated_signature.push(key + '=' + params[key]);
    }

it would work better to do

    for (var key in params){
        if (key != "signature") { //signature must not be included in hash
                calculated_signature.push(key + '=' + params[key]);
        }
    }

As a side note, saw that exchange_temporary_token() calls is_valid_signature() after making the oauth request. Verification should be moved at the top.

Hmac verifcation failed

Hi,

After the OAuth update of shopify my app has stopped working. I checked the issue and its when i call the "exchange_temporary_token" method and I get the error "Signature is not authentic!" now as my code is deployed on github without the node modules I am simply updating my version in the package.json so shouldnt it work?? If not then what is required at my end?? My current code is this

function verifyAndGetToken(req){
query_params = req.query;
shopifyApi.exchange_temporary_token(query_params, function(err, data) {
console.log("REsponse from auth token", err, data);// This line prints the error "Signature is not authentic!"
AccountDb.findOneAndUpdate({
"stores.name": req.query.shop
}, {
"stores": [{
name: req.query.shop,
token: data.access_token
}]
}, {
upsert: true
}, function(err, account) {
console.log("Got auth token and updated account", err, account)
req.session.shopify = query_params;
console.log("auth token set session",req.session)
res.redirect('/shopify/')
return;
});
});
}

quick question

  1. user installs app
  2. user accepts app charge
  3. app Shopify.exchange_temporary_token and saves token to database
  4. app POST creates uninstall webhook
  5. user uninstalls app
  6. app receives the POST from webhook
  7. app gets from database the token and replaces token below, after shop, api key, secret are input correctly
var Shopify = new shopifyAPI({
  shop: 'MYSHOP', // MYSHOP.myshopify.com
  shopify_api_key: '', // Your API key
  shopify_shared_secret: '', // Your Shared Secret
  access_token: 'token', //permanent token
});
  1. app DELETE Shopify.delete the uninstall webhook
    • app is getting 401 Invalid API key or access token (unrecognized login or wrong password)

My question is did I mess up or miss anything on any of the steps I listed to get the 401 error?

API requests don't always return an err for unsuccessful responses

API requests don't always return an err for unsuccessful responses. A simple case is a GET request to an asset that doesn't exist. For example:

shopifyAPI.get('https://<store>.myshopify.com/admin/themes/<themeid>/assets.json?asset[key]=doesnotexist', function(err, data, headers) {});

An API call like this results in Shopify sending a response with a 404 status code and an empty body. This should result in the callback being invoked with an err, but instead it gets called with no err and data={}.

The cause of the issue appears to be in shopify.js#makeRequest. This function is relying on JSON body inspection to determine if an error is returned.

Instead, the code should use response.statusCode to determine if the request was a success. And then inspect the JSON body just for the purpose of pulling out any additional messages.

SHA256

I'm using this module with React / Webpack and it works well with exception of the Shopify.exchange_temporary_token() fails because crypto.createHmac('SHA256') is used instead of crypto.createHmac('sha256'). React / Weback uses the crypto-browserify module which requires the hash name to be lowercase.

Refactor?

Hello guys,

We at ghostmonitor rely on this repo and want to keep it in good health :) If you you open we could make a refactor using promises generators and standard style guide. What do you think?

please document config.access_token

After initial install, a few days later one will instantiate as follows:

var Shopify = new shopifyAPI({
                shop: 'MYSHOP', // MYSHOP.myshopify.com
                shopify_api_key: '', // Your API key
                shopify_shared_secret: '', // Your Shared Secret
                access_token: 'token', //permanent token
            });

Please document this type of usage too.

Thanks

Include more query params when computing HMAC signature

Hello,

We had an issue with Shopify auth sending more query params, and resulting in an invalid HMAC.

That being said, you should consider almost all url query params (*see below) to re-generate the hmac value. Not just shop and timestamp. This allows us to send you extra params when they may be required, without you needing to make a code change.
*
Your code should remove hmac and signature from the url query params.

This
https://github.com/christophergregory/shopify-node-api/blob/master/lib/shopify.js#L54
should be changed to exclude hmac and signature, rather than including only a pre-defined list of params.

Thanks!

Private apps

Hello,

I am learning how to build a private app and on the auth_url I am getting an error that "Oauth error invalid_request: The Shopify API application does not support oauth"

Is there something that I am missing that is different for private apps vs public apps?

Thanks for your help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.