Closed DennisKraaijeveld closed 3 years ago
As a first step I would advise to go through ngrok to get more details about what is happening. The functions logs in netlify are in general not that helpful for debugging unfortunately.
The instructions for ngrok can be found here under Advanced Configuration.
The basic syntax is ngrok http [port]
, with [port]
being likely 8888 from netlify dev
.
After that you can simply copy the https url you are given and add it for the three different Shopify hooks of product creation, product deletion, and product update (Shopify store settings > notifications > webhooks).
With this setup the most useful output will not come from ngrok itself, but from netlify dev.
I am doing that and I will get the exact same error:
Response with status 200 in 440 ms.
Request from ::1: POST /.netlify/functions/shopify-sync
TypeError: Cannot destructure property 'metafield' of 'r.data.data.node' as it is null.
at Object.he [as handler] (/Users/dennis/Documents/Projecten/shopify-sanity/web/functions/shopify-sync.js:22:84686)
I am on Mac M1
This should refer to this part of the function:
Could you console.log out shopifyProduct in the function and post what you got? I assume you are using the correct webhook version?
shopifyProduct {
status: 200,
statusText: 'OK',
headers: {
date: 'Sun, 14 Mar 2021 15:08:47 GMT',
'content-type': 'application/json; charset=utf-8',
'transfer-encoding': 'chunked',
connection: 'close',
'x-sorting-hat-podid': '158',
'x-sorting-hat-shopid': '55016947871',
vary: 'Accept-Encoding',
'referrer-policy': 'origin-when-cross-origin',
'x-frame-options': 'DENY',
'x-shopid': '55016947871',
'x-shardid': '158',
'x-stats-userid': '',
'x-stats-apiclientid': '4965383',
'x-stats-apipermissionid': '310275375263',
'x-shopify-api-terms': 'By accessing or using the Shopify API you agree to the Shopify API License and Terms of Use at https://www.shopify.com/legal/api-terms',
'x-shopify-api-version': '2020-10',
'content-language': 'en',
'strict-transport-security': 'max-age=7889238',
'x-shopify-stage': 'production',
'content-security-policy': "default-src 'self' data: blob: 'unsafe-inline' 'unsafe-eval' https://* shopify-pos://*; block-all-mixed-content; child-src 'self' https://* shopify-pos://*; connect-src 'self' wss://* https://*; frame-ancestors 'none'; img-src 'self' data: blob: https:; script-src https://cdn.shopify.com https://cdn.shopifycdn.net https://checkout.shopifycs.com https://js-agent.newrelic.com https://bam.nr-data.net https://api.stripe.com https://mpsnare.iesnare.com https://appcenter.intuit.com https://www.paypal.com https://js.braintreegateway.com https://c.paypal.com https://maps.googleapis.com https://www.google-analytics.com https://v.shopify.com https://widget.intercom.io https://js.intercomcdn.com 'self' 'unsafe-inline' 'unsafe-eval'; upgrade-insecure-requests; report-uri /csp-report?source%5Baction%5D=query&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Fgraphql&source%5Bsection%5D=admin_api&source%5Buuid%5D=521fc250-916f-4265-96dd-ba69c67df8cb",
'x-content-type-options': 'nosniff',
'x-download-options': 'noopen',
'x-permitted-cross-domain-policies': 'none',
'x-xss-protection': '1; mode=block; report=/xss-report?source%5Baction%5D=query&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Fgraphql&source%5Bsection%5D=admin_api&source%5Buuid%5D=521fc250-916f-4265-96dd-ba69c67df8cb',
'x-dc': 'gcp-us-central1,gcp-us-east1,gcp-us-east1',
nel: '{"report_to":"network-errors","max_age":2592000,"success_fraction":0.0001}, {"report_to":"network-errors","max_age":2592000,"success_fraction":0.0001}',
'report-to': '{"group":"network-errors","max_age":2592000,"endpoints":[{"url":"https://monorail-edge.shopifycloud.com/v1/reports/nel/20190325/shopify"}]}, {"group":"network-errors","max_age":2592000,"endpoints":[{"url":"https://monorail-edge.shopifycloud.com/v1/reports/nel/20190325/shopify"}]}',
'x-request-id': '521fc250-916f-4265-96dd-ba69c67df8cb',
'set-cookie': [
'_y=6c0ecb7c-9855-4ce0-9260-8bed4d84f0fd; Expires=Mon, 14-Mar-22 15:08:47 GMT; Domain=viv-home-test.myshopify.com; Path=/; SameSite=Lax',
'_s=61a9ae0f-5a5a-47bd-8e64-e84855ae5436; Expires=Sun, 14-Mar-21 15:38:47 GMT; Domain=viv-home-test.myshopify.com; Path=/; SameSite=Lax',
'_shopify_y=6c0ecb7c-9855-4ce0-9260-8bed4d84f0fd; Expires=Mon, 14-Mar-22 15:08:47 GMT; Domain=viv-home-test.myshopify.com; Path=/; SameSite=Lax',
'_shopify_s=61a9ae0f-5a5a-47bd-8e64-e84855ae5436; Expires=Sun, 14-Mar-21 15:38:47 GMT; Domain=viv-home-test.myshopify.com; Path=/; SameSite=Lax',
'_shopify_fs=2021-03-14T15%3A08%3A47Z; Expires=Mon, 14-Mar-22 15:08:47 GMT; Domain=viv-home-test.myshopify.com; Path=/; SameSite=Lax'
],
'cf-cache-status': 'DYNAMIC',
'cf-request-id': '08d2e16e4e00004c14daa51000000001',
'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
server: 'cloudflare',
'cf-ray': '62fe6b5d48514c14-AMS',
'alt-svc': 'h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400'
},
config: {
url: 'https://apipass@viv-home-test.myshopify.com/admin/api/2020-10/graphql.json',
method: 'post',
data: '{"query":"query getProduct($id: ID!) {\\n node(id: $id) {\\n ... on Product {\\n id\\n handle\\n title\\n totalVariants\\n images(first: 100) {\\n edges {\\n node {\\n id\\n originalSrc\\n }\\n }\\n }\\n variants(first: 100) {\\n edges {\\n node {\\n id\\n title\\n price\\n displayName\\n }\\n }\\n }\\n metafield(namespace: \\"sync\\", key: \\"productData\\") {\\n value\\n id\\n }\\n }\\n }\\n}\\n","variables":{"id":"gid://shopify/Product/6590410686623"}}',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json;charset=utf-8',
'X-Shopify-Storefront-Access-Token': 'storefrontkey',
'User-Agent': 'axios/0.21.1',
'Content-Length': 625
},
transformRequest: [ [Function (anonymous)] ],
transformResponse: [ [Function (anonymous)] ],
timeout: 0,
adapter: [Function (anonymous)],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus]
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'viv-home-test.myshopify.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'viv-home-test.myshopify.com',
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 4510,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object],
[Symbol(RequestTimeout)]: undefined
},
_header: 'POST /admin/api/2020-10/graphql.json HTTP/1.1\r\n' +
'Accept: application/json\r\n' +
'Content-Type: application/json;charset=utf-8\r\n' +
'X-Shopify-Storefront-Access-Token: keystorefront2d\r\n' +
'User-Agent: axios/0.21.1\r\n' +
'Content-Length: 625\r\n' +
'Host: viv-home-test.myshopify.com\r\n' +
'Authorization: Basic Mzg4MmU3NjRmYjc5YzM4ZTgxYjc4ZTM4YWMxZjBhNzI6c2hwcGFfMGZkNjNjYjE1YmE4MjcwMTEyOGMwYWYxYjdiYjczYjY=\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: {},
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/admin/api/2020-10/graphql.json',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [Array],
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 200,
statusMessage: 'OK',
client: [TLSSocket],
_consuming: true,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://key:shppa_0fd67bb73b6@viv-home-test.myshopify.com/admin/api/2020-10/graphql.json',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 82,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0,
[Symbol(RequestTimeout)]: undefined
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'viv-home-test.myshopify.com',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 625,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://key:shppa_0fd6@viv-home-test.myshopify.com/admin/api/2020-10/graphql.json',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'x-shopify-storefront-access-token': [Array],
'user-agent': [Array],
'content-length': [Array],
host: [Array],
authorization: [Array]
}
},
data: {
data: { node: null },
errors: [ [Object] ],
extensions: { cost: [Object] }
}
}
I am using 2020-10 API Webhook
Errors and data are both not visible here and you will need to use JSON.stringify to get this data logged. And that could be quite some output. Maybe using something like pastebin or a gist would be advisable in this case.
Just to check: you have created products in Shopify and created the hooks for product creation, product deletion and product update? Because it looks like data is already arriving empty here.
Another thing would be to check further up whether payload
is constructed correctly from PRODUCT_QUERY
.
{
data: { node: null },
errors: [
{
message: 'Product access denied',
locations: [Array],
path: [Array]
}
],
extensions: {
cost: {
requestedQueryCost: 206,
actualQueryCost: 1,
throttleStatus: [Object]
}
}
}
Looks like data is arriving empty.
Which is weird since I have products and here in the shop I did set up my webhooks:
https://i.gyazo.com/93be52484d86110a0ec905a0401d1f26.png
I did yarn install Sanity Studio instead of NPM install, but everything is just running fine so I am really clueless right now. Maybe I should try to get everything working from the start again.
First time 'using' Gatsby as well (I use Vue and Nuxt) so I am a complete idiot
The studio should not be connected to this. Even without the studio deployed, Sanity would still receive the data, if the sync works out.
The web-hook and the netlify function fire, but apparently product access has been denied, which points at some config issue.
Could you please double check, that you used the right keys in the right places? There are many and they are easy to mix up.
(The response status could be 200
here even if the request hasn't been successful. This has to be done like that because Shopify will remove web-hooks completely if they fail and always returning 200
prevents that)
I saw I made a stupid mistake, now everything was working.. I forgot to give the API access to the products, damn.. Thanks
Awesome! Glad you got the issue settled :)
I am following the guide trying to set everything up, but when trying to sync all my Shopify products to Sanity I am getting stuck and I am not sure what is wrong. I did deploy everything on Netlify but when watching the Function log is do get the following error:
Build settings in Netlify are:
Placed all my env variables in Netlify and under Netlify Functions I set my Functions directory to functions/
Tried some things but can't figure it out yet.