Create posts from Google Forms responses

Heyah,

I have written a short script automatically posting new Google-Form-Entries to Discourse. You can use it to allow any kind of 3-party Data input into discourse for example:

  • Anonymous Feedback
  • Support-Request
  • Membership-Applications (this is what we do with it)

The script

The script is small and simple:

// ----- MINIMUM CONFIGURATION !!!! // generate this at /admin/api API_KEY = "d29dXXXXXXXXXXXXXXXXXXXXX70" // use full qualified domain name in url to discourse index TARGET_INSTALLATION = "http://DISCOURSE.EXAMPLE.ORG/" // ----- Optional Configuartion // which category to post this to? Default: 'uncategorized' CATEGORY = 'uncategorized' // which user should be the one posting? Default: 'system' POSTER = "system" // you probably wanna activate this, when using templates INCLUDE_RAW_DATA = true // the title to post at, // should contain any 'form'-replacer or Discourse might complain it already has that title TITLE_TEMPLATE = "New Form Entry: {{Name}}" // Wanna have it look pretty? TEMPLATE = "# {{Name}}\n\n - Water Type: {{Water}}" + function _compile(source, values){ var processed = source; for (key in values) { processed = processed.replace("{{" + key + "}}", values[key]); } return processed; } function _compile_data_from_form(formResponse){ var data = {}, itemResponses = formResponse.getItemResponses(); for (var j = 0; j < itemResponses.length; j++) { var itemResponse = itemResponses[j]; data[itemResponse.getItem().getTitle()] = itemResponse.getResponse(); } return data; } function postToDiscourse(evt) { var vals = evt.namedValues || _compile_data_from_form(evt.response), title = _compile(TITLE_TEMPLATE, vals), text = _compile(TEMPLATE, vals); if (INCLUDE_RAW_DATA) { var entries = []; for (key in vals){ entries.push(" - **" + key + "**: " + vals[key]); } text += "\n Raw Values: \n\n" + entries.join('\n'); } UrlFetchApp.fetch(TARGET_INSTALLATION + "/posts", {'method': 'post', 'payload':{ 'category': CATEGORY, 'auto_track': false, 'title': title, 'raw': text, 'api_key': API_KEY, 'api_username': POSTER }}); } function API_TEST(){ //var form = {namedValues:{'Name': 'Benji', 'Email': 'Testi'}}; var form = FormApp.openById("1RnCD4I2VgWpzTiJTq-0qq6u-v-LEpEKQgOBmhafTsQo"), formResponses = form.getResponses(), newestResponse = formResponses[formResponses.length -1]; postToDiscourse({response: newestResponse}); } 

Installation

  1. Generate an ADMIN-Key of your installation at /admin/api

  2. Add Script to a new googles form or existing one via Tools-> Script Editor

  3. Copy the entire script into the new Editor that opens

  4. Replace the API-Key in the script with the one from your installation,
    Change the Installation-Target-Name

  5. Save and check your configuration by running the “API_TEST” function:

  6. A new post should show up in your Discourse.
    – you might want to do redo this one until the configuration (posting user, posting in proper category) are all figure out

  7. Connect function to trigger by going to Resources->All Triggers and an on-form-submit-trigger connected to the postToDiscourse function:


    (you might be asked to give permission when saving the first time: yes, please do so)

Voilá, you’ll receive new posts (including all update and email features) of forms submitted in your discourse instance from now on.

You might want to also take a look at my “automatically email form-data” script and add that one, too. As always, feel free to posts questions, feedback and praise right down here as replies :slight_smile: .

16 Likes

Looks like there was a tiny bug in the form, where it didn’t succeed when using form-only-forms. Updated the original Post with the fix.

This still works really well. Thought the Google forms UI has changed a little, easy to work out.
But there is a bug in the code if folks are not aware of:

Need to remove the + on the end. I suspect that there was more content but wasn’t finished.

Great job!

~Cheers

Can you build a plugin for easier setup google form :slight_smile:

Since the API changed, the code for Google Forms (Google App Script) changed too. Here is a sample with a single question in the form.

FORM_ID = "<get this from the form URL>" ITEM_ID = <get this from the Developer tools, look for the id of the whole question element> // int value URL = "<site URL with the trailing />" CATEGORY = <from sites.json> // int value API_KEY = "<admin API key>" POSTER = "<assigned user name to the key>" MAX_TITLE_SIZE = 50 // this is just to keep title size in control function onFormSubmit() { var form = FormApp.openById(FORM_ID), item = form.getItemById(ITEM_ID), // repeat this for all items in the form or use alternative means of getting all items formResponses = form.getResponses(), newestResponse = formResponses[formResponses.length - 1], response = newestResponse.getResponseForItem(item).getResponse(); // this reads only the single item noted above console.log(response) if (response.length < 20) { response = "New topic posted: " + response // just to make sure response captured is > 20 characters } var title = response.substring(0,Math.min(MAX_TITLE_SIZE,response.length)); // just to make sure the title is not too big	const url = URL + "posts"; const fetched = UrlFetchApp.fetch(url, {	"method": "POST",	"headers": {	"Api-Key": API_KEY,	"Api-Username": POSTER,	"Content-Type": "multipart/form-data",	"Accept": "application/json",	"Content-Type": "application/json"	},	"muteHttpExceptions": true,	"followRedirects": true,	"validateHttpsCertificates": true,	"contentType": "application/json",	"payload": JSON.stringify({"title":title,"raw":response,"category":CATEGORY})	});	Logger.log("Response code is %s", fetched.getResponseCode());	Logger.log(fetched.getContentText()); } 

I hope this helps anyone looking for something similar for the original topic but with the new API.

1 Like