Get company name in google sheets using stock ticker - google-apps-script

I have a google sheet getting stock information by symbol. I found this code below to get prices but don't really understand how it's working.
function yahooF(ticker) {
const url = `https://finance.yahoo.com/quote/${ticker}?p=${ticker}`;
const res = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
const contentText = res.getContentText();
const price = contentText.match(/<fin-streamer(?:.*?)data-test="qsp-price"(?:.*)>(\d+\.\d+)<\/fin-streamer>/);
console.log(price[1]);
return price[1];
}
Does anyone know a way using a similar method to get specifically the company name, but understanding how to use this to get other data would be great. I'm not interested in using =GOOGLEFINANCE functions as they seem to fail pretty often.

Try, by parsing the json inside the source
function yahooFNameOfCompany(ticker) {
const url = `https://finance.yahoo.com/quote/${ticker}?p=${ticker}`;
const res = UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText();
var jsonString = res.match(/(?<=root.App.main = ).*(?=}}}})/g) + '}}}}'
var data = JSON.parse(jsonString)
console.log(data.context.dispatcher.stores.StreamDataStore.quoteData[ticker].shortName)
}

Related

Copy data from download URL using Google Script

I'm new to App scripts and need help with copying the data to spreadsheet from URL.
However, URL is not a website but link which after clicking with directly download csv file into the computer. Also, its not ending with .csv as I have seen in other examples here.
URL basically coming to my inbox at a specific time. I'm trying to use Fetch URL but its not working at all.
Sample URL -
https://docs.google.com/spreadsheets/d/1oPUPPUmy7psliSznUItT0DnHvilXwZHzyrmdyHpHi18/export?format=csv
function ABC () {
const searchQuery = 'XYZ';
const threads = GmailApp.search(searchQuery, 0,1);
const urls = [];
threads.forEach(thread => {
const messages = thread.getMessages();
messages.forEach(message => {
const body = message.getBody();
var re = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'"".,<>?«»“”‘’]))/i;
const match = body.match(re);
if (match) { urls.push(match[1]); }
});
}) ;
Logger.log(urls);
url = urls.toString().replace("[","").replace("]","") ;
Logger.log(url);
function getData() {
var attValue = '';
// making a call to the target website
var response = UrlFetchApp.fetch(url);
//logging response from target website - In Script Editor > View > Logs
Logger.log(response.getContentText());
//parsing the response data from website
//https://developers.google.com/apps-script/reference/url-fetch/http-response
var rawData = response.getContentText();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[1]);
var cell = sheet.getRange(1, 1);
cell.setValue(rawData);
}
};
Kindly help so that I can copy the data directly into spreadsheet or store the file in Google Drive with filename as combination of text and date.
Thanks
SUGGESTION
You can try the tweaked script below.
In my understanding, here is your goal:
Get your email messages that contain URLs (CSV file) via "XYZ" search terms.
Process the URL using URLFetchApp service
Place the CSV data into your second sheet tab.
Note: If there's anything else missing or something may have been misunderstood, feel free to let me know.
Tweaked Script
function ABC() {
/**TWEAKED: Created a function call method called "getData" */
const url = {
getData: function () {
const searchQuery = 'XYZ';
const threads = GmailApp.search(searchQuery, 0, 1);
const urls = [];
threads.forEach(thread => {
const messages = thread.getMessages();
messages.forEach(message => {
const body = message.getBody();
var re = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'"".,<>?«»“”‘’]))/i;
const match = body.match(re);
if (match) { urls.push(match[1]); }
});
});
Logger.log(urls);
/**TWEAKED: Instead of using the redundant replace method,
* used "regex" inside a single replace method to replace
* all [ and ] characters */
var geturl = urls.toString().replace(/\[|]/gm, "");
console.log(geturl)
return geturl;
}
}
var attValue = '';
/**TWEAKED: Call the "url" variable's "getData" function that will return the URL */
var response = UrlFetchApp.fetch(url.getData.call());
//logging response from target website - In Script Editor > View > Logs
Logger.log(response.getContentText());
//parsing the response data from website
//https://developers.google.com/apps-script/reference/url-fetch/http-response
var rawData = response.getContentText();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[1]);
var cell = sheet.getRange(1, 1);
cell.setValue(rawData);
};
Demonstration
After running the ABC() function on the Apps Script editor, the second sheet tab gets populated with the CSV data:
The Apps Script execution log view
References:
JavaScript Function call()

How to pass cell value as parameter in google apps script function?

I'm in need of some help with the final part of my code. I'm working with an API to get the name of the street and city from the government database and i use the Zip code and house number as input. The API i have working, but the final step is to pass cell values (Zip code, house number) as parameters into my formula. I cannot seem to get this working.
Here is my code:
function postHuisNaarStraat (ref1, ref2){
var PCCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref1).getValue();
var HNCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref2).getValue();
var postcode = "filters[postcode]=" + PCCell;
var huisnummer = "filters[huisnummer]=" + HNCell;
var API_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var url = "https://api.overheid.io/bag?" + postcode + "&" + huisnummer;
var response = UrlFetchApp.fetch(
url,
{
"headers":{
"ovio-api-key":API_KEY,
"Accept":"application/hal+json",
"Content-Type":"application/json"
}
}
);
// parse JSON reply
var json = response.getContentText();
var data = JSON.parse(json);
// Logger.log(data);
Logger.log(data["_embedded"]["adres"][0]["openbareruimte"]);
}
Please help me get the data from my cells (postcode, housenumber) and add their respective value in my formula.
Here is what i want to do but cant get working
Replace
var PCCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref1).getValue();
var HNCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(ref2).getValue();
by
var PCCell = ref1;
var HNCell = ref2;
or even better (as this will make your code shorter), instead of ref1 and ref2 as function argument names use PCCell and HNCell, respectivelly.
Resources
https://developers.google.com/apps-script/guides/sheets

Having trouble building a Script to look up Places in Google's API and return relevant data

I'm working on filling in data, including address, url, phone number, etc. for a list of businesses I have in a Google Sheet.
I have been on this site and others looking at scripts to call the Google Places API. I have figured out (I think) that I need to first get the Place_ID, and then I can call the API again to get all the details. I have copied and pasted a script off another answer on this forum, but it is hanging on line 8.
return placeId.candidates[0].place_id;
in this line, it appears that the code that I copied is referencing "candidates", which I don't know what this is.
I'd like this to write the Place_id to a cell in the row with the other known data. For example: A2:T2 is all the known data. In U2 I placed =locid(G2) where G2 is the full address. I'd like (I think) U2 to get the place_id and then subsequent columns to receive the other requested data.
function locId(text) {
var API_KEY = 'AIzaSyDAI35g3ocior056QvNrjgY_lLs02Jkyg4';
var baseUrl = 'https://maps.googleapis.com/maps/api/place/findplacefromtext/json';
var queryUrl = baseUrl + '?input=' + text + '&inputtype=textquery&key=' + API_KEY;
var response = UrlFetchApp.fetch(queryUrl);
var json = response.getContentText();
var placeId = JSON.parse(json);
return placeId.candidates[0].place_id;
Logger.log(placeId)
}
function GET_DETAILS(id) {
var API_KEY = 'AIzaSyDAI35g3ocior056QvNrjgY_lLs02Jkyg4';
var fields = 'name,rating,formatted_phone_number,formatted_address,photo';
var baseUrl = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=';
var queryUrl = baseUrl + id + '&fields=' + fields + '&key='+ API_KEY;
if (id == '') {
return 'Give me a Google Places URL...';
}
var response = UrlFetchApp.fetch(queryUrl);
var json = response.getContentText();
var place = JSON.parse(json).result;
return [[ place.name,
place.formatted_phone_number,
place.rating,
place.formatted_address,
place.photo
]];
}
The error I'm getting is:
TypeError: Cannot read property "place_id" from undefined. (line 8).
I'm assuming the undefined here is the 'candidates'
I'm not sure how this code should be structured to achieve what I am looking for.
I'm sure this is simple, as being a total hack noob, I have only a little understanding of what I am looking at. I appreciate your assistance in helping me understand how this works.

IMPORTJSON in Google Sheet sometimes not getting data

I have created a sheet to keep my crypto holdings. I use this importJSON function I found on youtube : (I have changed the help text for myself)
/**
* Imports JSON data to your spreadsheet Ex: IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1/?convert=EUR","data/quotes/EUR/price")
* #param url URL of your JSON data as string
* #param xpath simplified xpath as string
* #customfunction
*/
function IMPORTJSON(url,xpath){
try{
// /rates/EUR
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
//Logger.log(patharray);
for(var i=0;i<patharray.length;i++){
json = json[patharray[i]];
}
//Logger.log(typeof(json));
if(typeof(json) === "undefined"){
return "Node Not Available";
} else if(typeof(json) === "object"){
var tempArr = [];
for(var obj in json){
tempArr.push([obj,json[obj]]);
}
return tempArr;
} else if(typeof(json) !== "object") {
return json;
}
}
catch(err){
return "Error getting data";
}
}
I use this function to readout an API :
This is a piece of my script :
var btc_eur = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1/?convert=EUR","data/quotes/EUR/price");
var btc_btc = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1/?convert=BTC","data/quotes/BTC/price");
ss.getRange("B2").setValue([btc_eur]);
ss.getRange("H2").setValue([btc_btc]);
var bhc_eur = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1831/?convert=EUR","data/quotes/EUR/price");
var bhc_btc = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1831/?convert=BTC","data/quotes/BTC/price");
ss.getRange("B3").setValue([bhc_eur]);
ss.getRange("H3").setValue([bhc_btc]);
The last few days I get "Error getting data" errors. When I start manualy the script it works.
I than tried this code I found here :
ImportJson
function IMPORTJSON(url,xpath){
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
var res = [];
for (var i in json[patharray[0]]) {
res.push(json[patharray[0]][i][patharray[1]]);
}
return res;
}
But this gives an error about : TypeError: Cannot read property "quotes" from null. What am I doing wrong ?
The big problem is your script call API at least 4 times. When few users do it too, the Google server call API too much times.
The API of Coinmarketcap has limited bandwidth. When any client reach this limit, the API return HTTP error 429. Google Scripts is on shared Google servers, that means lot of users looks as one client for Coinmarketcap API.
When API decline your request, your script fails – the error message corresponds to the assumed error (xpath cant find quotes component in empty varible).
This is ruthless behavior. Please, don't ruin API via mass calls.
You can load data from API at once and re-use it angain for each finding in data.
I have similar Spreadsheet automatically filled from Coinmarketcap API, you can copy it for your:
Coins spreadsheet
Google Script on GitHub.
This my script is strictly ask API only once for whole runtime and reusing one response for all queries.
Change of your script
Also you can make few changes in your Code for saving resources:
Change IMPORTJSON function from this:
function IMPORTJSON(url,xpath){
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
...
to this:
function IMPORTJSON(json, xpath) {
...
and rutime section of code you can change like this:
var res = UrlFetchApp.fetch("https://api.coinmarketcap.com/v2/ticker/1/?convert=EUR");
var content = res.getContentText();
var json = JSON.parse(content);
var btc_eur = IMPORTJSON(json,"data/quotes/EUR/price");
var btc_btc = IMPORTJSON(json,"data/quotes/BTC/price");
ss.getRange("B2").setValue([btc_eur]);
ss.getRange("H2").setValue([btc_btc]);
...
Main benefit is: the UrlFetchApp.fetch is called only once.
Yes, I know, this code is not works 1:1 like your. That because that receive prices only for EUR and not for BTC. Naturally fetching comparation between BTC and BTC is unnecessary because it is always 1 and other values you can count matematically from EUR response – please don't abuse an api for such queries.
As Jakub said, the main issue is that all requests are counted as coming from the same Google server.
One solution which I consider easier is to put a proxy server in the middle, this can be done by either purchasing a server and setting it up (which is quite complex) or using a service like Proxycrawl which includes some free requests and after that, unless you run thousands of queries per month, it should cost you less than 1 USD per month.
To do that you just need to edit one line of the script:
var res = UrlFetchApp.fetch(url);
This line, becomes this:
var res = UrlFetchApp.fetch(`https://api.proxycrawl.com/?token=YOUR_TOKEN&url=${encodeURIComponent(url)}`);
Make sure to replace YOUR_TOKEN with your actual service token
Just this simple change will make the requests never fail as each request will be sent from a different IP instead of all coming from Google.

Google Apps Script messing up JSON values

I´m using a Google Apps Script, trying to import Bitcoin-exchange rate information to a Google Spreadsheet. I use this code:
var url = "https://btc-e.com/api/2/btc_usd/ticker";
var response = UrlFetchApp.fetch(url);
var json = response.getContentText();
var lcharts_data = JSON.parse(json)
function bitcoin(){
var b = lcharts_data["ticker"]["avg"];
return b;
}
The JSON-file looks like this:
{"ticker":
{"high":947.99902,
"low":817.64001,
"avg":882.819515,
"vol":24625847.06001,
"vol_cur":28189.09956,
"last":930,
"buy":930,
"sell":929.998,
"updated":1385575341,
"server_time":1385575342}
}
}
Yet b returns as 22.49. What am i doing wrong?
I use the similar method for receiving the data but I parse it slightly different. For example:
var url = "https://btc-e.com/api/2/btc_usd/ticker";
var response = UrlFetchApp.fetch(url);
var json = response.toString();
var lcharts_data = JSON.parse(json);
Notice the toString() method and the native Utilities.jsonParse() method. I tried JSON.parse() but that didn't work for me.
Also are using an API key to access the data? Have tried above but it's timing out.
As at when I tested your url, the JSON response returned was:
{
"ticker":{
"high":421.70001,
"low":418,
"avg":419.850005,
"vol":2361935.91952,
"vol_cur":5620.41595,
"last":420.168,
"buy":420.168,
"sell":419.853,
"updated":1460626271,
"server_time":1460626273
}
}
Here's the code that returns the value for 'avg':
var url = "https://btc-e.com/api/2/btc_usd/ticker";
var response = UrlFetchApp.fetch(url);
var json = response.getContentText();
var lcharts_data = JSON.parse(json);
function bitcoin(){
var b = lcharts_data.ticker.avg;
return b;
}