Closed yogat3ch closed 3 years ago
Raw data is finally coming in!
Update 2020-12-20T16:10:55: I used the "Test Web App" link when publishing some changes to the GAS. Turns out it was erroring because there wasn't a doGet function. Apparently that is required, even if the app will only be receiving POST requests. After adding doGet I'm finally getting data in the sheet 🎉
Alright, seems that the missing doGet
method was the culprit all along. For anyone who reads this, every script must have a doGet method to function.
Here's the final code (with script ID omitted and also redacted from above):
var SHEET_NAME = "raw"; // Enter sheet name where results will be collected
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
function doGet(e) {
return 0;
}
function doPost(e){
console.log(e);
return handleResponse(e);
}
function handleResponse(e) {
// The LockService allows you to have only one invocation of the script or portions thereof run at a time.
// More about: http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
var lock = LockService.getPublicLock(); //Public lock locks for any invocation of script.
lock.waitLock(30000);
try {
// Alternatively, you can hard code spreadsheet here
// eg. SpreadsheetApp.openById("REPLACE WITH YOUR ID")
var doc = SpreadsheetApp.openById("1LIwic5pkgyLX0sWlvTBIKCyfr3WRBHJTjifclOBteOA");
var sheet = doc.getSheetByName(SHEET_NAME);
var data = JSON.parse(e.postData.contents);
Logger.log(data);
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
for (i in headers){
if (headers[i] == "datetime"){
row.push(new Date());
}
else if (headers[i] == "raw_data"){
row.push(JSON.stringify(data));
}
else {
//To support multiple choice question (checkboxes)
if(Array.isArray(data[headers[i]])) {
row.push(data[headers[i]].join('|'));
}else {
row.push(data[headers[i]]);
}
//TODO: Support other types of questions
}
}
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch (e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally {
//Release public lock from line 19
lock.releaseLock();
}
}
function matchHeader (head, data) {
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
Hi @fischerbach , So this script broke for me a short while after getting it working - and I think it had to do with the ES6 upgrade on Google Apps Scripts.
After a good long period of trying to figure out what the issue is I realized that the i
in the for
loop isn't formally declared as a variable. Changing this to var i in headers
allowed me to run it with test data using the debugger. However, I'm unable to get the web app to respond in POST
requests from the site or from using curl
on my local machine.
I added some new questions to the survey and updated the sheet headers accordingly but that's the only change made since it was last functioning.
Any ideas?
Hi Rafał, Thank you for publishing this article! I was trying to come up with a means of implementing SurveyJS just like this over the past few days, and here you post an article detailing how to do it! Quite a synchronicity! I created and deployed a survey on my website by using the "safe" jQuery syntax such that it works on Wordpress. I've tested the alert method and it outputs the responses to the rating and comment type questions like so:
I've set up a sheet and replaced the necessary values in the script below. I've published as a web app with "Anyone, even anonymous" publishing permissions.
However, I'm not getting any data populating the sheet.
I think it might have to do with the Rating & Comment question types not being supported yet:
and the headers not matching
datetime
orraw_data
, so the conditional opts for the finalelse
statement only suited for multiple choice questions - so the sheet reports back with an error:The JSON payload looks like this:
I'm going to see if I can come up with some javascript such that the sheet will accept the data. I'll share them when I complete them.
The survey has nine main questions named with a single word, with a
-detail
optional question using the same name.If you have any simple solutions offhand to handle these questions types that would be great!
Update 2020-12-20T15:53:59: When I look at the Executions in the Google Apps Script dashboard there doesn't seem to be any record that it's actually running the
doPost
function so I wonder if thePOST
requests are actually being received?Update 2020-12-20T16:06:37: I manually sent a CURL POST request with a very simple JSON body and I'm still getting error: "exception"
Update 2020-12-20T16:10:55: I used the "Test Web App" link when publishing some changes to the GAS. Turns out it was erroring because there wasn't a
doGet
function. Apparently that is required, even if the app will only be receivingPOST
requests. After addingdoGet
I'm finally getting data in the sheet 🎉I've updated the script below with the current implementation with some lines for debugging/logging:
Here's the Javascript as it appears on the site: