Create posts from Google Forms responses

סיכום מבוסס בינה מלאכותית

In this how-to discussion for Administrators, lightyear shares a Google Apps Script that automatically posts new Google Form responses to Discourse, useful for anonymous feedback, support requests, or membership applications. The script requires minimal configuration: an API key, target Discourse URL, category, poster username, and customizable templates for title and body. A test function (API_TEST) helps verify setup before connecting the script to a form-submit trigger. lightyear later fixed a minor bug affecting form-only submissions. SGTGunner confirms the script still works well despite UI changes in Google Forms, but notes a syntax error in the original TEMPLATE string — the trailing + should be removed. thaidb humorously suggests building a plugin for easier setup. srmrox provides an updated script sample compatible with the newer Discourse API, demonstrating how to post a single-question form response with proper headers and payload formatting, including title length control and logging. The updated script uses JSON payload and modern fetch options, making it more robust for current implementations.

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 לייקים

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