Zoho Books API - Google Sheets

1.3k Views Asked by At

I am recording my sales details in Google Sheets and am using Zoho Books to maintain my books of accounts. I want to use Zoho Books API to sync data between google sheets and Zoho Books. I have done the following till now:

  1. Created a Self-Client in Zoho API Console to generate a Client ID and Client Secret
  2. Generated an authorization code for all Scopes under Invoices in the Zoho API Console
  3. Generated an access token and refresh token - using Postman
  4. Wrote the following code in Google Apps Script to create an invoice with dummy data
function ZohoInvoice() {
  var invoice = {
    customer_id: '2298656000000277003',
    invoice_number: 'MU001',
    date: '2021-09-02',
    line_items: [
      {
        item_id: '2298656000002380000',
        name: 'Item1',
        description: 'This is the description',
        rate: '1500.00',
        quantity: '2',
      },
    ],
    notes: 'These are the notes of this Invocie'
  };

  var zohoOauthToken = '1000.827612479824c7c66132118bb242e15942aa6a.4e63c9fd60a343658904a54191c4c32';
  var zohoOrganization = '19012342064';

  var zohoUrl = [
    'https://books.zoho.com/api/v3/invoices?',
    'organization_id=',
    zohoOrganization,
    '&authtoken=',
    zohoOauthToken,
    '&JSONString=',
    encodeURIComponent(JSON.stringify(invoice)),
  ].join('');

  try {
    var response = UrlFetchApp.fetch(zohoUrl, {
      method: 'POST',
      muteHttpExceptions: true,
    });
    var result = JSON.parse(response.getContentText());
    Logger.log(result.message);
  } catch (error) {
    Logger.log(error.toString());
  }
}

The above code throws an error Invalid value passed for authtoken.

Unsure where am I going wrong?

1

There are 1 best solutions below

7
On

Modification points:

  • When I saw the official document of "Create an invoice" for Books API, it seems that the sample curl command is as follows.

      $ curl https://books.zoho.com/api/v3/invoices?organization_id=10234695
      -X POST
      -H "Authorization: Zoho-oauthtoken 1000.41d9f2cfbd1b7a8f9e314b7aff7bc2d1.8fcc9810810a216793f385b9dd6e125f"
      -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8"
      -F 'JSONString="{,,,}"'
    
    • In this case, the token is required to be included in the request header.
    • But, I thought that in this curl command, the value of JSONString might not be correctly parsed at the server side, because of the content type is application/x-www-form-urlencoded. So I'm not sure whether this sample curl command of this official document is correct. I thought that in this case, -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" might not be required to be used. I'm worry about this. So, please test the following modified script.

When above points are reflected to your script, it becomes as follows. The following modified script is from above sample curl command.

Modified script:

Please set zohoOauthToken of your token.

var invoice = {
  customer_id: '2298656000000277003',
  invoice_number: 'MU001',
  date: '2021-09-02',
  line_items: [
    {
      item_id: '2298656000002380000',
      name: 'Item1',
      description: 'This is the description',
      rate: '1500.00',
      quantity: '2',
    },
  ],
  notes: 'These are the notes of this Invocie'
};
var zohoOauthToken = '###';
var zohoOrganization = '19012342064';

var baseUrl = "https://books.zoho.com/api/v3/invoices";
var url = baseUrl + "?organization_id=" + zohoOrganization;
var params = {
  method: 'POST',
  contentType: "application/x-www-form-urlencoded",
  payload: {JSONString: Utilities.newBlob(JSON.stringify(invoice), "application/json")}, // or null instead of "application/json"
  headers: {Authorization: "Zoho-oauthtoken " + zohoOauthToken},
  muteHttpExceptions: true,
};
var response = UrlFetchApp.fetch(url, params);
console.log(response.getContentText());

Note:

I think that above modified request is the same with the sample curl command for "Create an invoice". But, if above modified script occurs an error, please try the following patterns.

Pattern 1:

For above modified script, please modify params as follows and test it again.

var params = {
  method: 'POST',
  payload: {JSONString: Utilities.newBlob(JSON.stringify(invoice), "application/json")},
  headers: {Authorization: "Zoho-oauthtoken " + zohoOauthToken},
  muteHttpExceptions: true,
};
Pattern 2:

For above modified script, please modify params as follows and test it again. From OP's test, it was found that this sample request was correct.

var params = {
  method: 'POST',
  contentType: "application/json",
  payload: {JSONString: JSON.stringify(invoice)},
  headers: {Authorization: "Zoho-oauthtoken " + zohoOauthToken},
  muteHttpExceptions: true,
};

or

var params = {
  method: 'POST',
  contentType: "application/json",
  payload: JSON.stringify(invoice),
  headers: {Authorization: "Zoho-oauthtoken " + zohoOauthToken},
  muteHttpExceptions: true,
};

References:

Added:

When OP tested my proposed scripts, OP said the working script is The first one under Pattern 2. In this case, it seems that the sample curl command at the official document is not correct. When The first one under Pattern 2 is converted to the curl command, it's as follows. In this sample curl command is from the top of my answer.

$ curl https://books.zoho.com/api/v3/invoices?organization_id=10234695
-X POST
-H "Authorization: Zoho-oauthtoken 1000.41d9f2cfbd1b7a8f9e314b7aff7bc2d1.8fcc9810810a216793f385b9dd6e125f"
-H "Content-Type: application/json;charset=UTF-8"
-F 'JSONString="{,,,}"'

The Google Apps Script is as follows.

var invoice = {
  customer_id: '2298656000000277003',
  invoice_number: 'MU001',
  date: '2021-09-02',
  line_items: [
    {
      item_id: '2298656000002380000',
      name: 'Item1',
      description: 'This is the description',
      rate: '1500.00',
      quantity: '2',
    },
  ],
  notes: 'These are the notes of this Invocie'
};
var zohoOauthToken = '###';
var zohoOrganization = '19012342064';

var baseUrl = "https://books.zoho.com/api/v3/invoices";
var url = baseUrl + "?organization_id=" + zohoOrganization;
var params = {
  method: 'POST',
  contentType: "application/json",
  payload: {JSONString: JSON.stringify(invoice)},
  headers: {Authorization: "Zoho-oauthtoken " + zohoOauthToken},
  muteHttpExceptions: true,
};
var response = UrlFetchApp.fetch(url, params);
console.log(response.getContentText());