I would like to create a custom function that pulls a Drive URL from a file name in Google Sheets.
So, using the code below:
This may be a solution for some needs.
My particular need was: loop through a column of file names and pull the Google Docs URL at a set interval. The code below just loops through filenames in "Column A"
of "My Sheet"
and returns the value into the adjacent cell of "Column B"
(starting at row 2 because I had column headers). I'm not concerned about security because I'm only referencing internal organization files.
To get the code below to work you need to:
replaceFileColumn
in the select field within that modal)My mistake was: thinking that I needed to use a custom function in each cell to do so. (I still don't fully understand the auth reasons why this wouldn't work, so if anyone could explain in lay-man's terms that would be fabulous; my solution is just a workaround for expediency's sake).
In my spreadsheet I have a time-driven trigger calling replaceFileColumn()
Hope this helps someone!
function getMyFile(cell) {
var filename = encodeURI(cell);
var files = DriveApp.getFilesByName(cell);
while (files.hasNext()) {
var file = files.next();
if(file){
var fileValue = file.getUrl();
return(fileValue);
};
};
}
function replaceFileColumn() {
var spreadsheet = SpreadsheetApp.getActive().getSheetByName('My Sheet');
var range = spreadsheet.getRange("A2:A");
var range_update = spreadsheet.getRange("B2:B");
var values = range.getValues();
for (var i = 0; i < values.length; i++) {
var fileName = values[i];
var getFileUrl = getMyFile(fileName);
values[i][0] = getFileUrl;
}
range_update.setValues(values);
}
Custom functions runs as if run by a anonymous animal(user). ScriptApp.getOAuthToken
will return a anonymous token without the required scopes. What you're attempting is not possible, unless the file in question is public.
@I'-'I's answer is correct. Although I'm not sure whether this is what you want, how about this workaround? I have also experienced the same issue. At that time, I had used the following workaround.
The flow is as follows.
Please install this function as the time-driven trigger. Of course, you can run manually this function.
function setAccessToken() {
PropertiesService.getScriptProperties().setProperty("accessToken", ScriptApp.getOAuthToken());
}
In your script, please modify as follows.
From:var params = {
method: "GET",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
To:
var params = {
method: "GET",
headers: {"Authorization": "Bearer " + PropertiesService.getScriptProperties().getProperty("accessToken")},
muteHttpExceptions: true
};