doPost not working in Google app script - post

I came across various questions but none of them could solve my problem. I wrote a simple doPost() code in google app script:
function doPost(e){
Logger.log("Hello World");
}
Then I deployed it as a web app and pasted the url on hurl.it to make a post request. However, there is nothing being logged in the log and the response is 200 (Ok). I think it is not going inside this doPost() function. Can anyone guide as to what am I doing wrong here?

Your implementation does not meet all the requirements needed for a web app. Here's an excerpt from the documentation (link):
Requirements for web apps
A script can be published as a web app if it meets these requirements:
It contains a doGet(e) or doPost(e) function.
The function returns an HTML service HtmlOutput object or a content service TextOutput object.
Here are some examples:
function doGet(e) {
var params = JSON.stringify(e);
return HtmlService.createHtmlOutput(params);
}
function doPost(e) {
return ContentService.createTextOutput(JSON.stringify(e.parameter));
}
And just for completeness, you must also redeploy your web App as a new version every time you make changes to the code. Redeploying under an already existing version does not work, you have to make a new version for your changes to take hold.
Also using the standard Logger.log to trace changes within doGet(e) or doPost(e) is unreliable with web apps as they are executed asynchronously. I would recommend logging your output to a spreadsheet. There is an awesome script library called BetterLog that extends the Logger API to do just that; it can be found at the following link:
https://github.com/peterherrmann/BetterLog
UPDATE 2018-07-18
Apps Script now supports StackDriver Logging which is accessible from the Apps Scripts editor's View menu.

in order for the "exec" version of the published Web App URL to run with any new changes, you must publish a new version every time that you make a change to your script. It does not matter how small the change is. Instead of using Logger.log("Hello World"); I would write a value to a spreadsheet.
SpreadsheetApp.openById(id).getSheetByName(name).appendRow(['test']);
There are 2 different URL's for your Web App. One with 'dev' on the end and the other with 'exec' on the end. The 'dev' version is always the current code. The 'exec' version never changes unless you publish a new version.

I struggled with this for AWHILE NOW and I finally got lucky.
I use w3schools alot so I read fully on the form element and its attributes.
The ACTION attribute seems to be the key in getting doPost(e) to work for me and GAS.
Here's my HTML (removed opening and closing angle brackets)
<form
action="https://script.google.com/a/[org]/macros/s/[scriptID]/exec"
method="post" target="_blank" >
First name: input type="text" name="fname"<br>
Last name: input type="text" name="lname"<br>
input type="submit" value="Submit"
</form>
Here's my doPost ( the Logger ran as well as the new window displaying e.parameter)
function doPost(e){
Logger.log("I WAS RAN!!")
if(typeof e !== 'undefined') {
return ContentService.createTextOutput(JSON.stringify(e.parameter));
}
}

One of the reason can be you are using a Rest client like Postman. It won't work, though I don't know the reason why.
Try with a normal form like this and it will work:
<!DOCTYPE html>
<html>
<body>
<form action="https://script.google.com/macros/s/AKfyc.../exec">
First name:<br>
<input type="text" name="param1" value="ABC">
<br>
Last name:<br>
<input type="text" name="param2" value="XYZ">
<br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>

Related

In google sheets add some kind of dialog box that will display on an ipad

I am trying to add a yes/no message box to a google sheet that will display on an iPad. I have tried all the things below but none of them display the message. My goal is if the user changes a field the macro will change other fields if the user says it is ok. I can get this to work on a windows machine with no issues but when I try it on an ipad the message never appears. At this point I am just trying to get a message box to appear. This is what I have tried
1.
function onEdit(e) {
Browser.msgBox("test");
}
Result: The macros times out
2.
function onEdit(e) {
var html = HtmlService.createHtmlOutputFromFile('Page')
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'My custom dialog');
}
Page.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" />
</body>
</html>
I enabled the trigger for onEdit to get it to work and it works on the windows machine without issues but when run on the iPad I get:
Exception: You do not have permission to call Ui.showModalDialog. Required permissions: https://www.googleapis.com/auth/script.container.ui
So next I tried:
3.
function myFunction(){
Logger.log("myFun")
var html = HtmlService.createTemplateFromFile( 'Page' )
.evaluate()
.setWidth( 800 )
.setHeight( 400 );
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog( html, 'My page title' );
}
function onEdit(){
ScriptApp.newTrigger('myFunction')
.forSpreadsheet(SpreadsheetApp.getActive())
.onEdit()
.create();
}
Using the same page.html, this time in executions it looks like it runs but no box appears on the ipad(it does work on windows). I also tried spreadsheetApp.getUi().alert and prompt, these had the same results.
And Yes I have to use the iPad, I can not use another type of tablet.
Issue:
"Exception: You do not have permission to call Ui.showModalDialog. Required permissions: googleapis.com/auth/script.container.ui"
Fix:
What you can do is installing the trigger instead of using a simple trigger. The image below shows the difference between an installed (above) and a simple (below) trigger using the same code.
Output:
Note:
Don't use reserved function names on installed triggers to avoid it being executed twice like what's shown above. Change onEdit to something like promptUI or something else.
If the above fix isn't enough to show the dialog box, then we need to confirm if the issue might just be on the safari browser (if you are using one) since it worked on your other devices which I assumed are not using safari. You can try using an alternative browser in your device such as Google Chrome and see if the same issue persists. I recommended doing this since i'm seeing a number of issues between showModalDialog and safari
EDIT:
I have seen these related posts pointing out that there are some limitations on mobile apps. See the references below.
Also, some answers suggests that you need to access the spreadsheet via browser (google chrome desktop mode) and then trigger the script there.
References:
Add a script trigger to Google Sheet that will work in Android mobile app
google speadsheet api onOpen does not work on mobile ios
Executing Google Apps Script Functions from Mobile App
How to get scripts to work with phones and tablets

invokescriptasync HRESULT: 0x80020101' script runs fine in chrome and IE

I'm still trying to make the invokescriptasync work. I'm trying the following test on facebook.com and it fails with a HRESULT: 0x80020101' which normally means the script has an error in it, but I tried running the simple javascript in Chrome and IE without any problem.
private async void WebView_OnNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
await _webView.InvokeScriptAsync("eval", new[]
{
"document.getElementById('blueBarDOMInspector').innerHTML = '';"
});
}
Thanks
I have tested your code and the error is thrown only in case the blueBarDOMInspector is not found. I used the following simple HTML:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<p id="blueBarDOMInspector"></p>
</body>
</html>
You can confirm that the script works as expected with this HTML. So I suspect the problem is rather on HTML side than on side of UWP.
As for ScriptNotify not working - the website must be HTTPS and be added as trusted to appxmanifest. Better solution is web allowed object. A great example was posted in a question yesterday on SO or here as a sample project. Basically you have to create a Windows Runtime Component with a class marked as [WebAllowed] and then inject it in the WebView using AddWebAllowedObject method.
For your invoking JavaScript code issue,I've checked your code, it's simple, the possible issue might be the 'blueBarDOMInspector' object, please make sure that you could get the 'blueBarDOMInspector' object successfully when the OnNavigationCompleted is fired.
For your second question:
I can invoke the script : "window.external.notify('something');" but it doesn't raise the event ScriptNotify which is another problem :-(
Please check the document:
To enable an external web page to fire the ScriptNotify event when calling window.external.notify, you must include the page's Uniform Resource Identifier (URI) in the ApplicationContentUriRules section of the app manifest.

MVC Datalist is not working on prod server but works on Dev

I have an application that uses a datalist that works in the Dev environment but returns a blank field with no lookup in the Production environment. I want to use datalist extensively as it easily provides an auto complete facility but cannot until it works in Production.
Dev is MVC VS 2010 on IE 11.0 under Win7 and it scores 302 in the HTML5Test.
Production is IE 11.0 on Server 2012 R2 Standard reported as Win8.1 and scores 312 in the HTML5Test.
After much comparing, checking, trying, inspecting and reviewing I have found the source of the issue that stops datalist working.
MVC View Code in Index.cshtml
This is the eventual experimental code trying to isolate the issue:
#model IEnumerable<CRM_MVC.Models.BranchDiary>
#{
Layout = null;
}
<body>
<div>
<lable>Enter TV Series Name </label>
<input type="text" id="tv" name="series" list="tvseries" autofocus>
<datalist id="tvseries">
<option value="Heroes">
<option value="Lost">
<option value="Fringe">
<option value="CriminalMinds">
<option value="CSIMiami">
</datalist>
<p><strong>Note:</strong> The datalist tag is not supported in Internet Explorer 9 and earlier versions, or in Safari.</p>
</div>
</body>
Internet Explorer session showing Index.cshtml
The field should provide an autocomplete dropdown but doesn’t.
The Inspect screen shows that <datalist id=tv> is wrongly terminated by /datalist on the same line and after the option list /datalist wrongly has //datalist appearing after it.
When right click Edit HTML is selected for the Div, the original HTML correctly has the first datalist tag with no /datalist and the option list is correctly terminated at the end by the /datalist tag.
What can be done to stop the extras being added to so that it might work the same on Production as on Dev?
What resolved this was unchecking Display intranet sites in Compatibility View in IE Tools-> Compatibility View Settings.
Thanks to Mr Lister for this suggestion.
I will need to check to see if globally changing this setting affects anything else but it makes autocomplete work now as expected and required. Thanks again to Mr Lister for the assistance.

Fixing "You have included the Google Maps API multiple times on this page. This may cause unexpected errors."

I've included two below scripts in my header and I get the error "You have included the Google Maps API multiple times on this page. This may cause unexpected errors."
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js key=************"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
When I remove either script, I get additional js errors. How can I properly refactor these two scripts in my rails app?
In your example above, you're including the same script twice, but with different parameters. You should be able to solve your issue by including the script once, with all the required parameters like this:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE&libraries=places&sensor=false"></script>
If you're calling google maps via an ajax call, you can use window.google = {} upon exiting the state in which the map was called.
I know that in my case it's not a Rails app but might help to someone else ... I'm working with React and I was getting the same error when I was switching between views/pages.
And like wLc said window.google = {} worked like a charm and was deleting the error in the console but the <script> tag was remaining in the html and was added every time I was revisiting the page that has the map.
On componentWillUnmount I've added some code to remove the tag.
const allScripts = document.getElementsByTagName( 'script' );
[].filter.call(
allScripts,
( scpt ) => scpt.src.indexOf( 'key=googleAPIKEY' ) >= 0
)[ 0 ].remove();
window.google = {};

Get value of an input element on a firefox addon

How i can fetch the value of this input element in my main.js:
<input type="hidden" value="12124054" id="ctl00_cphContent_hdnID" name="ctl00$cphContent$hdnID">
I tried var id = document.getElementById("ctl00_cphContent_hdnPlayerID").value; and contentWindow.document.getElementById("ctl00_cphContent_hdnPlayerID").focus(); but i am getting errors that document and contentWindows are unidentified :(
You need to get the value from the page using a content script and then send the value to main.js - this is because web content is inherently untrusted by the addon-sdk. Please see these docs for more on how to use content scripts:
https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/dev-guide/addon-development/web-content.html#content_script_events
Here is an example add-on on Builder that shows how to pass values frmo the content script back to main.js. In this case I'm using the xui library to more easily bind events in the pgae.

Resources