Companies House, extracting data from the response (rest API) - javascript

I'm using Companies House API with a small google apps script. I want to retrieve the company numbers for a list of companies on a sheet.
I can't seem to be able to access the key/values of the response, can anyone help?
function findPayeeCHInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1")
var optionsheet = ss.getSheetByName('Options');
var payee = sheet.getRange("F6").getValue();
var my_api_key = optionsheet.getRange('C2').getValue();
//Logger.log(my_api_key);
var headers = {
"Authorization": "Basic " + Utilities.base64Encode(my_api_key+":"),
}
var params = {
"method":"GET",
"headers":headers,
muteHttpExceptions: true,
};
var url = "https://api.companieshouse.gov.uk/search/companies?q=" + payee;
var response = UrlFetchApp.fetch(url,params);
Logger.log(response);
}
my logger says:
[20-08-02 16:14:00:624 BST] Logging output too large. Truncating output. {"kind":"search#companies","total_results":4163,"items_per_page":20,"start_index":0,"page_number":1,"items":[{"description":"01026167 - Incorporated on 4 October 1971","snippet":"BARCLAYS BANK INTERNATIONAL ","address_snippet":"1 Churchill Place, London, E14 5HP","matches":{"title":[1,8,10,13],"snippet":[1,8,10,13]},"address":{"postal_code":"E14 5HP","address_line_1":"Churchill Place","premises":"1","address_line_2":"London"},"kind":"searchresults#company","description_identifier":["incorporated-on"],"title":"BARCLAYS BANK PLC","company_type":"plc","links":{"self":"/company/01026167"},"company_number":"01026167","company_status":"active","date_of_creation":"1971-10-04"},{"description_identifier":["incorporated-on"],"address":{"country":"England","locality":"London","premises":"1","postal_code":"E14 5HP","address_line_1":"Churchill Place"},"kind":"searchresults#company","snippet":"BARCLAYS UK AND EUROPE ","address_snippet":"1 Churchill Place, London, England, E14 5HP","matches":{"snippet":[1,8],"title":[1,8,10,13]},"description":"09740322 - Incorporated on 19 August 2015","company_number":"09740322","date_of_creation":"2015-08-19","company_status":"active","company_type":"plc","links":{"self":"/company/09740322"},"title":"BARCLAYS BANK UK PLC"},{"title":"ZEDRA TRUST
i've used different methods of addressing object values and they're either not recognised, return a null value or return everything that you see above.
I wasn't even sure it's an object, so tried addressing it as an array, with zero success. According to the documentation, this is a subset of "items", but when i try to log response.items.company_number i get
TypeError: Cannot read property 'company_number' of undefined –
The resource representation is here:
https://developer.companieshouse.gov.uk/api/docs/search-overview/CompanySearch-resource.html
any pointers will be gratefully received.

UrlFetchApp.fetch() returns HTTPResponse
Get the string from HTTPResponse and parse the string to a object
items in the response is a array of objects. Access the object inside using index of the array and then use company_name key
var httpResponse = UrlFetchApp.fetch(url,params);
var text = httpResponse.getContentText();
var object = JSON.parse(text);
var compName = object.items[0]['company_name'];
Logger.log(compName);

Related

Import CoinMarketCap Data into Google Sheets

I used CRYPTOFINANCE.ai with Google Spreadsheets for some months now and I want to move on, to be able to get cryptocurrency data by "myself".
I discover the CoinMarketCap API and that should do it. I succeed in import one or many quotes. Now I would like to import the full listings data so I can have all the prices updated, in order to get a realistic value of my portfolio.
Here is what I have now, but it isn't importing the full listings :
function price() {
var sh1=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Feuille 4');
var requestOptions = {
method: 'GET',
uri: 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest',
qs: {
'start': '1',
'limit': '5000',
'convert': 'USD'},
'headers' : {'X-CMC_PRO_API_KEY': '**********'},
'json': true,
'gzip': true};
var url='https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ETH';
var result = UrlFetchApp.fetch(url, requestOptions);
var txt= result.getContentText();
var d=JSON.parse(txt);
sh1.getRange(1, 2).setValue(d.data.ETH.quote.USD.price)
}
I know it has something to deal with: https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest but I couldn't figure it out by myself.
I am not familiar with this site but when I try the URL on its own it returns an error stating the API key is missing
{
"status": {
"timestamp": "2021-03-31T12:29:45.203Z",
"error_code": 1002,
"error_message": "API key missing.",
"elapsed": 0,
"credit_count": 0
}
}
Also, it looks like Yahoo Finance has crypto historical data for free, no API required, just make an appropriate web request. This one grabs BTC from March 31, 2020 thru March 31, 2021.
https://query1.finance.yahoo.com/v7/finance/download/BTC-USD?period1=1585662494&period2=1617198494&interval=1d&events=history&includeAdjustedClose=true
One would need to decipher the format for period1 and period2, I believe they are UNIX timestamps, I was able to confirm at this site:
https://www.unixtimestamp.com/
Then this code would download the data into the current sheet:
function importCSVFromWeb() {
// Provide the full URL of the CSV file.
var csvUrl = "function importCSVFromWeb() {
// Provide the full URL of the CSV file.
var csvUrl = "https://query1.finance.yahoo.com/v7/finance/download/BTC-USD?period1=1585662494&period2=1617198494&interval=1d&events=history&includeAdjustedClose=true";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}
BTW, it looks like Yahoo Finance gets their crypto data from CoinMarketCap
I was mistaken two requests : /listings and /quotes
Listing gives you a list of multiple currencies.
Quotes gives you data from one coin only

Request failed for https://docs.google.com returned code 401 - saving and emailing PDF files from Google Sheets

I have basically non-existent experience in Javascript, but know a little bit of Python so I figured I was up to the task of Frankensteining a couple of pre-made scripts together which I found online. The idea is to look through a list of data, then send PDFs of the appropriate spreadsheet to the desired e-mail address. I have copied my attempt below.
// This constant is written in for rows for which an email has been sent successfully.
var EMAIL_SENT = 'EMAIL_SENT';
function sendEmails2() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 16; // First row of data to process
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1, numRows, 6); // Fetch the range of cells
var data = dataRange.getValues(); // Fetch values for each row in the Range.
const token = ScriptApp.getOAuthToken();
const ss = SpreadsheetApp.getActiveSpreadsheet(); // Get the currently active spreadsheet URL (link)
const subject = 'Monthly Invoice'; // Subject of email message
const url = 'https://docs.google.com/spreadsheets/d/SS_ID/export?'.replace('SS_ID', ss.getId()); // Base URL
const exportOptions = // Specify PDF export parameters From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
'exportFormat=pdf&format=pdf' + // export as pdf / csv / xls / xlsx
'&size=A4' + // paper size legal / letter / A4
'&portrait=true' + // orientation, false for landscape
'&fitw=true&source=labnol' + // fit to page width, false for actual size
'&sheetnames=false&printtitle=false' + // hide optional headers and footers
'&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
'&fzr=false' + // do not repeat row headers (frozen rows) on each page
'&gid='; // the sheet's Id
const sheets = ss.getSheets();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[4];
var message = row[3];
var emailSent = row[5];
var client_id = row[0];
var client_sheet = ss.getSheetByName(client_id);
if (emailSent !== EMAIL_SENT) { // Prevents sending duplicates
const blobs = []; // make an empty array to hold your fetched blobs
// Convert individual worksheets to PDF
const response = UrlFetchApp.fetch(url + exportOptions + client_sheet, {
headers: {
Authorization: 'Bearer ${token}'
}
});
// convert the response to a blob and store in our array
blobs[i] = response.getBlob().setName('${client_sheet}.pdf');
// If allowed to send emails, send the email with the PDF attachment - 500 emails per day standard
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(emailAddress, subject, message, {
attachments: [blobs[i]]
});
sheet.getRange(startRow + i, 6).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
// create new blob that is a zip file containing our blob array
// const zipBlob = Utilities.zip(blobs).setName(`${ss.getName()}.zip`);
// optional: save the file to the root folder of Google Drive
// DriveApp.createFile(zipBlob);
}
I'm currently running into this error, however - and honestly I'm lost.
Request failed for https://docs.google.com returned code 401
Request failed for https://docs.google.com returned code 401. Truncated server response: <HTML> <HEAD> <TITLE>Unauthorized</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Unauthorized</H1> <H2>Error 401</H2> </BODY> </HTML> (use muteHttpExceptions option to examine full response) (line 39, file "send_emails")
If it helps, line 39 is:
const response = UrlFetchApp.fetch(url + exportOptions + client_sheet, {
Could somebody please assist? Thank you.
If you are using the script in your question, how about this answer? Please think of this as just one of several answers.
Modification point:
Unfortunately, in the current stage, the template literal, which was added at ES2015, cannot be used with Google Apps Script. I thought that the reason of your issue might be this.
Modified script:
Please modify your script as follows.
From:
Authorization: 'Bearer ${token}'
To:
Authorization: 'Bearer ' + token
And
From:
blobs[i] = response.getBlob().setName('${client_sheet}.pdf');
To:
blobs[i] = response.getBlob().setName(client_sheet + '.pdf');
References:
Basic JavaScript features
Template literals
If I misunderstood your question and this was not the result you want, I apologize.
Added:
I noticed one more modification point. Please modify your script as follows.
From:
var client_sheet = ss.getSheetByName(client_id);
To:
var client_sheet = ss.getSheetByName(client_id).getSheetId();
In order to retrieve gid, please use getSheetId().
Updated: December 19, 2020:
Now, Google Apps Script can use V8 runtime. Ref So the template literals can be used. But there is an important point. In this case, please use the backtick (grave accent) as follows.
Authorization: `Bearer ${token}`
and
blobs[i] = response.getBlob().setName(`${client_sheet}.pdf`);

Club different MQTT Topic data into one JSON string in node red

How can I club all the MQTT Topic data in one JSON String
I was able to get JSON string for the individual topic only like this
"{"time":1549737900821,"payload":"1997.32","topic":"RotateZ"}"
{"time":1549737900821,"payload":"1954.32","topic":"RotateY"}"
but I want to display all the topic data in one JSON string only for example
"{"time":1549737900821,
"RotateZ":"1997.32",
"RotateY":"1954.32"}"
I am using mentioned below code in function node
var topic = msg.topic;
var d = new Date();
var t = d.getTime();
payload = {"time":t, "payload" : msg.payload ,"topic": topic }
msg.payload = payload;
return msg;
what modification will help me to make it work?
Any suggestion on this will be a great help
Try Join node. Set Manual, Combine each msg.payload to create a key/value object using the value of msg.topic as the key. On output add timestamp in simle function like this :
var d = new Date();
msg.payload.time = d.getTime();
return msg;

Array size issue when copying GoogleSheet to another sheet

I need to get a sheet of data as an array, perform some processing, then save it to another sheet.
Without attempting any intermediate processing,
var booking = getRowsData(sheet); //should create the array
var range = target.getRange(lastDBRow+1,1,numRows); //obtains the destination range (numRows logged as 3)
then
range.setValues([booking]); //tries to save the values but throws an error "Incorrect range height, was 1 but should be 3"
Checking the booking object with
var response = ui.prompt(booking.length + " " + booking[0].length, ui.ButtonSet.OK);
shows length 3 and
booking[0].length (which I understood to be the columns) as undefined....
So why the row length mismatch?
And should the columns value be undefined?
My thanks in advance!
The full code is :
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('New booking');
var headers = sheet.getRange(1, 1,1,sheet.getLastColumn());
var lastRow = sheet.getLastRow();
var numRows= lastRow-1
var target = ss.getSheetByName('Test'); //temp redirect to test sheet
var lastDBRow =target.getLastRow(); //we want to append the data after this
var booking = getRowsData(sheet); // Get data to copy as array object
= ui.prompt(booking.length + " " + booking[0].length, ui.ButtonSet.OK);
// Returns 3 Undefined
var response = ui.prompt(numRows, ui.ButtonSet.OK);
// Returns 3
var range = target.getRange(lastDBRow+1,1,numRows); // Must match range size
range.setValues([booking]);
}
Looks to me like there is no column count defined in this range:
var range = target.getRange(lastDBRow+1,1,numRows); // Must match range size
range.setValues([booking]);
Without being about to use debug, I can't confirm my idea, but I see you are defining the starting row, the starting column and the number of rows, but not the number of columns. I don't know for sure if that error message would be caused by that, but it looks like something to consider.

Using JS to connect to an API and then output the JSON response

I'm trying to do a UK Postcode validation using JS by connecting to http://postcodes.io/ post code validation service.
When I post to api.postcodes.io/postcodes/POSTCODEVARIABLE/validate I should recieve a 200 response and result of either "True" or "False" depending on whether the postcode is valid or not.
However, when I try to receive the data (in JSON format) I get an error in the console:
"Uncaught SyntaxError: Unexpected token o in JSON at position 1"
Here is my code, if anyone could point out where I am going wrong, that would be great.
var cpostcode = 'RG1 8BT';
var cpostcode = cpostcode.replace(/\s+/g, '');
var myNewURL = 'https://api.postcodes.io/postcodes/' + cpostcode + '/validate';
var pcapi = new XMLHttpRequest();
pcapi.onreadystatechange = function() {
if (pcapi.readyState == XMLHttpRequest.DONE) {
alert(pcapi.responseText);
}
}
pcapi.open("GET", myNewURL, true);
pcapi.send(null);
var xyz = JSON.parse(pcapi);
console.log(xyz);
Like at #Youssef said you want to log the .responseText. You get that script error because pcapi is a XMLHttpRequest object and not valid json which JSON.parse() attempts to parse. If you want to learn more about what you can do with the pcapi object just console.log(pcapi) and you can see its {keys:values} or just read up on it.
JSON.parse() converts any JSON String passed into the function, to a JSON Object.
There is really no such thing as a "JSON Object". The JSON spec is a syntax for encoding data as a string. ... JSON is a subset of the object literal notation of JavaScript. In other words, valid JSON is also valid JavaScript object literal notation but not necessarily the other way around. - stackoverflow
var cpostcode = 'RG1 8BT';
var cpostcode = cpostcode.replace(/\s+/g, '');
var pcapi = new XMLHttpRequest();
var myNewURL = 'https://api.postcodes.io/postcodes/' + cpostcode + '/validate';
pcapi.open("GET", myNewURL, false);
pcapi.send();
var xyz = JSON.parse(pcapi.responseText);
console.log(xyz);

Categories