Send attachement as Word document via Google Script - google-apps-script

Via Google Spreadsheet I like to send an attachment. The attachment is a Google Doc.
I can sent it as PDF file.getAs('application/PDF') -- however I need it as a Word document (or something that opens up in Word).
It is possible to do send an email manually as Word attachment, however this solution requires to do this automatically.
I tried: application/vnd.openxmlformats-officedocument.wordprocessingml.document (http://en.wikipedia.org/wiki/Internet_media_type) but that doesn't work.
Kind regards
Stefan

Google Apps Script can't export anything else than pdf natively but the document API does so you can use urlFetch with parameters to get what you want (don't change these parameters, the request is anonymous and can stay so).
Here is the code, it doesn't require too much explanations except that the urlFetch must be authorized (the process is not the usual one, you'll get a second authorization for this script.)
function emailDocTestasDocx() {
var id = '1I9KIVTLieQbNnmz09zfOBSBNwZ9Tp7B0kfpysaf-ooY';// an example of Google doc
var url = 'https://docs.google.com/feeds/';
var doc = UrlFetchApp.fetch(url+'download/documents/Export?exportFormat=doc&format=doc&id='+id,
googleOAuth_('docs',url)).getBlob();
var me = Session.getEffectiveUser().getEmail();
MailApp.sendEmail(me, 'test', 'see attachment', {attachments:[doc]});
}
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey('anonymous');
oAuthConfig.setConsumerSecret('anonymous');
return {oAuthServiceName:name, oAuthUseToken:"always"};
}

Related

Include sheet names when exporting Google Spreadsheets to PDF with Google Apps Scripts

I am exporting a Google Spreadsheet to PDF format with Google Apps Script, and would like to 'include sheet names' on the PDF pages. Is this possible to do this from the code?
var spreadsheetFile = DocsList.getFileById(spreadsheet_id);
var blob = spreadsheetFile.getAs('application/pdf');
blob.setName(spreadsheetFile.getName());
DocsList.getFolder(file_destination).createFile(blob);
In the Spreadsheet app it is supported in the UI, so I am wondering whether Apps Scripts supports this too?
The .getAs() method does not allow for parameters but you can use the spreadsheet api where you can choose all the parameters available from the "normal" Ui.
See this post answer to see how to use it, and follow the github link
Here is the demo code as there were a few inconsistencies in the code in ref. (just to illustrate with an example exporting sheet1 with grid and title)
note this will ask for 2 distinct authorizations.
function test(){
var key = "0AnqSFd3iikE3dFd1WEVhMFhYczM5VWpuNDZHQ3AwZEE";
var pdf = spreadsheetToPDF(key);
DocsList.createFile(pdf);
}
function spreadsheetToPDF(key) {
var oauthConfig = UrlFetchApp.addOAuthService("spreadsheets");
var scope = "https://spreadsheets.google.com/feeds"
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oauthConfig.setAuthorizationUrl("https://accounts.google.com/OAuthAuthorizeToken");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
var requestData = {
"oAuthServiceName": "spreadsheets",
"oAuthUseToken": "always",
};
var name = DocsList.getFileById(key).getName()+".pdf";
var pdf = UrlFetchApp.fetch("https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="+key+
"&exportFormat=pdf&gid=0&gridlines=true&printtitle=true&size=A4&sheetnames=true&fzr=true&portrait=true&fitw=true", requestData).getBlob().setName(name);
return pdf;
}
/*
fmcmd=12
size=legal/A4
fzr=true/false
portrait=false/true
fitw=true/false
gid=0/1/2
gridlines=false/true
printtitle=false/true
sheetnames=false/true
pagenum=UNDEFINED
attachment=false/true
*/

Google Appscript approvals for public document

I have a google spreadsheet that is shared with all members on our domain. I'd like to have a script which will send the spreadsheet as an email attachment whenever one of the users runs the script.
Following this question as a guide, I arrived at the following code:
function sendEmail() {
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getName();
//var email = Session.getUser().getEmail();
var email = "xxxxx#example.com";
var subject = "Order Form";
var body = "Please find the attached Order Form for drop-ship delivery.";
var oauthConfig = UrlFetchApp.addOAuthService("google");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://spreadsheets.google.com/feeds/");
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
var requestData = {"method": "GET", "oAuthServiceName": "google", "oAuthUseToken": "always"};
var url = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="
+ ssID + "&gid=0&portrait=true" +"&exportFormat=xls";
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
MailApp.sendEmail(email,subject ,body, {attachments:[{fileName:sheetName+".xls", content:contents, mimeType:"application//xls"}]});
}
This code works, but only if I run the code from the script editor first (which involves authorizing access to the google mail account), and then authorizing the script when using the script.
So, I passed along the document to the order department, and again, it only works when EACH USER authorizes the script from the script editor, and then authorizes the script when using it.
Is there a way to eliminate the "authorizing by way of the script editor"? I'd really not like to have to go into each users account to authorize this script for them (as well as have to remember to do the same for any new user created)?
I appreciate any help offered!
Unfortunately NOT. see also my question and the answer by one of the google developer advocates.
You can vote for the issue I opened to push for a solution.

How to add a Google Drive folder to "My Drive" section to other users

I have a Google Drive herarchichal folder and subfolders structure owned by me and I want to add it to the "My Drive" section in all users in our Google Apps for Business domain automatically.
How can I do this? I heard about Google Apps Script and AddToFolder function.
Please, can you help me?
Thanks in advance.
This is very easy to do if each user could just access a link and authorize a script (that you build) to do the job for them (place a shared folder in their root folder).
But if it's a lot of users, you are the admin of the domain, and you really want to do it all automatically without anyone doing a thing, it is possible but probably very difficult to do. I mean, you need to access the Drive API directly and set oAuth 2.0 to impersonate your users, because the Apps Script built-in DocsList API does not have this impersonation feature. If you're really going for it, take a look at this other question.
First, set up a simple web app. The Google App Script editor even has a template that gets you most of the way there.
Second, implement something like the following and call it from the handler function.
function addRequiredFolders() {
var root = DocsList.getRootFolder();
var folderIds = ["somefolderid", "anotherfolderid"];
folderIds.map( function(id) { DocsList.getFolderById(id).addToFolder(root) } );
}
I've tested a variant of this up to this point. The next step is to publish the Web App for your domain, and email it out to people or otherwise distribute it. I assume they will have the unpleasant step of needing to grant the web app permission to access their documents.
Right now I've implemented this feature using "Google Documents List API". I know that this API is deprecated but for now it works.
(the code is not finished)
(...)
//var user = Session.getActiveUser().getUserLoginId() OR
var user = e.parameter.user_email
var TB_folder = e.parameter.TB_folder
var TB_sub_folder = e.parameter.TB_sub_folder
var base = 'https://docs.google.com/feeds/';
var fetchArgs = googleOAuth_('docs', base);
fetchArgs.method = 'POST';
var rawXml = "<?xml version='1.0' encoding='UTF-8'?>" + "<entry xmlns='http://www.w3.org/2005/Atom'>"
+ "<category scheme='http://schemas.google.com/g/2005#kind' "
+ "term='http://schemas.google.com/docs/2007#folder'/>"
+ "<title>" + TB_folder +"</title>"
+ "</entry>";
fetchArgs.payload = rawXml;
fetchArgs.contentType = 'application/atom+xml';
fetchArgs.contentLength = 245;
// POST a https://docs.google.com/feeds/default/private/full
var url = base + user + '/private/full/?v=3&alt=json';
var content = UrlFetchApp.fetch(url, fetchArgs).getContentText()
var json = Utilities.jsonParse(content)
var folder = json.entry.gd$resourceId.$t // -> I get "folder:folder_id"
var id_folder = folder.split(':')[1]
var folder_created_by = json.entry.gd$lastModifiedBy.email.$t
var folder_owner = json.entry.author['0'].email.$t
(...)
Now, you have the folder ID and can use it to create another subfolder or a file...
You need this function :
//Google oAuth
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("XXXXXXXX");
oAuthConfig.setConsumerSecret("XXXXXXXXXXXXXXXXXXX");
//oAuthConfig.setConsumerKey("anonymous");
//oAuthConfig.setConsumerSecret("anonymous");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
You can create a file or add a user to a file (add a wriker).
Now I want to implement this functionality with " Drive API " . If someone has done it would be nice to get some help.
Sergi

Google Apps Script: How to share calendar with another user?

I am trying to share google calendars of a user in domain with another user in other domain using google apps script and OAuth authorization. But i am not able to perform this task. I fetched all the calendars events of user but couldn't do the sharing.
Any solution would be appreciated.
Thank You
Solution of this problem is here:
function calenderSharing(user1,user2){
var scope = 'https://www.google.com/calendar/feeds/';
var fetchArgs = googleOAuth_('calenders', scope);
var rawXml= "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>"+
"<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'/>"+
"<gAcl:scope type='user' value='"+user2+"'></gAcl:scope>"+
"<gAcl:role value='http://schemas.google.com/gCal/2005#owner'> </gAcl:role></entry>"
fetchArgs.method = 'POST';
fetchArgs.payload = rawXml
fetchArgs.contentType = 'application/atom+xml';
try{
var url='https://www.google.com/calendar/feeds/'+user1+'/acl/full'
var urlFetch=UrlFetchApp.fetch(url,fetchArgs) //Giving Permission To personal account as a owner
}
catch(err){
var err1=err.toString()
var ex='Exception: Request failed for returned code 302'
if(ex==err1.split('.')[0]){
var tempCalenderUrl=[]
tempCalenderUrl.id = err1.split('<A HREF="')[1];
tempCalenderUrl.id = tempCalenderUrl.id.split('"')[0];
var url=tempCalenderUrl.id
try{
var urlFetch=UrlFetchApp.fetch(url,fetchArgs)
}
catch(err){}
}
}
}
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey(consumerKey);
oAuthConfig.setConsumerSecret(consumerSecret);
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
In Google Script you can't. The Calendar Script API does not support sharing of calendars (at this time).
Your workaround might be to get the calendar ID using script and using UrlFetch (with OAuth) to call the Google Calendar API https://developers.google.com/google-apps/calendar/v3/reference/. Ensure you authenticate, perform a 'get' to get the calendar based on the ID you retrieved from your script, get the ACL and add a new entry to share with the user outside your domain.
Not an easy solution. Sorry.
Why don't you make an App that would allow this user to simply subscribe to this new calendar instead?
All the necessary tools are in the gas calendar service-
Here is an example of such an application

Mail Document via apps script

It is possible to mail the contents of a google document via apps script? I can see how to mail a link to the document, which works fine if the recipient has access.
It is possible to do this manually
- checkmark the document
- from the More.. button select Share... then Email as Attachment...
- from the next screen select the attach as drop down and select Paste the item itself into the email.
However, I can't figure out how to do this through a script.
This is fairly straightforward and there are a few examples available on the internet but basically here is how to proceed to send it as a pdf attachment:
var docName = DocumentApp.openById(docID).getName();
var pdf = DocsList.getFileById(docID).getAs('application/pdf').getBytes();
var attach = {fileName: docName+".pdf",content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(emailadress, 'Your document as PDF ('+docName+')', 'see attachment', {attachments:[attach]});
I hope this example is clear enough.
EDIT : following your comment, I think this post by Henrique on the old Google group forum should fulfill your needs.( It's a workaround that I use a lot in many scripts and it works beautifully... the only annoying detail is that it needs to be authorized from the script editor (not the usual red border popup).
Here is how it goes :
function emailDocTest() {
var id = 'Doc-Very-Long-ID-Here';
var url = 'https://docs.google.com/feeds/';
var doc = UrlFetchApp.fetch(url+'download/documents/Export?exportFormat=html&format=html&id='+id,
googleOAuth_('docs',url)).getContentText();
var emailAdress = Session.getEffectiveUser().getEmail();
MailApp.sendEmail(emailAdress, 'test doc send by mail as html', 'html only', {htmlBody:doc});
}
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey('anonymous');
oAuthConfig.setConsumerSecret('anonymous');
return {oAuthServiceName:name, oAuthUseToken:"always"};
}