Run multiple scripts when we open an HTML web app - google-apps-script

How to run multiple scripts when we open an HTML web app...?
Below is my example script, when user opens the HTML web apps the second (function getMail) script should run and capture the email id in defined sheet
function doGet() {
return HtmlService
.createTemplateFromFile('index')
.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
return html;
}
function getMail() {
Logger.log(Session.getActiveUser().getEmail());
var value = Logger.getLog();
var ss = SpreadsheetApp.openById("1IRpIzJKdc50dz99hYHoUVUBuwwhZI4NGdEKbc2QWqS8").getActiveSheet();
ss.getRange(ss.getLastRow()+1,1).setValue(value);
}
function getData() {
return SpreadsheetApp
.openById('1P0Z_njzrwjiPHrynDW37OTjwaPPFvntpiyBYSNBXt40')
.getDataRange()
.getValues();
}

You can call Google Apps Script function getMail from index.html template using next syntax:
<? getMail() ?>
Detailed docs: https://developers.google.com/apps-script/guides/html/templates#calling_apps_script_functions_from_a_template

Related

GoogleJsonResponseException: API call with error: Login Required

I made a script using the advanced service API Google Drive. It's working fine when we stay into the app script GUI :
/** #OnlyCurrentDoc */
function GetListOfDrivesName() {
const ALL_AVALIBLE_DRIVE = Drive.Drives.list();
return ALL_AVALIBLE_DRIVE.items.map(driveData => driveData = driveData.name)
}
However, when it's called from cell into Google Sheet we got an error
Error message is like below : GoogleJsonResponseException: API call to drive.drives.list failed with error: Login Required.
I guess it's some authentification & authorisation to ask before using the sheet.
Unfortuantly I have no idea how to request that ! I read doc but it's sound like it will be asked promptly.
In addition, trigger have been added for this function but it neither worked
Any idea ? Thanks in advance !
Hi #Yuri Khristich you were right, using ui is a good work around , code turn up to work corectly
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var ui = SpreadsheetApp.getUi();
ui.createMenu('[FM Script for G Drive]')
.addItem('test','showAvaillableDrive')
.addToUi();
}
function showAvaillableDrive(){
var ui = SpreadsheetApp.getUi();
var resultat = ui.prompt(GetListOfDrivesName())
}
function GetListOfDrivesName() {
const ALL_AVALIBLE_DRIVE = Drive.Drives.list();
return ALL_AVALIBLE_DRIVE.items.map(driveData => driveData = driveData.name)
}
As suggested by the comments you can build a menu over the Sheet and run it to write down Drive files that I own.
I have this custom Sheet where you can run the "Drive" function over "Adv Menu"
I automatically get the information of the Sheet and get a list of my Drive files:
function onOpen () {
var ui= SpreadsheetApp.getUi();
ui.createMenu('Adv Menu').addItem('Drive', 'getMyFilesFromDrive').addToUi();
}
function getMyFilesFromDrive() {
var myFiles = DriveApp.searchFiles('"me" in owners');
var sheet = SpreadsheetApp.getActive().getSheetByName("Files");
sheet.clear();
var rows = [];
rows.push(["ID", "Name", "Url"]);
while(myFiles.hasNext()) {
var file = myFiles.next();
if(file != null) {
rows.push([file.getId(), file.getName(), file.getUrl()]);
}
}
sheet.getRange(1,1,rows.length,3).setValues(rows);
}
It would also write it directly to my Sheet. Feel free to review it and use it.
You can also Draw a button (Inserting a Google Drawing) over the Sheet and assign a script:
Reference:
https://developers.google.com/apps-script/guides/menus

Make a google Script Run from a HTML front

I have a script that will run an HTTP request to our server and bring the most recent orders.
We want to be able to run the script on request but also be able to Install it as an addon to different sheets for our different stores
The front End of the app is generated by this html
<link href="https://ssl.gstatic.com/docs/script/css/add-ons.css"
rel="stylesheet">
<div class="sidebar">
<div class="block form-group">
<button class="blue" id="load_orders">Import Order Data</button>
</div>
<div id='orders'></div>
</div>
<script>
$(function onSuccess(load_orders) {
});
withSuccessHandler(onSuccess).importcogs();
});
</script>
Then on the .gs I have a script to show the app (before we Deploy it) and the import orders script
function onInstall() {
onOpen();
}
function onOpen() {
SpreadsheetApp.getUi()
.createAddonMenu() // Add a new option in the Google Docs Add-ons Menu
.addItem("Import Order Data", "showSidebar")
.addToUi(); // Run the showSidebar function when someone clicks the menu
}
function showSidebar() {
var html = HtmlService.createTemplateFromFile("Front")
.evaluate()
.setTitle("Import Order - Search"); // The title shows in the sidebar
SpreadsheetApp.getUi().showSidebar(html);
}
function importcogs() {
Logger.log("import begin");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var urlsheet = ss.getSheetByName("GetInfo");
var request = urlsheet.getRange(5,2).getValue();
Logger.log(request);
var response = UrlFetchApp.fetch(request);
Logger.log("download data finish");
Logger.log(response.getContentText());
var sheet = ss.getSheetByName("Data");
var obj = JSON.parse(response);
let vs = obj.data.map(o => Object.values(o));//data
vs.unshift(Object.keys(obj.data[0]));//add header
sheet.getRange(1,1,vs.length, vs[0].length).setValues(vs);//output to spreadsheet
}
I Haven't been able to link the "Import orders" button to the script for some reason .
As what Cooper has said in the above comment, it is not a standalone function:
Sample Usage:
google.script.run.withSuccessHandler(onSuccess).importcogs();
This will in return runs the importcogs function and will trigger onSuccess function if the function successfully finished. Parameters of the onSuccess will be the return of the function called importcogs if it has any.

Google Apps Script how to use page name to query google sheet

I have a simple Google Site setup that runs a Web App that queries a Google Sheet, and returns templated html code with the necessary queried information. I would like to add functionality that allows the Script to query the Sheet using the Page Name from where the Web App is embedded.
So, for example, say my website is: https://sites.google.com/view/SOMESITE
Say it has a few pages such as:
https://sites.google.com/view/SOMESITE/Dave
https://sites.google.com/view/SOMESITE/Rick
What I want to do is embed my web app in each of these sheets, and use the respective page name (i.e. Dave or Rick) as a parameter to refine the query the Web App does.
I have tried this, but the 'page' comes back Null.
var page = SitesApp.getActivePage();
var name = Logger.log(page.getName());
How can I get the page name as a variable to use in my Script/Web App?
UPDATE:
I have revised my approach per the comments. So let's say I have the URL to my WebApp like this:
https://www.somedomain.com/blah/blah?Rick
And this is my Web App Code:
DoGet:
function doGet(e) {
var name = e.queryString
return HtmlService
.createTemplateFromFile('index')
.evaluate();
}
getData
function getData() {
// ...here there is a bunch of code extracting data from my spreadsheet
return [pick, title, artist, name]
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<? var data = getAlbum(); ?>
// ... the rest is a bunch of markup that makes a table of the query results from getData
How to I pass the variable 'name', which should equal "Rick", to my getData function so I can use it when querying my Sheet?
You can pass query parameters to your Web App URL, you can check here what query parameters are and how to use them. For example:
https://www.somedomain.com/blah/blah?name=Rick
With the parameter attribute from the e event object, you can get the object with all the parameters you passed to the get request. You can use these values directly in your code.gs file, for example:
DoGet:
function doGet(e) {
var parameters = e.parameter;
getData(parameters);
return HtmlService
.createTemplateFromFile('index')
.evaluate();
}
getData
function getData(parameters) {
// ...here there is a bunch of code extracting data from my spreadsheet
return [pick, title, artist, name]
}
Finally, if you need to communicate between the HTML file and the code.gs file, you should check out the documentation for it.
I didn't have enough room for this in the comments. But this is what the doGet() might look like:
function doGet(e)
{
//Logger.log('query params: ' + Utilities.jsonStringify(e));
if(e.queryString !=='')
{
switch(e.parameter.mode)
{
case 'page4':
setPage('Page4')
return HtmlService
.createTemplateFromFile('Page4')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Page4");
break;
case 'page3':
setPage('Page3');
return HtmlService
.createTemplateFromFile('Page3')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Page3");
break;
case 'page2':
setPage('Page2');
return HtmlService
.createTemplateFromFile('Page2')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Page2");
break;
case 'page1':
setPage('Page1');
return HtmlService
.createTemplateFromFile('Page1')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Page1");
break;
default:
setPage('Page1');
return HtmlService
.createTemplateFromFile('Page1')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Page1");
break;
}
}
else
{
setPage('Page1');
return HtmlService
.createTemplateFromFile('Page1')
.evaluate()
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setTitle("Page1");
}
}
Requirements for WebApps

Google Sheets & Docs Script fails to create add-on menu when add-on is installed from Chrome store

Possible cause is the following:
Usually this is caused by a problem with the Authorization Lifecycle, specifically the opening stage.
The most common culprit is a global variable in the code that tries to access Google services without authorization, like:
var doc = DocumentApp.getActiveDocument();
See the documentation:
Warning: When your onOpen(e) function runs, the entire script is loaded and any global statements are executed. These statements execute under the same authorization mode as onOpen(e) and will fail if the mode prohibits them. This preventsonOpen(e) from running. If your published add-on fails to add its menu items, look in the browser's JavaScript console to see if an error was thrown, then examine your script to see whether the onOpen(e) function or global variables call services that aren't allowed in AuthMode.NONE.
Here is my script:
function onOpen(e) {
SpreadsheetApp.getUi().createAddonMenu()
.addItem('Browse Templates', 'browseTemplates')
.addToUi();
}
function onInstall(e) {
onOpen(e);
}
function browseTemplates(){
collectBasicData();
// Display a modal dialog box with custom HtmlService content.
var htmlOutput = HtmlService
.createTemplateFromFile("Gallery").evaluate()
.setWidth(700)
.setHeight(510);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Spreadsheet123 - Template Vault');
}
function collectAllData(){
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(DATA_SHEET);
DATA = sheet.getDataRange().getValues();
return DATA;
}
function collectBasicData(){
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(PIVOT_SHEET);
var tabSheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(TAB_SHEET);
BASIC_DATA = {
"tab_about" : getValue(tabSheet,"B1"),
"tab_help": getValue(tabSheet,"B2"),
"pivot":sheet.getDataRange().getValues()
};
return false;
}
function getValue(sheet,addr){
return sheet.getRange(addr).getValue().toString().replace(/^\s+|\s+$/g, '');
}
function createACopy(id){
var docName = DocsList.getFileById(id).getName();
return DocsList.getFileById(id).makeCopy(docName).getUrl();
}
function insertInCurrent(id){
var destinationSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheets = SpreadsheetApp.openById(id).getSheets();
for(var i=0;i<sourceSheets.length;i++){
var sheetName = sourceSheets[i].getName();
var source = SpreadsheetApp.openById(id).getSheetByName(sheetName);
source.copyTo(destinationSpreadSheet).setName(sheetName);
}
}
Can you please help me a little or a lot.
Thanks in advance
OK, so my code was actually correct, but my mistake was that I should have saved any changes made to my code under the new version before publishing it to the store, which I did not and therefore all changes that I made were simply ignored.
function onOpen(e) {
SpreadsheetApp.getUi().createAddonMenu()
.addItem('Browse Templates', 'browseTemplates')
.addToUi();
}
function onInstall(e) {
onOpen(e);
}

Google App Script - Display PDF on Form Submit

I have a current Google Form and App Script where the Apps Script is taking the form data, putting it into a spreadsheet template (which does some calculations) then e-mails that spreadsheet as a PDF.
Is there a way in Google Apps Script to have this PDF displayed in the web browser rather than being sent in an e-mail?
You can use this workround .
pag.html
<html>
<input type="submit" onclick="downloadPDF()"/>
Click here to open
<script>
function sucess(e) {
alert(e);
var downloadLink = document.getElementById("myDownloadLink");
downloadLink.href=e;
downloadLink.style.display = 'block';
}
function downloadPDF() {
google.script.run.withFailureHandler(alert).withSuccessHandler(sucess).getFile();
}
</script>
</html>
code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile("pag");
}
function getFile() {
return DriveApp.getFileById("1pczv0kRvgpI87owXWUXTtm4wXXsiG8-ErVWFtv05izI").getUrl();
}