Script to automatically make a copy of a Google Document for editing
Asked Answered
S

5

19

I feel like a total noob posting here. I know CSS, HTML, and XML pretty well but have always avoided JS. I know very little javascript and recently started a Lynda.com course to catch up. Sorry for my ignorance. As such, I am really struggling learning Google Apps Script. Obviously, I need to learn JS before I can make sense of any of it.

The school I work for (5000 students) has set up an online curriculum. I created the curriculum in the form of thousands of google document worksheets. These worksheets are linked on various websites.

The problem we are facing is that when students open the documents, they have to make a copy of them before they can edit them (I of course don't want them to be able to edit the originals). This really sucks for students using mobile browsers on their tablets as making a copy in Google Docs doesn't really work well when using the desktop UI on mobile devices.

I know this kind of thing can be automated with script. I've looked here, and low and behold, it works! I'm pissing my pants with joy as I've been searching for such functionality for three years. (Yes, I know that's sad).

So, what I'm asking is, would anyone be willing to help a noob figure out how to adapt this code so that students click a button on a website lesson and it automatically makes and opens a copy of the worksheet in a new tab?

/**
 * Copy an existing file.
 *
 * @param {String} originFileId ID of the origin file to copy.
 * @param {String} copyTitle Title of the copy.
 */
function copyFile(originFileId, copyTitle) {
  var body = {'title': copyTitle};
  var request = gapi.client.drive.files.copy({
    'fileId': originFileId,
    'resource': body
  });
  request.execute(function(resp) {
    console.log('Copy ID: ' + resp.id);
  });
} 

Spending all day yesterday learning Javascript, I've still got a long way to go. Not sure how long it'll take for me to be able to figure this out on my own.

Seaway answered 4/11, 2012 at 19:16 Comment(8)
And what is your question exactly?Plural
Basically, need this function to execute by a button click and get the doc to open in a new tab. Looking for people kind enough to adapt the code.Seaway
This is not Apps Script code. Have you tried to learn it at all? (before asking for someone to write it for you)Xeniaxeno
Yeah, currently studying js. Just thought I would ask as it would probably take someone ten seconds to adapt the code. I know I need to learn this stuff.Seaway
Apps Script uses only javascript syntax basically, everything else is different (with a handful exceptions maybe). So, learning one does not really help learning the other. Well, at least not much more than learning to program at all.Xeniaxeno
Yes, but I am new to programming. It is quite clear from Google's documentation that learning Apps Script requires programming knowledge. Trust me, it doesn't make any sense to someone that is just learning about js functions. I get they are different, but like you said, they use the same syntax. As such, for me to make use of the API, I need to learn basic programming. I realize I am embarking on a long and arduous task. Just thought I would ask for help for one task I am learning programming for. Thought it could also help me with the learning process.Seaway
Well, after further reading, from what I can gather, looks like I need to look at the Drive API for what I'm trying to do. Hope I'm on the right path.Seaway
@Plural , he/she wants to know this: would anyone be willing to help a noob figure out how to adapt this code so that students click a button on a website lesson and it automatically makes and opens a copy of the worksheet in a new tab?Viola
T
15

You can certainly do this with Apps Script. Only takes a couple of lines. In fact, you can use just the version I wrote below.

Here is how I would do it -

  1. Ensure you original document is at least read enabled for the folks that will be accessing it.

    Access rights

  2. Grab the fileId from the URL -

    enter image description here

  3. Write a web app in Apps Script with the following code -

    function doGet(e) {
      //file has to be at least readable by the person running the script
      var fileId = e.parameters.fileId;  
      if(!fileId){
        //have a default fileId for testing. 
        fileId = '1K7OA1lnzphJRuJ7ZjCfLu83MSwOXoEKWY6BuqYitTQQ'; 
      }
      var newUrl = DocsList.getFileById(fileId).makeCopy('File copied to my drive').getUrl(); 
      return HtmlService.createHtmlOutput('<h1><a href="'+newUrl+'">Open Document</a></h1>');
    }
    
  4. Deploy it to run as the person accessing the app.

    deploy settings

One key thing to remember is that a web app built by Apps Script cannot force open a new window automatically. Instead we can show a link which is clickable into the document in edit mode.

You can see it in action here (will create some dummy file) -

https://script.google.com/macros/s/AKfycbyvxkYqgPQEb3ICieywqWrQ2-2KWb-V0MghR2xayQyExFgVT2h3/exec?fileId=0AkJNj_IM2wiPdGhsNEJzZ2RtZU9NaHc4QXdvbHhSM0E

You can test this by putting in your own fileId.

Tejeda answered 6/11, 2012 at 1:23 Comment(2)
As I understand this requires the file sharing setting to remain as "anyone with the link", right?Sapless
NOTE: If you give the above link access, it has permission to add, update, and delete all files in your DriveOtho
S
9

Since DocsList is deprecated, currently you can make a copy of a file using the following code:

File file=DriveApp.getFileById(fileId).makeCopy(fileName, folder);

where fileId can be obtained as explained in the answer by Arun Nagarajan.

Swipe answered 9/4, 2016 at 7:19 Comment(2)
This doesn't work. I go to the script editor, copy-paste your code, replace the fileId with the unique file identifier in single quotes but I receive the error message SyntaxError: Unexpected identifier (line 1, file "Code.gs")Musso
This line of code worked for me, thanks! To the above comment, you not only have to change "fileId", but also "fileName" and "folder". In other words, you have three parameters you must change: fileId, fileName, folder. While .getFileById requires the fileID, .makeCopy() is optional; leave both empty, and it will assume default values; leave one empty and it will assume default for only that value; or provide both values for fileName and folder for ultimate control.Littell
D
5

Here is the code to do it properly (works in 2019,2020,2021):

/**
 * Create custom menu when document is opened.
 */
function onOpen() {
  DocumentApp.getUi()
    .createMenu('For Students')
    .addItem('Make a copy', 'makeACopy')
    .addToUi();
}

function makeACopy() {
  var templateId = DocumentApp.getActiveDocument().getId();
  DriveApp.getFileById(templateId).makeCopy();
}
Deneendenegation answered 3/4, 2019 at 5:1 Comment(0)
N
4

Update as of 2015, Google Script removed the fileId for reasons unknown. The previous method of appending "/copy" to the URL of the Google doc has been re-enabled. Ex) https://docs.google.com/document/d/1GTGuLqahAKS3ptjrfLSYCjKz4FBecv4dITPuKfdnrmY/copy

Nickels answered 16/9, 2015 at 18:5 Comment(0)
P
0

Here is the code I use to make an auto copy of my google Docs.

function makeCopy() {


// generates the timestamp and stores in variable formattedDate as year-month-date hour-minute-second
var formattedDate = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd' 'HH:mm:ss");

// gets the name of the original file and appends the word "copy" followed by the timestamp stored in formattedDate
var name = DocumentApp.getActiveDocument().getName() + " Copy " + formattedDate;

// gets the destination folder by their ID. REPLACE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx with your folder's ID that you can get by opening the folder in Google Drive and checking the URL in the browser's address bar
var destination = DriveApp.getFolderById("16S8Gp4NiPaEqZ0Xzz6q_qhAbl_thcDBF");

// gets the current Google Docs file
var file = DriveApp.getFileById(DocumentApp.getActiveDocument().getId())

Add a trigger and enjoy!


The same code works for google Sheets. Only you need to replace

DocumentApp.getActiveDocument().getName()

with

SpreadsheetApp.getActiveSpreadsheet()

You can find more details here.

Precisian answered 1/5, 2022 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.