Running a GraphQL Mutation in Google Apps Script

function Run_Mutation(){
  
  var token = "Bearer [Censored]"
  var Business_ID = "[Censored]"
  var url = "https://gql.waveapps.com/graphql/public";
  
  var query = 
 "mutation Mutation($input: CustomerCreateInput!) {\
  customerCreate(input: $input) {\
    didSucceed\
  }\
}";
  
  var variables = {
  "input": {
    "businessId": Business_ID,
    "name": "Santa",
    "firstName": "Saint",
    "lastName": "Nicholas",
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="94e7f5fae0f5d4f1ecf5f9e4f8f1baf7fbf9">[email protected]</a>",
    "address": {
      "city": "North Pole",
      "postalCode": "H0H 0H0",
      "provinceCode": "CA-NU",
      "countryCode": "CA"
    },
    "currency": "CAD"
  }
};
    
    var headers = {
      'muteHttpExceptions' : true,
      'contentType' : 'application/json',
      'authorization' : token
  }
    
    var data = {
        "operationName": "Mutation",
        "query" : query,
        "variables" : variables
      }
    
    var options = {
      'method' : 'POST',
      'headers' : headers,
      'payload' : data
    }
    
    var response = UrlFetchApp.fetch(url, options);
    Logger.log(response);
}

This code snippet demonstrates a mutation request using GraphQL. It pertains to creating a customer in Wave Accounting API for a specific business while keeping sensitive information censored. The customer details are fictitious placeholders.

The script operates smoothly on platforms like the Wave API Playground and Apollo. Yet, when implemented on Google App Script, an error arises:

POST body missing. Did you forget use body-parser middleware?

To resolve this issue, the integration of body-parser middleware into the script may be necessary. It is speculated that the absence of such middleware impedes the interaction with the Wave API server specifically on G.A.S. Alternatively, modifications can be made to ensure successful mutation requests within G.A.S.

Note that query requests function without any problems, with mutations being the primary concern.

Answer №1

Within your script, the request header utilizes

'contentType' : 'application/json'
and 'muteHttpExceptions' : true. However, at 'payload' : data, the object of data is not being converted to a string. Upon reviewing the official documentation for the GraphQL API, it appears that the data should be sent as application/json. Reference I suspect that the reason for the error message stating
POST body missing. Did you forget to use the body-parser middleware?
may be related to this issue.

Given this scenario, how about implementing the following modification?

From:

  var headers = {
    'muteHttpExceptions' : true,
    'contentType' : 'application/json',
    'authorization' : token
}
  
  var data = {
      "operationName": "Mutation",
      "query" : query,
      "variables" : variables
    }
  
  var options = {
    'method' : 'POST',
    'headers' : headers,
    'payload' : data
  }

To:

var headers = {'authorization': token}
var data = {
  "operationName": "Mutation",
  "query": query,
  "variables": variables
}
var options = {
  'method': 'POST',
  'headers': headers,
  'payload': JSON.stringify(data),
  'muteHttpExceptions': true,
  'contentType': 'application/json',
}

Note:

  • If you wish to set query as shown below,

      mutation Mutation($input: CustomerCreateInput!) {
        customerCreate(input: $input) {
          didSucceed
        }
      }
    
  • Please make the following modifications:

    • From

          var query = 
         "mutation Mutation($input: CustomerCreateInput!) {\
          customerCreate(input: $input) {\
            didSucceed\
          }\
        }";
      
    • To

          var query = `mutation Mutation($input: CustomerCreateInput!) {
          customerCreate(input: $input) {
            didSucceed
          }
        }`;
      
    • or

        var query = "mutation Mutation($input: CustomerCreateInput!) {\n  customerCreate(input: $input) {\n    didSucceed\n  }\n}";
      

Note:

  • This modification assumes that both your request body (data) and token are valid. Please double-check these elements. If an error persists after making the above changes, verify the integrity of your request body and token once again.

References:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve information from the NodeJs server pertaining to the previous 10-minute timeframe

While working on a project where I needed to fetch and display data from a website within the past 10 minutes that meets a certain condition, I initially thought of storing it in a global variable. However, I realize that this may not be the best practice. ...

How to insert text into a text input using onKeyPress in react.js

I am looking to simulate a typing effect where the phrase 'Surveillance Capitalism' is inputted letter by letter into a text input field as a user types. However, I encounter an issue when trying to add each individual letter into the input; I re ...

Is there a way for me to choose the item from the search dropdown so that it fills in the search input field automatically?

Upon typing a word into the search input field, a list of suggestions will appear below. https://i.sstatic.net/etOBI.png Is there a way for me to select a word from the list like Maine (ME) and have it automatically fill the search input field? What chan ...

The loading of Google maps occurs simultaneously with ongoing AJAX requests

I am currently working with the Google Maps API in combination with rails 5.0.4. My goal is to have the map center on the user's location and populate the latitude and longitude fields with the corresponding coordinates. Right now, the lat, lng field ...

JavaScript snippet for extracting all gif images from a website's page

I was attempting to retrieve all the images on a webpage and then print them in the console log with the following code: function findImages() { var imgs = document.getElementsByTagName("img"); var imgSrcs = []; for (var i = 0; i < ...

dynamic image size based on mobile device orientation

Struggling with a tiny mobile image gallery here. Whenever I switch to portrait mode, the images end up being too big for the screen. Is there a way to use javascript to resize the images to fit the screen when switching to portrait mode? They display fin ...

Receiving undefined when trying to access an array within the state in React

When I use console.log(this.state.animal_names), the output is >(2) [Array(2), Array(2)] Upon expanding, I see 0: (2) ["dogNames", Array(53)] 1: (2) ["catNames", Array(100)] However, when I attempt to access them like this: desiredAnimal = "dogNames ...

Enable the entire button to be clickable without the need for JavaScript by utilizing a Bootstrap 5 button

Is there a way to make a button redirect when clicking anywhere on it, not just the text inside? Here is the button code utilizing Bootstrap 5: <button class="btn btn-rounded btn-primary" type="button">Placeholder Text</button& ...

Asynchronous mismatches occur with React.js useState values

There is an unusual problem I'm encountering where the value passed into useState is different than the variable for useState. This issue occurs consistently on one specific UI component, while others do not experience the same problem. I just want to ...

Using Angular to dynamically load images through ajax requests

Is it possible to load an image via ajax, meaning to get the contents of the image via ajax and display it as an actual image? I understand how to handle the second part but how do you store the ajax data/blob in a variable? how can you initiate an ajax ...

Create a React MUI component that allows menu items to become sticky when selected

Is there a way to make the mui MenuItem stay sticky to Select while scrolling down? To see the issue in action, check out this codesandbox example https://codesandbox.io/s/quirky-knuth-5hr2dg?file=/Demo.tsx Simply click on the select and start scrolling ...

Resolve feature for UI routes fails to function upon refreshing the page

My app utilizes UI Route for view routing. When accessing /berlinerliste/, a function is triggered to display an array of objects. If one of these objects is clicked, the view changes to /berlinerliste/{id}/ and shows the details of that specific object. ...

Access to the Heroku app is restricted to the specific device that I have designated for its

I am having some issues with deploying my app and need some help. Here are the details: Using the free plan on Heroku On other devices, only the background image/color/pattern is visible Errors on other devices (mainly related to Redux): On Firefox ...

Sending product identification to content_ids for Facebook Pixel tracking

Looking to implement Facebook Pixel for tracking the ViewContent event on product pages. According to Facebook, it's necessary to provide content_ids or contents along with a content_type. I assume that the content_type should always be 'product ...

Performing two ajax calls within a non-existent div that has only just been appended

I've been developing a website similar to 9gag. I attempted to incorporate a voting feature created by someone else, as I'm not well-versed in AJAX requests, but it just doesn't seem to be functioning. My index.php file fetches five posts f ...

Error: Attempting to use the map method on currentTodos, which is not

When attempting to send the currentTodos array to Cardhouse, I encountered an issue. I want to pass the currentTodos array from seach-result.component.jsx to the render loop in card-house.component.jsx. Unfortunately, it resulted in an error stating "TypeE ...

Retrieve data from jQuery and send it to PHP multiple times

<input type="checkbox" value="<?= $servicii_content[$j]['title'] ?>" name="check_list" id="check" /> By using jQuery, I am able to extract multiple values from the table above once the checkboxes are checked. Here's how: var te ...

Struggling to set up the connection between React-Redux connect and the Provider store

Currently utilizing Redux with React Native for state management. I've set up the store and Provider successfully it seems, as I can utilize store.getState() and store.dispatch(action()) from any component without issue. However, I'm encountering ...

Cannot access JS variable within Ionic framework

I'm attempting to use a basic JavaScript function to manipulate a div, but I keep encountering an error related to the variable being used: originalText is not defined main.js code: declare var orginalText: any; imports ... export class HomePag ...

Top method to gather all necessary inputs

I am dealing with a form that contains several required fields. You can find an example here <div class="form-group"> <label class="col-md-3 control-label" for="mpassword">Password<span class="required">* </span>< ...