Using Google Scripts to upload without intervention - google-apps-script

I have used the below to upload files from my local drive by choosing a file from the UI. I would like to upload a particular file with a static pathway every day. Is there a way to have a script upload a particular file? (Then I could just use triggers to make sure it happened routinely).
function doGet(e) {
var app = UiApp.createApplication().setTitle("Upload CSV to Sheet");
var formContent = app.createVerticalPanel();
formContent.add(app.createFileUpload().setName('thefile'));
formContent.add(app.createSubmitButton());
var form = app.createFormPanel();
form.add(formContent);
app.add(form);
return app;
}
function doPost(e) {
// data returned is a blob for FileUpload widget
var fileBlob = e.parameter.thefile;
var doc = DocsList.createFile(fileBlob);
}'

No, that is not possible (using Apps Script). Apps Script runs on Google servers and therefore do not have access to your local files.
I wrote an article for Steegle a while ago where I explain such Apps Script's aspects. You might want to give it a quick read.
You have to write such program using "traditional" development tools. That is, programs that run in your computer. For example, a Java program using Google Drive API library could do this easily. Then you could schedule it using your OS's scheduling feature (e.g. cron on linux/unix).

Related

edit google document remotely

I'm trying to add a feature to my website as follows:
Clicking a button appends text to a Google document.
Obviously I will need to create an Apps Script in the drive. The question is how to trigger the Apps Script from my website. You can assume that I am the owner of the drive/document and so have permissions to edit it in any way I like.
I have looked at these topics:
Workarounds : How to edit native google documents programatcally?item
How to programmatically manipulate native google doc files
It seems they are all actions performed from the drive itself and not triggered remotely.
I have also looked up the Apps Script API in Google but have not found a way to do this. Is it even possible?
Yes, it is possible.
First write an Apps script that changes your desired document. Then deploy it as a web-app running as you that anyone has access, even anonymous. Check out the guides at Apps Script page to see how to write your script as a web-app.
Your script will then have a public url, which you can call from your website and have it run "remotely" normally.
To provide an example of what Henrique suggests, here is a small webapp that adds text to a publicly viewable document I own (it doesn't need to be public except for anyone here to check it works !)
I wrote it using UiApp but you could of course use HTMLService if you prefer...
The app runs as me but is accessible to anyone even anonymous.
// publicly viewable test doc url : https://docs.google.com/document/d/1THzBTURxGr2CdUmcZ7i2zD-RM8I3im2JCSHI3BHlkeM/edit
function doGet(){
var app = UiApp.createApplication().setTitle('docEdit');
var panel = app.createAbsolutePanel().setSize('100%','100%').setStyleAttributes({'padding':'40px','backgroundColor':'lightBlue'});
var text = app.createTextArea().setName('text').setPixelSize(500,300);
var grid = app.createFlexTable().setId('grid');
grid.setText(0,0,'Add your text').setWidget(1,0,text);
var handler = app.createServerHandler('writeText').addCallbackElement(panel);
grid.setWidget(2,0,app.createButton('update document',handler).setId('btn'));
app.add(panel.add(grid));
return app;
}
function writeText(e){
var doc = DocumentApp.openById('1THzBTURxGr2CdUmcZ7i2zD-RM8I3im2JCSHI3BHlkeM');
var now = Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'MMM/dd/yyyy # hh:mm:ss');
var body = doc.getBody();
body.appendParagraph('Append text on '+now+' : '+e.parameter.text);
doc.saveAndClose();
var app = UiApp.getActiveApplication();
var grid = app.getElementById('grid');
grid.setWidget(3,0,app.createHTML('Thanks,<br>Your text has been added to the document'));
app.getElementById('btn').setEnabled(false).setHTML('Button disabled');
return app;
}

How To set permissions to Google Drive files/folder while adding from Google Site

I am new to Google Sites, I have created a test google site, and add some pages files from google drive to the pages.
My Question is: Is it possible to set permissions from a Google Site while adding a file/folder from Google Drive via any Google Apps Script or Google Drive SDK?
I also did some overview about Google Apps Script for adding UI elements/ html elements, and perform some basic authentication using Google Drive SDK. Given this:
Is possible to perform permission actions.
If we upload a file in a file cabinet template can we set any kind of permissions or remove download link button of that file?
Apps Script has a service called Drive. Drive has a class named: DriveApp. DriveApp can create, save and retrieve files. Once you have a reference to a file, you can use other Classes, Properties and Methods.
setSharing method - Google Documentation
Thanks to Your Answer #Sandy Good from you suggestion/idea I able to create a simple script and after creating this script I am sure I will be able to create a complicated script also.
I have created a script that will create a form in in google site's page. this form contain a dropdown list of my google drive files and an input filed in which i will add an email address.
and in the last a submit button.
after pressing submit button , the script work as it will grant permission on a selected to the email given as viewer of the file if he has link.
create a blank script in the Google Site's Apps Script Section.
Add some UI via UI Service
function doGet() {
// create ui element
var app = UiApp.createApplication();
// create form
var form = app.createFormPanel();
// create area or panel
var flow = app.createFlowPanel();
// create list box for files
var element_file = app.createListBox().setId('file_name').setName('file_name');
// add first elemnt
element_file.addItem('Please Select','');
// get drive files
var files = DriveApp.getFiles();
while (files.hasNext()) {
var file = files.next();
element_file.addItem(file.getName(),file.getId());
}
flow.add(element_file);
var element_text=app.createTextBox().setId('email').setName('email');
flow.add(element_text);
flow.add(app.createSubmitButton("Submit"));
form.add(flow);
app.add(form);
return app;
}
after this I handle the data submitted via post
function doPost(e) {
var app = UiApp.getActiveApplication();
var email = e.parameter.email;
var file_name = e.parameter.file_name;
var public_file = DriveApp.getFileById(file_name);
public_file.addViewer(email);
return app;
}
after this you can check the permissions of the specific file in the google drive.
you may also add a success message.
after this go to publish menu of the file select deploy as web app then select the required things. remember please select execute scripts only as me option because you are listing all your files.
then go to the page in which you want to add script just edit/add new page from editor of the page just insert Apps Script.
apologies , its my first time to work in google apps script , if I miss anything or i did not follow any rule etc.
Thanks,

Using UrlFetchApp in a container-bound script to run code in a web app as effective user

In a little over my head. Trying to use UrlFetchApp.fetch(url, options) from a container-bound script to run code in a web app.
The problem: Container-bound doc script can only run as the activeUser. doc script creates a new doc by copying a template. I would like the doc newly created from the template to be stored in a centralized folder owned by the developer. I see two solutions.
I give all domain users view/edit access to the developer's folder.
I create a web app from a standalone script which runs as the effectiveUser (developer) who has access to the folder. In this case the doc script calls the web app using UrlFetchApp passing in the parameters (folder, doc). However, to quite able to figure out how to do this, if possible.
var unitId = DocumentApp.getActiveDocument().getId();
var unit = DriveApp.getFileById(unitId);
var folderId = unit.getDescription() //FoldId for unit is stored in description
var folder = DriveApp.getFolderById(folderId);
var lesson = DriveApp.getFileById(UNIT.LESSON_TEMPLATE_ID).makeCopy('Lesson - ' + result.getResponseText());
folder.addFile(lesson);//Currently I have the folder shared/edit with domain users.
//I would prefer to share/view. However, since the
//container-bound doc script runs only as active user, no
//can do. Is it possible to build a small web app which
//runs as effective user and saves lesson to folder.
showLessonSidebar(folderId);
Any hints out there?
Yes, it is possible to create a web app that runs as effective user.If the developer - effective user has access to folder and template file.
You could pass the folderId and Name of the file to be copied to the WebApp, rather than passing folder and Doc object (passing the folder Object and Doc object as URL parameter may be quite tricky and if content is too large may not be even possible as there are constraints on the possible length of URL)
1) Write a Apps Script
function doGet(e) {
var folderId = e.parameters.folderId;
var copyFileName = e.parameters.name;
var userEmail = e.parameters.email;
var folder = DriveApp.getFolderById(folderId);
var lesson = DriveApp.getFileById(UNIT.LESSON_TEMPLATE_ID).makeCopy(copyFileName);
folder.addFile(lesson);
//share file to domain or share folder with domain - folder.setSharing(....);
file.setSharing(DriveApp.Access.DOMAIN, DriveApp.Permission.VIEW);
}
2) While deploying the Web App, developer can set Execute as me(developer#...) and set "Who has access to Web App" as Anyone.
3) Make sure developer has authorized the web App.
4) Share the Web App Script file with all your domain users.
Also, if you want to pass the content of file for some reason from container-script to Web App, you may consider implementing the logic in doPost() as you would have the ability to pass large data using POST in UrlFetch.
As far as I understand, the only way to use UrlFetch in a bound script, is using an installed trigger. (UrlFetch is not authorized to run when used in a bound script's simple triggers: https://developers.google.com/apps-script/add-ons/lifecycle#authorization_modes.)
An installed trigger always "runs with the authorization of the user who created the trigger, even if another user with edit access opens the spreadsheet". Thus, simply use installed triggers:
function setupTrigger(){
var doc = DocumentApp.getActiveDocument();
ScriptApp.newTrigger('open').forDocument(doc).onOpen().create();
}
This sample code creates an installable trigger for opening the document bound to the script.

'google is not defined' in custom spreadsheet function

I am trying to write a very basic custom function for my google docs spreadsheet. I have a column in the spreadsheet that lists every day of the year. It's a simple function that should scroll to 'today' in the date column.
However, when I try to run the query, I get an error "google is not defined".
function gotoToday() {
var now = new Date();
var now = Utilities.formatDate(now, "EST", "M/d/yyyy");
var file = SpreadsheetApp.getActiveSpreadsheet();
var sheet = file.getActiveSheet();
var query = new google.visualization.Query(sheet);
query.setQuery('select A WHERE A= '&now);
query.send(handleQueryResponse);
function handleQueryResponse(response) {
Browser.msgBox(response);
var row = day+4;
file.setActiveCell(sheet.getRange(row,1));
}
};
It's dying at the new google.visualization.Query line, saying gooogle isn't defined.
Shouldn't I get those objects for free? Since it is being run in Google Docs, I can't load the jsapi via a script tag. I thought it should just be there. All the other code samples use this same method and the docs don't say anything about other scripts needing to be loaded.
Any ideas would be appreciated!
Thanks,
D
In addition to standard Javascript objects, APIs for many of google's offerings are provided as Services. You don't need to load other scripts to access the Script Services.
The visualization library is represented in Google Apps Script via the Charts Service. The GMail Stats tutorial is one of several that introduces use of the service.
All the other code samples use this same method...
Client-side Javascript samples can do that. No Google Apps Script example does.

Script to unzip attachment

I was trying to create a Google Apps Script, that takes attachment of e-mails, unzips it a forwards it. I saw unpacking feature in Google Drive (you can upload a file there, open it and copy individual files to you drive). Is this functionality accessible from Google Apps Script somehow?
First you need to write a script for automatically makes attachments of an email as directly uploaded on user's Google Drive after this trigger run this piece of code shown below
function testzip(){
var files=DocsList.getRootFolder().find('Sans titre.txt.zip');
var zipblob=files[0].getBlob();
var unzipblob = Utilities.unzip(zipblob);
var unzipstr=unzipblob[0].getDataAsString();// it is a text file
DocsList.createFile('Sans titre.txt',unzipstr);// I kept the original name to make it simple
}
Check this code. Don't blame me if it won't work. It's just a proposal.
Comment: Files are blobs so need to call getBlob(). Anything that has a getBlob() function can be used as a blob directly. You can replace
var zipblob=files[0].getBlob();
var unzipblob = Utilities.unzip(zipblob);
with this:
var zipfile=files[0];
var unzipblob = Utilities.unzip(zipfile);
I tried to edit the other answer, but someone who apparently didn't try the code rejected the edit as incorrect.