Call parameter through a webapp? - google-maps

The code below gets the distance between 2 different addresses and returns the distance in miles, kilometers or minutes. My understanding was that I could execute my app-script in a web app using google.script.run.googleMaps();
My question is how do I use input fields as my from and two columns to replicate the same result in a web app?
function googleMaps(start_address,end_address, return_type){
var mapObj = Maps.newDirectionFinder();
mapObj.setOrigin(start_address);
mapObj.setDestination(end_address);
var directions = mapObj.getDirections();
var getTheLeg = directions["routes"][0]["legs"][0];
var meters = getTheLeg["distance"]["value"];
switch(return_type){
case "miles" :
return Math.floor(meters * 0.000621371);
break;
case "kilometers" :
return meters / 1000;
break;
case "minutes" :
var duration = getTheLeg["duration"]["value"];
return duration / 60;
break;
default :
return "Error: Wrong unit type";
}
}

Passing parameters to a WebApp
A WebApp must contian a function doGet(e) (or alternatively doPost(e)), which will be the first function to be run when the WebApp is called
When you deploy a WebApp, the WebApp URL will be something like this:
https://script.google.com/a/XXXXX.eu/macros/s/XXXXXXXXXXXXXXXXXXX/exec
If you want to pass paramters to the url, you should do it like
https://script.google.com/a/XXXXX.eu/macros/s/XXXXXXXXXXXXXXXXXXX/exec?start_address=AAA&end_address=BBB&return_type=CCC
Those parameters can be retrieved within the WebApp as
function doGet(e){
var start_address = e.parameter.start_address;
var end_address = e.parameter.end_address;
var return_type = e.parameter.return_type;
...
}
Now, you can completely integrate your function within doGet() - you do not need google.script.run.googleMaps(); for it
If you do want to call your function with google.script.run, note that it is a method that calls an Apps Script function from within client-side (Javascript)
If you want to use it, it means that first you need to create a client-side with HtmlService
Second, you will need to pass the retrieved parameters from Apps Script to Javascript and back

You can pass them directly:
google.script.run.googleMaps(start_address,end_address, return_type);

Related

Use Google Web App URL Parameter As Part Of Function

I'm trying to use a parameter in a Google web app url to select which tab of a Google Sheet I want to extract data from. The request for data is made via a Chatfuel JSON GET request, which pulls data from the spreadsheet tab and returns it as formatted json code into the chatbot.
When I run the request without passing a parameter and manually enter the sheet tab name into the doGet function of the Google Sheet script as below it works fine.
URL - https://script.google.com/macros/s/xxx-xxx-xxx/exec
function doGet() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Retail");
var data = sheet.getDataRange().getValues();
elements = create_elements(data)
if (elements.length != 0) {
return buildImageGallery(elements);
} else {
return notFound()
}
}
I just can't quite figure out how to take a parameter from a url (e.g "type"), and then use that as part of the doGet function - this is what I'm roughly trying to do...
URL - https://script.google.com/macros/s/xxx-xxx-xxx/exec?type=Retail
function doGet() {
var type = e.parameter.type;
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(type);
var data = sheet.getDataRange().getValues();
elements = create_elements(data)
if (elements.length != 0) {
return buildImageGallery(elements);
} else {
return notFound()
}
}
I'm sure it's soemthing simple, but I'm just getting started with this coding stuff so I'm not sure what I need to change. Thanks in advance for your help.
Does function doGet(e) work?
Is it a typo or you missed it? The e parameter inside the function.

Triggering GAS function via URL

Very new to this, but giving it a shot. I am trying to set up an Arduino motion sensor to trigger a script. At this point, my goal is to trigger a script via URL. I found this code below that I am working through, but I continue to get this error when running/debugging.
TypeError: Cannot read property "parameter" from undefined. (line 4, file "Code")
I have been looking into e.parameter object, but have not been able to make any headway
function doGet(e) {
Logger.log(e)
var passedString,whatToReturn;
passedString = e.parameter.searchStringName;
if (passedString === 'tylog') {
whatToReturn = tylog(); //Run function One
};
return ContentService.createTextOutput(whatToReturn);
};
var mns = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Monster")
var tyl = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("tyLog")
var tyd = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("tyData")
var twl = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("twLog")
var twd = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("twData")
var tym = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("tyMaster")
var twm = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("twMaster")
var test = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("test")
var tydate = tyd.getRange('A2');
var tydur = tyd.getRange(2, 2);
// Start functions
function start() {
tyl.getRange('A1').setValue(new Date());
twl.getRange('A1').setValue(new Date());
}
//Log Typhoon ride
function tylog() {
tyl.getRange(tyl.getLastRow() + 1, 1).setValue(new Date());
}
//Log Twister ride
function twlog() {
twl.getRange(twl.getLastRow() + 1, 1).setValue(new Date());
}
//Send Data to both logs and clear
function tyclear() {
tyd.getRange('A2:H2').copyTo(tym.getRange(tym.getLastRow() + 1, 1), {contentsOnly: true});
twd.getRange('A2:H2').copyTo(twm.getRange(twm.getLastRow() + 1, 1), {contentsOnly: true});
tyl.getRange('A1:A100').clearContent();
twl.getRange('A1:A100').clearContent();
}
URL Request:
https://script.google.com/macros/s/AKfycbxC5zYevR1IhfFcUMjmIqUaQ1dKNHTm4mhmWBq_Rc9HgemJQ6Q/exec?searchStringName=tylog
I put this into a new project by itself and it still returned undefined​.
function doGet(e) {
var passedString,whatToReturn;
passedString = e.parameter.searchStringName;
if (passedString === 'functionOne') {
whatToReturn = functionOne(); //Run function One
};
return ContentService.createTextOutput(whatToReturn);
};
function functionOne() {
var something;
return ContentService.createTextOutput("Hello, world!"); }
I believe that your URL should be https://script.google.com/macros/s/AKfycbxC5zYevR1IhfFcUMjmIqUaQ1dKNHTm4mhmWBq_Rc9HgemJQ6Q/exec?searchStringName=functionOne
After pondering this question for a while it makes no sense to require a return from functionOne. I was getting the client server communication mixed up with the Get request process. For most Get requests the request suggests some type of response since in general we're looking for some type of content to be displayed. In this situation that may not be required since the requestor is a machine.
The use of e.parameter.paramname; just enables us to send key/value pairs from within our querystring that we can recover to redirect our server actions.
2020 UPD:
Upon revisiting the question, I noticed that the OP runs the doGet trigger in the context of script editor, hence the e becoming undefined (as it is only constructed when a request hits the URL with an HTTP request with GET method).
Thus, the answer to the debugging part is:
When running a trigger manually from the script editor, event object will be unavailable
The answer to the running part is as a result of an extended discussion:
When assigning a result of the function, one has to put the return statement inside the function, and the tylog function did not return anything.
Also note that any change to a Web App code, unless accessing it via /dev endpoint (i.e. via /exec endpoint), won't be available until after redeployment.
References
Web Apps guide

Using google.visualization.Query in google web app

I have a functioning google web app that is identical to the app presented [here]
You'll note in code.gs that SpreadsheetApp.openByID......getRange().getValues() is used to retrieve an Array that is later converted into a DataTable in the Dashboard-JavaScript.html
Working Code.gs:
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
// Build and return HTML in IFRAME sandbox mode.
return template.evaluate()
.setTitle('Dashboard demo')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
/**
* Return all data from first spreadsheet as an array. Can be used
* via google.script.run to get data without requiring publication
* of spreadsheet.
* Returns null if spreadsheet does not contain more than one row.
*/
function getSpreadsheetData() {
var sheetId = '-key-';
var data = SpreadsheetApp.openById(sheetId).getSheets()[0].getRange("A1:D8").getValues();
return (data.length > 1) ? data : null;
}
I would like to use google.visualization.query instead of .getRange.
Does not work - currently returns "Google" not defined
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Index');
// Build and return HTML in IFRAME sandbox mode.
return template.evaluate()
.setTitle('Dashboard demo')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function getSpreadsheetData() {
var opts = {sendMethod: 'auto'};
var sheetId = '-key-';
var query = new google.visualization.Query('http://spreadsheets.google.com?key=' + sheetId, opts);
query.setQuery('select A, B, C, D');
query.send(draw)
}
function draw(response) {
if (response.isError()) {
alert('Error in query');
}
alert('No error')
}
I'm certain there are several issues - but I can't get any helpful errors returned to debug the issue.
My questions are:
Is is possible to use google.visualization.query in code.gs?
(I've read a post that leads me to believe that perhaps it cannot be used server side??/why)
If yes - how do I avoid "google not defined" errors
If no - is there an alternative method to "query" a google sheet from server side (the end goal is to have the flexibility to omit columns, perform aggregate functions, etc. when the datatable is retrieved). It is not possible to change the underlying spreadsheet (ie. sharing and publishing)
Finally- I apologize if any of this is formatted poorly or not clear. This is my first post here. In addition, I have limited experience and less expertise with javascript/apps script and google web apps.
No, it cannot be done server side, because google is a client side API.
Same reason as with google.script.run. (For a better understanding, you can check the whole code yourself, it resides here, a code that needs to be embedded within <script> tags, on the Html side).
As an alternative for the server side, you should be able to use the URLFetchApp.
The URL to compose should look something like:
var BASE_URL = "https://docs.google.com/a/google.com/spreadsheets/d/";
var SS_KEY = "stringSS_Key";
var BASE_QUERY = "/gviz/tq?tq=";
var partialUrl = BASE_URL + SS_KEY + BASE_QUERY;
var queryToRun = 'select dept, sum(salary) group by dept';
var finalUrl = partialUrl + encodeURIComponent(queryToRun);
And call URLFetchApp.fetch on it.

Url Parameter Error in Google Appscript with ContentService, MimeType XML

I am getting some issue when taking value form parameter here is my simple code in Google App script and deployed service. what is the issue ?
function doGet(e) {
var num = e.parameter.num;
var result=false;
result=(num%2==0);
if(result){
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.XML);
}else{
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.XML);
}
}
https://script.google.com/macros/s/AKfycbz86LRyPqowhg_ajj48oM13aESMPms30tbne-_p9sWwJVcaQzg/exec?num=20
Here is google appscript deployed url
This error I am getting when I am hitting this url
and code running error in App-script Environment
it seems that the issue might come from the modulo operation you are trying to apply to a string value, when I try this code it runs without error
function doGet(e) {
var num = Number(e.parameter.num);// make it a number before testing parity
var result=false;
result=(num%2==0);
var xmlContent = '<mydata>' + result+ num + '</mydata>';// added num value for test purpose
if(result){
return ContentService.createTextOutput(xmlContent).setMimeType(ContentService.MimeType.XML);
}else{
return ContentService.createTextOutput(xmlContent).setMimeType(ContentService.MimeType.XML);
}
}
That said, I suppose this is just a test code because I don't really see what it can be used for and the xml output is not valid but I'll leave you with that issue.

how do i call a published google script from another google script? the scripts are in different accounts

//script calling the published script, this script is in the account 1
function callScript(){
try{//published url
var response =UrlFetchApp.fetch("https://script.google.com/macros/s/../exec? calendar='CalendarName'");//calendar name as parameter
}catch(e){
Logger.log(e);
}
Logger.log(response.getContentText());
}
//account 2
//the code is published, it will run as the user who call the script(account 1), the access is for anyone
function doGet(e){//published script
var app = UiApp.createApplication();
var calendar=e.parameter.calendar; //calendar name as parameter
// Determines how many events are happening now
var now = new Date();
var oneMinuteFromNow = new Date(now.getTime() + (60 * 1000));
var events = CalendarApp.getCalendarsByName(calendar) [0].getEvents(now,oneMinuteFromNow);
var email=Session.getActiveUser().getEmail();
for(i in events){
var tituloEvento=events[i].getTitle();
var descEvento= events[i].getDescription();
var insertar=leerBD(email,tituloEvento,descEvento);
if (insertar) {
var inserto=insertarBD(email,tituloEvento,descEvento);
}
}
return ContentService.createTextOutput(e.parameter.string.calendar);
}
I want to call the script in the account 2 and pass a calendar name as parameter, in the account 2, the script will run as the user who call the script and get some events
Let's say Script1 is the 'client', or the script calling the 'server', Script2.
In the published Script2, go to the menu option 'File > Project properties', and copy the 'Project key' property into the 'Find a library' dialog of Script1 as described here:
https://developers.google.com/apps-script/guide_libraries#writingLibrary
You will also need to expose the Script2 functions you want to handle from Script1, and pass in your arguments as normal:
script1Var = Script2.myFunction(script1Param)
You don't need to use quotes in the parameters included in your URL, try like this:
var response =UrlFetchApp.fetch("https://script.google.com/macros/s/../exec?calendar=CalendarName");//calendar name as parameter
and also :
why are you writing e.parameter.string.calendar in the last tine of your sample code ? What is string for ? I guess the purpose is to return something else than just the calendar name ... please explain.
here is a working demo where I removed your specific function calls and use a public agenda.
it returns only the name of the calendar in the logger.
//script calling the published script, this script is in the account 1
function callScript(){
try{//published url
var response =UrlFetchApp.fetch("https://script.google.com/macros/s/AKfycbxg-XiPOSIzTATNO520r2DYqLWFjSJXIZ4h-9G_4eV4UZTgxnjo/exec?calendar=test_agenda");//calendar name as parameter
}catch(e){
Logger.log(e);
}
Logger.log(response.getContentText());
}
//account 2
//the code is published, it will run as the user who call the script(account 1), the access is for anyone
function doGet(e){//published script
var app = UiApp.createApplication();
var calendar=e.parameter.calendar; //calendar name as parameter
// Determines how many events are happening now
var now = new Date();
var oneMinuteFromNow = new Date(now.getTime() + (60 * 1000));
var events = CalendarApp.getCalendarsByName(calendar) [0].getEvents(now,oneMinuteFromNow);
var email=Session.getActiveUser().getEmail();
for(i in events){
var tituloEvento=events[i].getTitle();
var descEvento= events[i].getDescription();
}
return ContentService.createTextOutput(e.parameter.calendar);
}