Reputation: 5051
Trying to create a new project with files with a call to the Drive SDK within Apps Script.
Where exactly would the following go in a UrlFetchApp
request...
{
"files": [
{
"id":"9basdfbd-749a-4as9b-b9d1-d64basdf803",
"name":"Code",
"type":"server_js",
"source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
},
{
"id":"3asf7c0d-1afb-4a9-8431-5asdfc79e7ae",
"name":"index",
"type":"html",
"source":"\u003chtml\u003e\n \u003cbody\u003e\n New message!!\n \u003c/body\u003e\n\u003c/html\u003e"
}
]
}
It's from the import/export docs and in the example video Dan mentions the calls are for languages outside of Apps Script but requesting a list of script file types and the content of those files does work once the authorization is setup with Eric's oAuth2 library.
My most recent guess...
function createProject( ) {
var token = getDriveService().getAccessToken(); // from Eric's oAuth2 lib
var url = 'https://www.googleapis.com/upload/drive/v2/files?convert=true';
// Where does this go?
var files = {
"files": [
{
"name":"Code",
"type":"server_js",
"source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
},
{
"name":"index",
"type":"html",
"source":"\u003chtml\u003e\n \u003cbody\u003e\n Hello, world!!\n \u003c/body\u003e\n\u003c/html\u003e"
}
]
};
// Where does this go too?
var metadata = {
'title': 'script-test1',
'mimeType': 'application/vnd.google-apps.script',
"parents": [
{
"id": "0B2VkNbQMTnaCODBRVjZQcXBXckU"
}
],
};
var options = {
'headers' : {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/vnd.google-apps.script+json',
},
'method' : 'POST',
'payload' : files // probably not right
};
var response = UrlFetchApp.fetch(url, options);
Logger.log(response.getResponseCode());
}
An untitled Drive file of unknown type does get created and the payload does get inserted into it, but it's not converted to a script file type.
Going another route and just using...
var file = {
"title": "Test script",
"mimeType": "application/vnd.google-apps.script",
"parents": [
{
"id": "[INSERT FOLDER ID HERE]"
}
]
};
Drive.Files.insert(file);
...throws an Internal error.
Also aware of the Drive insert docs that have a client-side JS example, but don't know how much of it should be translated over (if possible) to server-side Apps Script.
Upvotes: 3
Views: 995
Reputation: 1424
You're almost there, but you have a few mistakes. Your first approach (using UrlFetch
) has some errors in the options
variable. Here's a doGet() function that (after verifying authorization) creates a new Apps Script Project and writes the UrlFetch response to the page:
function doGet() {
var driveService = getDriveService();
if (!driveService.hasAccess()) {
var authorizationUrl = driveService.getAuthorizationUrl();
var template = HtmlService.createTemplate(
'<a href="<?= authorizationUrl ?>" target="_blank">Authorize</a>. ' +
'Refresh the page when authorization complete.');
template.authorizationUrl = authorizationUrl;
var page = template.evaluate();
return page;
} else {
var url = "https://www.googleapis.com/upload/drive/v2/files?convert=true";
var requestBody = {
"files": [
{
"name":"Code",
"type":"server_js",
"source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
},
{
"name":"index",
"type":"html",
"source":"\u003chtml\u003e\n \u003cbody\u003e\n Created with Apps Script.\n \u003c/body\u003e\n\u003c/html\u003e"
}
]
};
var options = {
"headers": {
'Authorization': 'Bearer ' + driveService.getAccessToken(),
},
"contentType": "application/vnd.google-apps.script+json",
"method" : "post",
"payload": JSON.stringify(requestBody)
}
var response = UrlFetchApp.fetch(url, options);
return HtmlService.createHtmlOutput(response.getContentText());
}
}
This code creates an Apps Script project file called "Untitled" in the root Drive folder. The options
object should specify POST as the method for creating projects (default is GET), and the payload needs to be converted to a string from a JSON object to be understood by UrlFetch
.
Alternatively, you can do the same thing by using the Advanced Drive Service in Apps Script instead of UrlFetch
. The following code creates the same Apps Script project (but places it in the specified folder and names the file 'Test script'):
function createGoogleFileInFolder3() {
var requestBody = {
"files": [
{
"name":"Code",
"type":"server_js",
"source":"function doGet() {\n return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
},
{
"name":"index",
"type":"html",
"source":"\u003chtml\u003e\n \u003cbody\u003e\n Created with Apps Script.\n \u003c/body\u003e\n\u003c/html\u003e"
}
]
};
var resource = {
"title": "Test script",
"parents": [
{
"id": "<parent folder id here>"
}
]
};
var blob = Utilities.newBlob(JSON.stringify(requestBody), "application/vnd.google-apps.script+json");
Drive.Files.insert(resource, blob, {"convert":"true"});
}
Upvotes: 4