Received Webhook in Google App Script - Shopify not receiving my 200 OK

New Member
11 0 0

I am using this code in Google App Script to receive a webhook created in the Shopify Admin > Notifications

The code executes in about 500 milliseconds. But I can see that Shopify is resending the post again because firebase is being triggered multiple times in succession. My webhook has been deleted 3 times because I'm not responding correctly apparently.

function doPost(e) {
//store data  in firebase
return ContentService.createTextOutput('200 OK');
}

What am I doing wrong here?

 

Documentation: https://developers.google.com/apps-script/guides/web

 

0 Likes
New Member
11 0 0

(Further proof)
I sent a test post to my webapp using zapier and got this response which seems correct to me. Shopify seems to still be sendnig the same post multiple times.

Michael_Holmes_0-1606349504999.png

 

0 Likes
New Member
11 0 0

any help on this? I'm returning 200 OK as text in 0.5 second but its still deleting my webhook.

0 Likes
Explorer
69 5 14
0 Likes
New Member
3 0 0

I'm a bit late to the party, but could it possibly be due to the way ContentService uses redirects? See here: GAS Content Service -> Redirects 

I haven't gotten far enough into using the Shopify API to test this on my own, but HtmlService a try instead: GAS Class HtmlService -> createHtmlOutput() 

0 Likes
New Member
11 0 0

Seems this sovles my problem:

 

 

 

HtmlService.createHtmlOutputFromFile('200 OK').setSandboxMode(HtmlService.SandboxMode.IFRAME);

 

 

 

0 Likes
New Member
3 0 0

Well, that's good to know! I'll keep that in mind when I'm getting set up.

Another issue is that there's no way to read HTTP headers in Google Apps Script (an annoyance of mine for a long time...), and that's where Shopify puts all the context (including the hash so you know the webhook is truly from them). I don't think sending a hash through the query parameter is secure, but at least we can add some context that way and have the script parse the query string parameter when received (eg: {{web app url}}/exec?api_version=2020-10&scope=orders_create&store=samplestore).

0 Likes
New Member
3 0 0

For anyone having troubles, this worked well, and the query parameters help to identify where the webhooks are coming from. Note that there's no need for text in the HtmlService response; Shopify just looks at the headers for a 200 OK response code.

/*
Sample format: https://script.google.com/macros/s/{{SCRIPT_ID}}/exec?source=shopify&api_version=2020-10&store_name={{STORE_NAME}}&event={{EVENT_NAME}}
*/
function doPost(e) {
  
  if (e && e.postData && e.postData.type === "application/json") {
    let data = JSON.parse(e.postData.contents);
    let query = e.parameter;
    if (query.source === "shopify") {
      Logger.log("Shopify API " + query.api_version + ": Received " + query.event + " webhook data for store " + query.store_name + ".");
      // TODO: data stuff
    }
  }
  
  return HtmlService.createHtmlOutput("");
  
}

 

When I tried it with ContentService.createTextOutput() I got several hits of the doPost function indicating that Shopify retried it a few times. Checking with Chrome developer tools it appears that ContentService definitely does do a redirect that Shopify doesn't like, so it's best not to use that. ContentService doesn't sanitize the output like HtmlService does, so that's why Google needed to go through an extra step.

0 Likes