Hi what I'm trying to do is get the data from a Salesbinder invoice API (Invoice # is taken from Sheet2 Cell A1) output the data to a Google sheet (sheet Cell A2)
here's the code i'm using to get data from Salesbinder API
function fetching() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
var sheet2 = ss.getSheetByName('Sheet2');
var InvNumber = sheet2.getRange('A1').getValue();
var USERNAME = 'APIKey';
var PASSWORD = 'x';
var url = 'https://mydomain.salesbinder.com/api/2.0/documents.json?documentNumber='+InvNumber+'&contextId=5';
var headers = {
"Authorization": "Basic " + Utilities.base64Encode(USERNAME + ':' + PASSWORD)
};
let response = UrlFetchApp.fetch(url, { headers });
Logger.log(response.getContentText());
}
The result I get from the data is like this
{"document":[{"document_number":8542,"name":"VIOLET BEARINGS","context_id":5,"total_cost":7213.03,"total_tax":415.45,"total_tax2":0,"total_price":8309.08,"total_transactions":0,"issue_date":"2022-12-13T00:00:00+00:00","expiry_date":null,"shipping_address":"(Same as above)","date_sent":null,"shipped_percent":null,"status_id":9,"public_note":"","attention":"GLEN","payment_terms":"","id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","customer_id":"5b0d881b-6a88-46e5-998c-06330a8e0006","user_id":"5b0d75b3-e9cc-4899-bf99-77610a8e0006","associated_document_id":"","created":"2022-12-13T21:21:43+00:00","modified":"2022-12-21T16:01:04+00:00","status":{"id":9,"name":"unpaid"},"context":{"id":5,"name":"invoice"},"customer":{"id":"5b0d881b-6a88-46e5-998c-06330a8e0006","name":"TestClient","customer_number":1889,"billing_address_1":"Add1","billing_address_2":"Add2","billing_city":"TestCity","billing_region":"TestLoc","billing_postal_code":"TestPost","billing_country":"CANADA","shipping_address_1":"Add1","shipping_address_2":"Add2","shipping_city":"TestCity","shipping_region":"TestLoc","shipping_postal_code":"TestPost","shipping_country":"CANADA"},"user":{"first_name":"test","last_name":"test"},"document_items":[{"id":"0ea11906-f197-4eb4-971e-715d4dc77ab2","name":"B-0832","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":4,"service_category_id":"5dc2f6d2-27e0-4dac-a2b7-39080a8e0008","description":"JGE/H/K DOOR GASKET","quantity":8,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":38.1,"price":43.81,"discounted_price":0,"weight":2,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-15T15:43:57+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null},{"id":"2b7e9376-ed70-4e75-95c9-6237aad8cfc0","name":"B-0770","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":4,"service_category_id":"5dc2f6d2-27e0-4dac-a2b7-39080a8e0008","description":"MAIN BEARING JGE/H/K","quantity":8,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":282.73,"price":325.14,"discounted_price":0,"weight":6,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-15T15:43:57+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null},{"id":"391c2ec1-e02d-4390-9a10-429c2ea460fc","name":"B-2082","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":4,"service_category_id":"5dc2f6d2-27e0-4dac-a2b7-39080a8e0008","description":"ROD BEARING JGE/H/K","quantity":8,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":282.73,"price":325.14,"discounted_price":0,"weight":5,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-15T15:43:57+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null},{"id":"725fb97d-243f-44aa-98d0-50d903871ae4","name":"B-0776","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":4,"service_category_id":"5dc2f6d2-27e0-4dac-a2b7-39080a8e0008","description":"THRUST PLATE JGE/H/K","quantity":2,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":878.44,"price":1010.21,"discounted_price":0,"weight":7,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-15T15:43:57+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null},{"id":"956cf37e-3921-4cad-94bf-670cdedd2d17","name":"B-1032","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":4,"service_category_id":"5dc2f6d2-27e0-4dac-a2b7-39080a8e0008","description":"JGK DOOR GASKET","quantity":8,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":17.21,"price":19.79,"discounted_price":0,"weight":3,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-15T15:43:57+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null},{"id":"c2b74c55-465b-4bee-84a1-6c9e8e5bd102","name":"A-0661","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":4,"service_category_id":"5dc2f6d2-27e0-4dac-a2b7-39080a8e0008","description":"OIL FILTER","quantity":3,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":24.5,"price":28.18,"discounted_price":0,"weight":4,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-15T15:43:57+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null},{"id":"de2c8695-9589-4856-be7a-d3979a776646","name":"FREIGHT CHARGE","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":1,"service_category_id":"5e6a78e2-cf6c-437c-ac52-0c3a0a8e000a","description":"RE:E2920103","quantity":1,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":70.64,"price":95.35,"discounted_price":0,"weight":8,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-21T15:34:51+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null},{"id":"eab3c271-20ce-4c4e-af92-8553425eaa71","name":"C-6200","document_id":"0b24e8d2-e7cc-4441-abd7-337c8a2c6cf1","item_id":null,"unit_id":4,"service_category_id":"5dc2f6d2-27e0-4dac-a2b7-39080a8e0008","description":"TOP COVER GASKET","quantity":1,"quantity_partially_received":0,"quantity_partially_shipped":0,"tax":5,"tax2":0,"discount_percent":0,"cost":345.85,"price":397.73,"discounted_price":0,"weight":1,"modified":"2022-12-21T16:01:04+00:00","created":"2022-12-13T21:21:43+00:00","item_variations_location_id":null,"item_variation_data":null,"delete":false,"item":null}]}]}
I would like to output the JSON content to look like this on my google sheet
https://docs.google.com/spreadsheets/d/18x1cyztf5SgnKZHjqgWx2iP7SzQAksOzE_EVZoUOcy8/edit#gid=0
Any help would be greatly appreciated
Thanks
In your script, when the value of response.getContentText() is your showing data, how about the following modification?
From:
Logger.log(response.getContentText());
To:
Logger.log(response.getContentText());
// I added the below script.
const value = JSON.parse(response.getContentText());
const addValues = [value.document[0].customer.name, value.document[0].issue_date, value.document[0].attention, value.document[0].name];
const res = value.document[0].document_items.map(o => [value.document[0].document_number, ...["name", "description", "quantity", "price", "discounted_price"].map(h => o[h]), ...addValues]);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
sheet.getRange(sheet.getLastRow() + 1, 1, res.length, res[0].length).setValues(res);
Please set your sheet name to getSheetByName("Sheet1").
Unfortunately, I cannot find External PO# you expect from your data.
Suggestion: Clean and Extract the Required Data
The first thing I noticed is that your current script has already extracted a single JSON object from Salesbinder. However, the format returned is hard to read. You may use JSON beautify sites online to rearrange and analyze the JSON object you have produced like JSON Viewer (DISCLAIMER: I am not affiliated with the website, I just find it helpful to share it to others due to its helpful features).
Script
Afterwards, you may be able to access the data you wanted by accessing the JSON object. For your table, you may use the following:
var salesBinderInvoiceNumVal = object.document[0].document_number;
var itemNameVal = object.document[0].document_items[0].name;
var descriptionVal = object.document[0].document_items[0].description;
var quantityVal = object.document[0].document_items[0].quantity;
var priceVal = object.document[0].document_items[0].price;
var discountPercentVal = object.document[0].document_items[0].discount_percent;
var clientNameVal = object.document[0].customer.name;
var issueDateVal = object.document[0].issue_date;
var attentionVal = object.document[0].attention;
var nameVal = object.document[0].name;
Note: The External PO number can't be found since there are no given values in your sample table.
But before doing so, you may want to store the generated JSON object to a variable. Thus, you may change:
Logger.log(response.getContentText());
to:
var object = response.getContentText();
Afterwards, you may add the setValues() function to add the values to the last row of your table. Thus, your script should be somewhat like this:
function fetching() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
var sheet2 = ss.getSheetByName('Sheet2');
var InvNumber = sheet2.getRange('A1').getValue();
var USERNAME = 'APIKey';
var PASSWORD = 'x';
var url = 'https://mydomain.salesbinder.com/api/2.0/documents.json?documentNumber=' + InvNumber + '&contextId=5';
var headers = {
"Authorization": "Basic " + Utilities.base64Encode(USERNAME + ':' + PASSWORD)
};
let response = UrlFetchApp.fetch(url, { headers });
//Changes start here
var object = response.getContentText(); //Store the JSON object to this variable
var lastRow = sheet.getLastRow(); //get the last row
//required values
var salesBinderInvoiceNumVal = object.document[0].document_number;
var itemNameVal = object.document[0].document_items[0].name;
var descriptionVal = object.document[0].document_items[0].description;
var quantityVal = object.document[0].document_items[0].quantity;
var priceVal = object.document[0].document_items[0].price;
var discountPercentVal = object.document[0].document_items[0].discount_percent;
var clientNameVal = object.document[0].customer.name;
var issueDateVal = object.document[0].issue_date;
var attentionVal = object.document[0].attention;
var nameVal = object.document[0].name;
//add the required values to a 2d array
var output = [[salesBinderInvoiceNumVal, itemNameVal, descriptionVal, quantityVal, priceVal, discountPercentVal, clientNameVal, issueDateVal, attentionVal, nameVal]];
sheet.getRange(lastRow+1, 1, 1, output[0].length).setValues(output); //add the 2d array to the last row of your table
}
Output:
Since your script only gets the value of one cell, I assumed that it only fetches one item or one row to your table. NOTE: I only processed the given JSON object in your post since I have no access/account in Salesbinder. I did assume that it was the output of your current script.
Reference:
You may further study about accessing JSON objects date in this article: JSON Object Literals
I have a simple Apps Script need, but can't find a near enough sample from the community.
I need to convert 2 sheets from a Google Spreadsheet, individually, as CSV files then attach them in an email.
So far, I found a script to convert a sheet into a CSV format and file it in a folder.
I looked for a script to add that will instead attach the CSV file to an email, but can't find anything which I can use based on my novice level of Apps Script knowledge.
Any help will be greatly appreciated. Thank you very much.
Script:
function sheet1ToCsv()
{
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheet_Name = "xxxx"
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet_Name)
var sheetNameId = sheet.getSheetId().toString();
params= ssID+"/export?gid="+sheetNameId +"&format=csv"
var url = "https://docs.google.com/spreadsheets/d/"+ params
var result = UrlFetchApp.fetch(url, requestData);
var folderId = "yyyy";
var csvContent = {
title: sheet_Name+".csv",
mimeType: "application/vnd.csv",
parents: [{id: folderId}]
}
var fileJson = Drive.Files.insert(csvContent,result)
}
In your showing script, an email is not sent. And, only one CSV file is created to Google Drive. From I need to convert 2 sheets from a Google Spreadsheet, individually, as CSV files then attach them in an email. and your showing script, when your showing script is modified, how about the following modification?
Modified script:
function myFunction() {
var emailAddress = "###"; // Please set your email address.
var sheetNames = ["Sheet1", "Sheet2"]; // Please set your 2 sheet names you want to use.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssID = ss.getId();
var requestData = { "method": "GET", "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
var blobs = sheetNames.map(s => {
var params = ssID + "/export?gid=" + ss.getSheetByName(s).getSheetId() + "&format=csv";
var url = "https://docs.google.com/spreadsheets/d/" + params;
return UrlFetchApp.fetch(url, requestData).getBlob().setName(s); // <--- Modified
});
MailApp.sendEmail({ to: emailAddress, subject: "sample subject", body: "sample body", attachments: blobs });
}
When this script is run, an email is sent by including 2 CSV files as the attachment files.
References:
map()
sendEmail(message)
function myfunk() {
const folder = DriveApp.getFolderById("folderid");
const ss = SpreadsheetApp.getActive();
const names = ["Sheet1", "Sheet2"];
const params = { "method": "GET", "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
let bA = [];
names.forEach(n => {
let sh = ss.getSheetByName(n);
let url = "https://docs.google.com/spreadsheets/d/" + ss.getId() + "/export?gid=" + sh.getSheetId() + "&format=csv";
let r = UrlFetchApp.fetch(url, params);
let csv = r.getContentText();
let file = folder.createFile(n, csv, MimeType.CSV);
bA.push(file.getBlob());
})
GmailApp.sendEmail(recipient, subject, body, { attachments: bA })
}