I am looking to simulate the behavior of Google Classroom's assignment feature that allows you to make a copy of a document for a list of students. This copy retains ownership by the creator and adds the student as an editor.
I have succeed in making this work with a script attached to a template doc. The teachers can paste a list of email addresses into a custom pull-out, and on submission a loop creates each doc with the permissions.
Attempts:
- I can use
copy()
functionality to copy the doc, but the attached script goes along for the ride and is then accessible by the students. This is not a major security risk, but has the potential to be abused. - I can have moderate success by using the regularly mentioned method of looping through all elements and appending them to the new doc, but so far I have not been able to make everything work in this way. Some images, tables, and other elements that teachers might create do not format properly in the new doc.
Hopeful solutions:
- Is there a way to remove the script from the copied doc? or
- Is there a way to use permissions to only allow the script to be run by faculty? (We do have an Org Unit for faculty, but my tests with the AdminDirectory module leave me concerned about permissions once all faculty is using the tool.) or
- Knowing that our student email addresses are formatted differently from our faculty email addresses, could I programmatically block the script based on email address parsing of the current user?
I've gone in circles and keep ending up at the posts explaining how to copy elements one at a time into a new doc. This does not appear to be sufficient due to formatting so I'm hoping one of the other solutions involving keeping the copy()
function is possible.
Sidebar Code sidebar.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
</script>
<style>
textarea{
font-size: .9em;
width: 90%;
height: 300px;
}
</style>
</head>
<body>
<textarea id="addressList">
Paste class email list here with spaces between addresses.
</textarea>
<p>
<input id="submit" type="button" value="Distribute to Students" onclick="distributor();" />
<input id="reset" type="button" value="Reset" onclick="reset();" />
</p>
<script>
function reset(){
document.getElementById('addressList').value = "Paste class email list here with spaces between addresses.";
document.getElementById("submit").disabled = false;
}
var mainOut = "";
function cleanUp(output){
mainOut += output;
document.getElementById('addressList').value = mainOut;
}
function distributor(){
document.getElementById("submit").disabled = true;
var nameList = document.getElementById('addressList').value; // get email list
var list = nameList.split("\n"); // break it up
// loop through names
for(let i = 0; i < list.length; i++){
// create a doc for each student and return success to the UI
google.script.run.withSuccessHandler(cleanUp).distro(list[i],i+1,list.length);
}
}
</script>
</body>
</html>
Current Script Code.gs
// student email addresses end in a 2 digit class year, faculty does not
var event;
var emailParts = Session.getEffectiveUser().getEmail().split('@');
var username = emailParts[0];
var classCheck = username.substring(username.length-2);
var validUser = false;
// using school email address style, determine if student or teacher to hide the UI changes
if(isNaN(classCheck)){
validUser = true;
}
// Custom Menu
function onOpen(e){
if(validUser){
event = e;
var ui = DocumentApp.getUi();
var faMenu = ui.createMenu('FA')
.addItem('Open Distribution Tool', 'openTool').addToUi();
}
}
/**
* Creates Custom Sidebar for emailing teams from spreadsheet
*/
function openTool() {
if(validUser){
var html = HtmlService.createHtmlOutputFromFile('sidebar');
html.setTitle('Share with Students');
html.setWidth(400);
html.setContent(html.getContent());
DocumentApp.getUi().showSidebar(html);
}
}
// create copy, set permissions
function distro(studentEmail,count,total){
var output = "";
if(validUser){
var teacherEmail = 'xxx@xxx.org'; // this will be replaced by email of logged in user
var thisDoc = DocumentApp.getActiveDocument();
let studentName = studentEmail.split('@')[0];
if(studentEmail != "" && studentEmail != null){
let filename = thisDoc.getName() + "- " + studentName;
let newDoc = DriveApp.getFileById(thisDoc.getId()).makeCopy(filename);
newDoc.setOwner(studentEmail);
newDoc.addEditor(teacherEmail);
output += "Created doc " + count + "/" + total + ": " + filename + "\n";
}
}
return output;
}