I need to convert the active Google document into a Word document within a specific folder using the below oAuth scopes.
"https://www.googleapis.com/auth/documents.currentonly"
"https://www.googleapis.com/auth/drive.file"
This is my implemented script.
function convertGoogleDocToWordDoc() {
var rootFolder = findFolderOrFile("MyTest",'application/vnd.google-apps.folder');
if(rootFolder!= null){
folderID = rootFolder;
}
else{
var rFolder = {
title: "MyTest",
mimeType: 'application/vnd.google-apps.folder'
};
var folder = Drive.Files.insert(rFolder);
folderID = folder.getId();
}
var documentObject = DocumentApp.getActiveDocument();
var token = ScriptApp.getOAuthToken();
var ext = ".docx";
// Fetch the docx blob
var blb = UrlFetchApp.fetch("https://docs.google.com/feeds/download/documents/export/Export?id=" documentObject.getId() "&exportFormat=docx",
{
headers : {
Authorization : 'Bearer ' token
},
muteHttpExceptions: true
}).getBlob();
var filename = documentObject.getName();
var name = ~filename.indexOf(ext) ? filename : filename ext;
var file = {
title: name,
mimetype :'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
parents: [{'id':folderID}]
}
var file = Drive.Files.insert(file,blb);
return file.getId();
}
This creates a Word document in the correct format within the "MyTest" folder only when I use the "https://www.googleapis.com/auth/documents"
oAuth scope.
How should I modify this script to create the Word document using the "https://www.googleapis.com/auth/documents.currentlyonly"
scope ?
Thanks in advance!
CodePudding user response:
For my following asking,
When I tested your script with the scopes of
"https://www.googleapis.com/auth/documents.currentonly","https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/script.external_request"
, no error occurs. The DOCX file converted from Google Document is put to the folder. So, when you ran your script, can I ask you about the error message?
I got the following reply,
Yes, it doesn't give errors, but the creating .docx file is corrupted. Try opening the created .docx file.
From your reply and your showing script, I thought that your current situation might be related to your Google Document of var documentObject = DocumentApp.getActiveDocument()
and the scope of https://www.googleapis.com/auth/drive.file
.
If your Google Document of var documentObject = DocumentApp.getActiveDocument()
is not created by the same client with https://www.googleapis.com/auth/drive.file
, the Google Document cannot be obtained. By this, I thought that in the case of your script, your this situation it doesn't give errors, but the creating .docx file is corrupted.
might occur.
But, this is just my guess. So, in order to confirm my guess, please test the following modified script using your Google Apps Script project which has your showing script.
Sample script
function sample() {
var token = ScriptApp.getOAuthToken();
// 1. Create new Google Document using the scope of `https://www.googleapis.com/auth/drive.file`
var doc = Drive.Files.insert({ title: "sampleDocument", mimeType: MimeType.GOOGLE_DOCS }, Utilities.newBlob("sample text", MimeType.HTML));
// 2. Export Google Document as DOCX.
var blob = UrlFetchApp.fetch(
`https://docs.google.com/feeds/download/documents/export/Export?id=${doc.id}&exportFormat=docx`,
{ headers: { Authorization: 'Bearer ' token } }
).getBlob();
Drive.Files.insert({ title: "convertedDOC.docx" }, blob);
}
- When you copy and paste this script to your Google Apps Script project which has your showing script, this script can be run with the scopes of
"https://www.googleapis.com/auth/documents.currentonly","https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/script.external_request"
. - When you run this script, a new Google Document is created and the created Google Document is exported as DOCX file. By this, you can see
sample text
in the exported DOCX file. This DOCX is not broken. - When I tested this script with those scopes, I confirmed that the valid DOCX file can be exported.
Workaround:
As a workaround for achieving your goal, I would like to propose using Web Apps as a wrapper API for exporting Google Document. Your current situation is as follows.
- 3 scopes of
"https://www.googleapis.com/auth/documents.currentonly","https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/script.external_request"
are used. - Your active Google Document is not created by the client of this Google Apps Script project.
- By this, an error like
it doesn't give errors, but the creating .docx file is corrupted.
occurs.
- By this, an error like
- You want to export this Document using only these scopes.
Usage:
1. Create Google Apps Script for Web Apps.
In order to use Web Apps, please create a new Google Apps Script project. In this case, it is not required to modify appsscript.json
.
2. Sample script:
Please copy and paste the following script to the script editor of the created Google Apps Script project.
function doGet(e) {
const { documentId } = e.parameter;
var blob = UrlFetchApp.fetch(
`https://docs.google.com/feeds/download/documents/export/Export?id=${documentId}&exportFormat=docx`,
{ headers: { Authorization: 'Bearer ' ScriptApp.getOAuthToken() } }
).getBlob();
var obj = Drive.Files.insert({ title: "convertedDOC.docx" }, blob);
return ContentService.createTextOutput(obj.id);
// DriveApp.getFiles(); // This is used for automatically detecting the scope for exporting Document. But, from `Drive.Files.insert`, this might not be required to be used.
}
- In this case, the required scopes are automatically detected.
3. Enable Drive API.
Please enable Drive API at Advanced Google services.
4. Deploy Web Apps.
The detailed information can be seen at the official document.
- On the script editor, at the top right of the script editor, please click "click Deploy" -> "New deployment".
- Please click "Select type" -> "Web App".
- Please input the information about the Web App in the fields under "Deployment configuration".
- Please select "Me" for "Execute as".
- This is the importance of this workaround.
- Please select "Anyone" for "Who has access".
- In your situation, I thought that this setting might be suitable.
- In order to simply access to this Web Apps, I used this setting.
- Please click "Deploy" button.
- Copy the URL of the Web App. It's like
https://script.google.com/macros/s/###/exec
.- When you modified the Google Apps Script, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful this.
- You can see the detail of this in the report of "Redeploying Web Apps without Changing URL of Web Apps for new IDE".
5. Testing.
Please copy and paste the following script to the script editor of the Google Apps Script project with the scopes of "https://www.googleapis.com/auth/documents.currentonly","https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/script.external_request"
. And, please set your Web Apps URL to https://script.google.com/macros/s/###/exec
.
function sample2() {
var documentId = DocumentApp.getActiveDocument().getId();
var webAppsUrl = "https://script.google.com/macros/s/###/exec";
var res = UrlFetchApp.fetch(webAppsUrl "?documentId=" documentId);
console.log(res.getContentText())
}
- When this script is run, this script requests with the document ID of the active Document. And, the active Google Document is exported as DOCX file by the Web Apps using those 3 scopes.
Note:
- When you modified the Google Apps Script, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful this.
- You can see the detail of this in the report of "Redeploying Web Apps without Changing URL of Web Apps for new IDE".
References:
CodePudding user response:
I believe it is just not possible. You must use
https://www.googleapis.com/auth/documents
as scope, otherwise instead of the document contents, a HTML string containing an Error (Sorry, the file you have requested does not exist.
) is returned by theexport
endpoint.According to the best practices in the documentation, I’d recommend for you to consider using Drive API v3 method Files: export().
Running the method above on my end (without changes), the minimum OAuth scopes to properly save the document as Docx are:
"oauthScopes": [
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/drive.file"
]