0

I just made my first website and linked my 'contact' page to google sheets using GAS, however, once the form is submitted it redirects to a 'script.googleusercontent.com' URL displaying '{"result":"success","row":8}' How can I automatically redirect this back to my original website? I used bootstrap studio to make my website

I tried adding


const sheetName = 'Sheet1'
const scriptProp = PropertiesService.getScriptProperties()

function initialSetup () {
  const activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
  scriptProp.setProperty('key', activeSpreadsheet.getId())
}

function doPost (e) {
  const lock = LockService.getScriptLock()
  lock.tryLock(10000)

  try {
    const doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
    const sheet = doc.getSheetByName(sheetName)

    const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
    const nextRow = sheet.getLastRow() + 1

    const newRow = headers.map(function(header) {
      return header === 'Date' ? new Date() : e.parameter[header]
    })

    sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

    return ContentService
      .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  catch (e) {
    return ContentService
      .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  finally {
    lock.releaseLock()
  }

  
function doGet() {
  return HtmlService.createHtmlOutput(
    "<form action='submitdata.html' method='get' id='redirect'></form>" + 
    "<script>document.getElementById('redirect').submit();</script>");
}

}

to the end of google apps script, which did nothing. I just learned the basics with HTML and a bit of CSS as this is my first website, so something simple like this is going a little over my head. Simple explanations would be extremely helpful!

  • It's hard to help you debug without seeing more of the code, are you able to share more of the code you used that is resulting in this situation? – Miguel Rivera Rios Jul 17 '23 at 22:01
  • Please provide enough code so others can better understand or reproduce the problem. – Community Jul 18 '23 at 00:10
  • @Miguel Rivera Rios Okay, and just to add, I have my website hosted in bootstrap studios, not GAS. I simply made a form and only have this one script attatched to the form, all my website files are in bootstrap studio. I will update my original post with the full code from my GAS. Also, am I supposed to simply add the above function to the end of my script, or is it something else? thanks! – Daniel Huddleston Jul 18 '23 at 16:24
  • @MiguelRiveraRios^ – Daniel Huddleston Jul 18 '23 at 17:52

1 Answers1

0

Thank you for adding more of your code. In your specific case, it sounds like you have a website, you added a simple form to your website to collect user information (ie name, email, etc), and you told your form to send the data to your Google Web App (maybe by specifying the Google Web App URL on the form submit feature), which should then process the data, and add the data to a Google Sheet. Please correct me if any of that is wrong.

You said you're new to some of this, so I'll be more verbose, but skip ahead if you already know this.

First let me quickly explain how Google Web Apps work (most of this information can be found on Google's own documentation). A Google Web App is basically a set of code that is exposed to the internet via a singular URL (something like https://script.google.com/macros/s/<<UNIQUE_ID>>/exec). Depending on the type of request that hits that URL, the Web App will function differently. If a GET request (which is generally just a request for some information/resource) hits the URL, then the Web App will attempt to run whatever code is within the doGet. If a POST request (which generally contains some type of new form data) hits the URL, then the Web App will attempt to run whatever code is within the doPost. (There are other types of requests, but Google Web Apps really only work on the Get/Post binary.) Also important to note that whatever is served/returned from the doGet/doPost is actually sandboxed within an iFrame (which is why you always see that This application was created by another user, not by Google header).

(Sort of a side point, I see that your doGet is actually nested inside your doPost. That won't work, doGet needs to be at the top level of the file for it to work. Regardless though, that code won't work as it'll just attempt to redirect from inside the iFrame and most sites do not allow themselves to be iFramed.)

With that in mind, your code seems to be working as it's written. When a user submits your contact form, the data gets sent to the Google Web App URL, and your Web App proceeds through the doPost code where it will attempt to append the data to your spreadsheet. The way you have your logic written, whether or not the data is successfully added to the spreadsheet, you will serve some simple text back to the user (via ContentService.createTextOutput), which is the '{"result":"success","row":8}' that you were referring to. Ideally, after processing the data, you want the user to be redirected back to your site, as opposed to them seeing this text. This was actually possible a couple years ago, but it seems like Google has tightened up their security a bit, and this is no longer possible (see their official notes, as well as this post and this post referring to the same thing). Basically, Google did this to protect the user from things like malicious auto-redirects and to promote a safer environment in their Web App ecosystem.

As an alternative to automatically redirecting back to your website, you can add a button that the user can click to send them back to your website. As long as there is still an explicit user action/gesture, Google is okay redirecting the user to a new page, they just don't want the browser to automatically redirect the user without their input. For example, you can add a new html file to your web app:

redirectSuccess.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
      <p>Thank you for submitting your information!</p>
      <button onclick="window.top.location.replace('<<YOUR_WEBSITE>>')" type="submit">Navigate to Other Page</button>
  </body>
</html>

Because of your try/catch you can also add another HTML file for if the process fails for whatever reason:

redirectError.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
      <p>Whoops sorry about that, something went wrong. Please try again alter.</p>
      <button onclick="window.top.location.replace('<<YOUR_WEBSITE>>')" type="submit">Navigate Back to Website</button>
  </body>
</html>

and then your doPost will will look like this (the rest of the file can remain as is):

function doPost(e) {
  const lock = LockService.getScriptLock()
  lock.tryLock(10000)

  try {
    const doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
    const sheet = doc.getSheetByName(sheetName)

    const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
    const nextRow = sheet.getLastRow() + 1

    const newRow = headers.map(function (header) {
      return header === 'Date' ? new Date() : e.parameter[header]
    })

    sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

    const template = HtmlService.createTemplateFromFile("redirectSuccess");
    template.url = ScriptApp.getService().getUrl();
    return template.evaluate();
  }

  catch (e) {
    const template = HtmlService.createTemplateFromFile("redirectError");
    template.url = ScriptApp.getService().getUrl();
    return template.evaluate();
  }

  finally {
    lock.releaseLock()
  }
}

(Make sure that if you make any changes to your Web App, that you Deploy a new version of your Web App, and if the Web App URL changes, point your contact form to the new URL.)

Then after the users submits the form, they will be directed to the above redirect page and when the user clicks the button, they are taken back to your website. Of course this is not ideal and you'd definitely want to style the redirect page to be inline with your website. The only other real alternative would be if you had full control over the javascript on your Bootstrap Studios page, you could prevent the form from redirecting while still sending the data to your webapp (you can see some options here (the more recent answers are on the bottom), but I'm not sure if you have that level of control/experience.

  • You have no idea how much this helps me, however I still have a few questions. You are correct, I simply have this one script in GAS and I connected it by adding the URL to my forms code. I can definitely add a html file into the GAS, however I'm still confused as to where I add this redirect code. Do I make a second script, or does this go at the end of the GAS I already have? also, do I replace the 'ContentService.createTextOutput' command, as I will want to display my new button and not the ''{"result":"success","row":8}''? you have no idea how much I appreciate your help! – Daniel Huddleston Jul 18 '23 at 20:42
  • After adding this to my script, I still get the same output. I even made a redirect.html inside my GAS and am having the same issue. Here is what my GAS looks like now, as well as my form code. [link](https://imgur.com/a/D53jQdd) – Daniel Huddleston Jul 18 '23 at 20:58
  • I updated my answer to show exactly what your doPost would look like and to include 2 pages (in the event of an error or success). If you are still getting the same output, make sure to redeploy the web app and attach the new deployed url to the contact form (re-deploying the web app usually generates a brand new URL) – Miguel Rivera Rios Jul 18 '23 at 21:10
  • I hate to keep bugging you, however I added your code and now when submitting GAS says "Exception: No HTML file named redirectError was found. (line 35, file "Code")" also, in my html form I have dropdowns to select options, and before the selections would post to my google sheet, and now they are left blank. Sorry I'm so confused, I really do appreciate your help though. Here's what everything looks like. [link](https://imgur.com/a/ygMLdwl) – Daniel Huddleston Jul 18 '23 at 21:40
  • Sorry I didn't say it, but I also modified the HTML sections of my answer as well. Since you have a try/catch I figured you would want to serve different things to the user depending on whether or not the doPost succeeded. If you are using the code as I have it for your `doPost`, you'll need 2 additional HTML files in your GAS project, one titled `redirectSuccess.html` and another titled `redirectErrror.html` – Miguel Rivera Rios Jul 18 '23 at 21:42
  • It worked!!! thanks so much, I'd even love to give you a small tip if you have apple pay, not that I have very much money. I really appreciate your help, I just have one small issue and it's that my form has a select component and those options aren't getting added to my form, they used to however something changed. Do you have any idea for that? – Daniel Huddleston Jul 18 '23 at 21:49
  • Haha no tip needed, but please do upvote and accept the answer so others can see it if they run into the same issue, thanks! – Miguel Rivera Rios Jul 18 '23 at 21:49
  • I just made this account and need more rep to upvote, but once I can I promise I will. And I'll keep messing with the form until I fix my other issue causing some of the data to not transfer. – Daniel Huddleston Jul 18 '23 at 21:50
  • Ah gotcha, you won't be able to update as a new account, but you should be able to accept the answer (the checkbox outline underneath the upvote/downvote buttons), but if not nbd – Miguel Rivera Rios Jul 18 '23 at 21:54
  • Will do, and I will also upvote once I can. Do you have any idea what's causing the script to fail each time? while it does redirect now, it's redirecting to redirectError.html and I believe it's because it's not grabbing the information from my 'select' component on my form, and only text input is going to the google sheet. Before adding this code I wasn't having this issue, I will continue to mess with it however if you see anything I may have done wrong I'd really appreciate the input. Thanks again – Daniel Huddleston Jul 18 '23 at 21:58
  • Sorry I don't see anything immediately that might be wrong, are you able to share your web app for me to see? Alternatively, you might be able to get more information if you console log the error in the catch statement `console.log(e)` and review the logs. – Miguel Rivera Rios Jul 18 '23 at 22:16