So I have a small script that I am using to find the distance between locations using Maps. Most people would want to use the shortest recommended route, but I am trying to find the longest. Here is the start of the current script:
function googlemaps (start_address, end_address) {
start_address = "Starbucks, 799 A St, Hayward, CA 94541";
end_address = "Hayward BART Station, 699 B St, Hayward, CA 94541";
var mapObj = Maps.newDirectionFinder();
mapObj.setOrigin(start_address);
mapObj.setDestination(end_address);
var directions = mapObj.getDirections();
Logger.log(directions["routes"]);
Logger.log(directions["routes"].length);
};
When I look on Google maps for the directions of the above address, I can see that there are three possible routes, but when I try to find the length of the array, it just says 1. I'm not sure what I am missing
Modification points:
In your situation, you can retrieve other patterns using setAlternatives(true). Ref This has also already been mentioned in the comment.
In order to retrieve the longest you expect, it is required to retrieve it from the response values.
When these are reflected in your script, how about the following modification?
Modified script:
function googlemaps(start_address, end_address) {
start_address = "Starbucks, 799 A St, Hayward, CA 94541";
end_address = "Hayward BART Station, 699 B St, Hayward, CA 94541";
var mapObj = Maps.newDirectionFinder();
mapObj.setOrigin(start_address);
mapObj.setDestination(end_address);
mapObj.setAlternatives(true); // Added
var directions = mapObj.getDirections();
var res = directions.routes.sort((a, b) => a.legs[0].distance.value > b.legs[0].distance.value ? -1 : 1)[0]; // Modified
console.log(res.legs[0].distance.value); // Modified
// console.log(res); // Here, you can see the object of `the longest`.
}
When this script is run, you can retrieve the object of the longest as res. In this modification, in order to retrieve the object of the longest, I used sort.
References:
setAlternatives(useAlternatives)
sort()
Related
I'd like to call this custom formula in Google sheets +100 times. Can I add an array to this script?
function GOOGLEMAPS(start_adress,end_adress) {
var mapObj = Maps.newDirectionFinder();
mapObj.setOrigin(start_adress);
mapObj.setDestination(end_adress);
var directions = mapObj.getDirections();
var meters = directions["routes"][0]["legs"][0]["distance"]["value"];
var distance = meters/1000;
return distance;
}
You might add an array but this could easily lead to exceed the quota of the number calls being done in a short period of time, also it could exceed the maximum execution time for a custom function (30 seconds) so the advise is to not do that when using the Map Service.
Anyway, you could send an array to a custom function by useing a A1:B2 style reference justlimit the number of distances to be calculated in order to prevent the errors mentioned above.
function GOOGLEMAPS(arr) {
var output = [];
for(var i = 0; i < arr.length; i++){
var start_address = arr[i][0];
var end_adress = arr[i][1];
var mapObj = Maps.newDirectionFinder();
mapObj.setOrigin(start_adress);
mapObj.setDestination(end_adress);
var directions = mapObj.getDirections();
var meters = directions["routes"][0]["legs"][0]["distance"]["value"];
var distance = meters/1000;
output.push([distance]);
}
return output;
}
Resource
https://developers.google.com/apps-script/guides/sheets/functions#guidelines_for_custom_functions
Related
Errors When Calculating Distance Between Two Addresses
Google Sheets JSON Error: "Service invoked too many times for one day:"
Other related
Google Apps Script - How to get driving distance from Maps for two points in spreadsheet
For these inputs:
Origin
Destination
Arrival Time
I want two Google Sheets formulas that result in showing:
the distance in miles
travel times (driving, with traffic).
It'd be simple formulas that reference cells in the sheet that goes something like
=TravelTime(Origin,Destination,Arrive)
I've set up a Google Directions API account and pieced together this so far, but I have no idea how to get the URL to work and how to get the formula to return the outputs I want.
function TravelTime(Origin,Destination,Arrive) {
var Origin
var Destination
var Arrive
var apiUrl = 'https://maps.googleapis.com/maps/api/directions/json?origin='&Origin&'&destination='&Destination&'&key=MYKEY';
}
It seems you are trying to call an external API.
Try doing something like this:
function TravelTime(Origin,Destination,Arrive) {
var apiUrl = 'https://maps.googleapis.com/maps/api/directions/json?origin='&Origin&'&destination='&Destination&'&key=MYKEY';
var response = UrlFetchApp.fetch(apiUrl);
var json = response.getContentText();
var data = JSON.parse(json); //your final object, get the data you want here then return it.
}
Hope it helps!
I've been quite overwhelmed with all of this as I am completely new to working with APIs. I would like to populate a Google Sheet with a channel's videos so that I can always have its stats updated anytime I need while adding (or replacing the oldest) new videos to the list. I tried following a video guide and feel like I'm close but I'm having troubles.
NOTE: The playlistID I used below is for the Google Developers channel.
The video I watched showed an example where the videos being pulled were the top search results for a specific keyword. I would instead like to pull the last 50 videos from a specific channel.
The original code had the line:
var sr = YouTube.Search.list("snippet,id", { q: "guitars", maxResults: 50});
I changed that to:
var sr = YouTube.PlaylistItems.list("snippet,id", { playlistId: "UU_x5XG1OV2P6uZZ5FSM9Ttw", maxResults: 50});
The problem seems to be in this line:
var srVidsOnly = sr.items.filter(function(res){ return res.resourceId.kind === "youtube#playlistItems"});
I tried going through this and after many trial-and-error attempts, gave up. I'm not sure what this line is supposed to look like at all.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
var sr = YouTube.PlaylistItems.list("snippet,id", { playlistId: "UU_x5XG1OV2P6uZZ5FSM9Ttw", maxResults: 50});
var srVidsOnly = sr.items.filter(function(res){ return res.resourceId.kind === "youtube#playlistItems"});
var modRes = srVidsOnly.map(function(v){ return [v.resourceId.videoId,v.snippet.title]; });
var ids = modRes.map(function(res){return res[0]; }).join(",");
var stats = YouTube.Videos.list("statistics", {id: ids});
var vidStats = stats.items.map(function(res){return [res.statistics.viewCount, res.statistics.likeCount]; });
activeSheet.getRange(2, 1, modRes.length, modRes[0].length).setValues(modRes);
activeSheet.getRange(2, 3, vidStats.length, vidStats[0].length).setValues(vidStats);
}
The error given is:
TypeError: Cannot read property "kind" from undefined. (line 6, file "Code")
Removing kind from the fifth line, like this:
var srVidsOnly = sr.items.filter(function(res){ return res.resourceId === "youtube#playlistItems"});
gives the error:
TypeError: Cannot read property "length" from undefined. (line 12, file "Code")
Following the initial video guide exactly worked (videos from search result). The sheet was formatted just as I wanted it. I just need videos from a specific channel rather than a search results.
Thanks
How about this modification?
Modification points:
Please modify as follows.
res.resourceId.kind to res.kind
youtube#playlistItems to youtube#playlistItem
v.resourceId.videoId to v.snippet.resourceId.videoId.
So when above modifications are reflected to your script, it becomes as follows.
Modified script:
Please modify myFunction() in your script as follows.
From:
var srVidsOnly = sr.items.filter(function(res){ return res.resourceId.kind === "youtube#playlistItems"});
var modRes = srVidsOnly.map(function(v){ return [v.resourceId.videoId,v.snippet.title]; });
To:
var srVidsOnly = sr.items.filter(function(res){ return res.kind === "youtube#playlistItem"});
var modRes = srVidsOnly.map(function(v){ return [v.snippet.resourceId.videoId,v.snippet.title]});
Note:
From your script, I understood that you are using Google Apps Script and Advanced Google Services.
References:
PlaylistItems
PlaylistItems: list
If I misunderstood your question and this was not the result you want, I apologize.
I have some codes to return the tasks in one of my tasklist.
Problem is that it is only returning only 19 task at a time. It that normal if so how to I work around it
Code is use are
var tasks=Tasks.Tasks.list(tasklistID);
return tasks
You want to retrieve all tasks from a task list using Google Apps Script.
The task list has over 100 tasks.
You have already been able to use Tasks API.
If my understanding is correct, how about this modified script?
Modification points:
At Tasks.Tasks.list(), maxResults is 20 as the default.
In your case, it uses maxResults: 100 which is the maximum value. By this, it can reduce the number of API calls.
When over 100 tasks are retrieved, the property of nextPageToken is required to be used.
This has mentioned by Cooper's comment.
When above points are reflected to your script, it becomes as follows.
Modified script:
var tasklistId = "###"; // Please set this.
var list = [];
var pageToken = "";
do {
var res = Tasks.Tasks.list(tasklistId, {maxResults: 100, pageToken: pageToken});
Array.prototype.push.apply(list, res.items);
pageToken = res.nextPageToken;
} while (pageToken);
Logger.log(list) // You can retrieve all tasks with "list".
Note:
When you use this script, please enable Tasks API at Advanced Google Services.
Although this has not been mentioned, if you want to retrieve all tasks including the completed tasks, please modify var res = Tasks.Tasks.list(tasklistId, {maxResults: 100, pageToken: pageToken}) as follows.
var res = Tasks.Tasks.list(tasklistId, {maxResults: 100, pageToken: pageToken, showHidden: true})
Reference:
Advanced Google Services
Tasks: list
If I misunderstood your question and this was not the result you want, I apologize.
I am new to decoding hence I am unable to decode below response while using UrlFetchApp.
Below is the function I am using to fetch data but getting values in unicode which I need to decode. Any function that I can use to decode this?
function scrape() {
var url = UrlFetchApp.fetch("https://immi.homeaffairs.gov.au/visas/working-in-australia/skillselect/invitation-rounds");
var elements =/id="ctl00_PlaceHolderMain_PageSchemaHiddenField_Input" (.*?)\/>/gim;
var x = url.getContentText().match(elements);
Logger.log(x);
}
Although I'm not sure whether this is the best way, how about this modification?
Modified script:
function scrape() {
var url = UrlFetchApp.fetch("https://immi.homeaffairs.gov.au/visas/working-in-australia/skillselect/invitation-rounds");
var elements =/id="ctl00_PlaceHolderMain_PageSchemaHiddenField_Input" (.*?)\/>/gim;
var x = url.getContentText().match(elements);
var res = unescape(x[0].replace(/\\u/g, "%u")); // Added
Logger.log(res)
}
Result:
When above modified script is used, as a sample, the values are converted as follows.
From:
\u003cp\u003eThe table below shows the number of invitations issued in the SkillSelect invitation round on 11 September 2018.\u003c/p\u003e\n\n\u003ch3\u003eInvitations issued on 11 September 2018\u003c/h3\u003e\n\n
To:
<p>The table below shows the number of invitations issued in the SkillSelect invitation round on 11 September 2018.</p>\n\n<h3>Invitations issued on 11 September 2018</h3>\n\n
References:
unescape()
replace()
If I misunderstand your question, I'm sorry.
function scrape() {
var url = UrlFetchApp.fetch("https://immi.homeaffairs.gov.au/visas/working-in-australia/skillselect/invitation-rounds");
var elements =/id="ctl00_PlaceHolderMain_PageSchemaHiddenField_Input" (.*?)\/>/gim;
var x = url.getContentText().match(elements);
var res = unescape(x[0].replace(/\\u/g, "%u")); // Added
Logger.log(res)
}