Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create a new GitHub Issue from a Google Form submission

Wiring up a Google Form to GitHub is not that difficult with a little bit of Apps Script automation. All you need is a Google account, a GitHub account, and a web browser...

Set up your GitHub Personal Access Token

Personal access tokens provide an easy way to interact with the GitHub API without having to mess with OAuth. If you don't already have a personal access token with repo or public_repo access, visit your GitHub settings page and generate a new token.

Be sure to copy your token some place safe and keep it secure. Once generated, you will not be able to view or copy the token again.

Set up the Form & Spreadsheet

  1. Create a Google Form.
  2. From the Responses tab, click the More icon.
  3. Select Choose a response destination.
  4. Select New spreadsheet: Creates a new spreadsheet in Google Sheets for responses.
  5. Click Create to create and open the sheet.

Configure the App Script Logic

  1. You should have a newly created blank spreadsheet with headers automatically generated from your form.
  2. Click Tools > Script editor... to launch the App Script editor coding environment. This Script will be bound to your sheet, so you can listen for form submissions and fire off a new issue to your GitHub repo.
  3. Delete the boilerplate code in the Code.gs file and replace it with something similar to this:
var ghToken = "my-personal-access-token";

function onFormSubmit(e) {

  var title = e.values[2] + ": " + e.values[4];
  
  var body = "| Contact Email | Organization Name | Change Date | Change Type | Plan | Licenses | Comments |\n" +
             "|---|---|---|---|---|---|---|\n" +
             "| "+e.values[1]+" | "+e.values[2]+" | "+e.values[3]+" | "+e.values[4]+" | "+e.values[5]+" | "+e.values[6]+" | "+e.values[7]+" |" ;
  
  var payload = {
    "title": title,
    "body": body
  };
   
  var options = {
    "method": "POST",
    "contentType": "application/json",
    "payload": JSON.stringify(payload)
  };
  
  var response = UrlFetchApp.fetch("https://api.github.com/repos/bmcbride/my-repo/issues?access_token="+ghToken, options);
}
  1. The onFormSubmit function includes an event object e, which includes the form/spreadsheet field values as a simple array with values in the same order as they appear in the spreadsheet. e.values[0] is the first spreadsheet column (typically Timestamp).
  2. In my example, I'm collecting information from users who wish to make license changes to a web service. I'm building a simple markdown table, which includes some of the form data in the body of my issue.
  3. Reference the GitHub Issues API for a full list of options for programmatically creating a new issue.
  4. Once we've built the title and body of the issue, we can build the HTTP request using App Script's URL Fetch Service.
  5. Give your app script project a name and save it .

Set up the Trigger

  1. From within the app script editor, click Resources > Current project's triggers.
  2. Click to add a trigger
    • Run: onFormSubmit
    • Events: From spreadsheet, On form submit
  3. Click Save and accept any authorizations to access your forms and access web services on your behalf.
  4. This trigger will listen to form submissions and pass the data to your function, which POSTs the new issue to your GitHub repo.

Conclusion

This exercise demonstrates how to utilize Google Forms as a front-end for capturing information, which can then be passed on to other services, such as GitHub, CartoDB, Fulcrum, etc.

@Thomanphan

This comment has been minimized.

Copy link

commented Mar 7, 2016

don't work
TypeError: Cannot read property "values" from undefined. (line 5, file "Code")

@Thomanphan

This comment has been minimized.

Copy link

commented Mar 12, 2016

Can you fix ?

@tylerswartz

This comment has been minimized.

Copy link

commented Apr 15, 2016

@Thomanphan, I was getting the same thing and switched out the e.values.

Looks like this now:

function onFormSubmit(e) {

  var itemResponses = e.response.getItemResponses();
  var item1 = itemResponses[1].getResponse();
  var item2 = itemResponses[2].getResponse();
  var item3 = itemResponses[3].getResponse();
  var item4 = itemResponses[4].getResponse();
  var item5 = itemResponses[5].getResponse();
  var item6 = itemResponses[6].getResponse();
  var item7 = itemResponses[7].getResponse();
  var item8 = itemResponses[8].getResponse();

  var title = "Bug: " + item2;

  var body = 
      "<strong>Submitted By: </strong>" + item1 +
        "\n<strong>url: </strong>" + item3 +
        "\n<strong>device: </strong>" + item4 +
        "\n<strong>browser: </strong>" + item5 +
        "\n<strong>expected behavior: </strong>" + item6 +
        "\n<strong>actual behavior: </strong>" + item7 +
        "\n<strong>steps to reproduce: </strong>" + item8;

  var payload = {
    "title": title,
    "body": body
  };

  var options = {
    "method": "POST",
    "contentType": "application/json",
    "payload": JSON.stringify(payload)
  };

  var response = UrlFetchApp.fetch("https://api.github.com/repos/EXAMPLE?access_token="+ghToken, options);
}
@troystarwalt

This comment has been minimized.

Copy link

commented Aug 18, 2016

Hey y'all. How would you recommend hiding your GitHub token?

@WPSAppleProject

This comment has been minimized.

Copy link

commented Oct 26, 2016

Just a little tweak on this - I needed to bind the script to the Google Form in order for it to work. But once working it's a great script! Thanks for posting.

@ThadeuLuz

This comment has been minimized.

Copy link

commented Apr 8, 2017

@bmcbridge Simple question. Is the hard coded key safely hidden? Where will this script run? google servers, so probably yes.

@bellerbrock

This comment has been minimized.

Copy link

commented Jun 9, 2017

Thanks @bmcbride!
@Thomanphan, @tylerswartz : I encountered the same error, but as far as I can tell it is only because there is no actual FormSubmit event happening when you run the debugger. It worked when I used the form preview and submitted real data.

A few things that would have saved me some time if I knew them in advance:
There is no console.log() in Google App scripts. Instead you can use Logger.log() while debugging, then view what you logged at View > Logs
While setting up the trigger, there is an option to alter the notification frequency. For debugging it was helpful to change the notifications to 'email immediately'.
Github uses a special domain and path ("https://api.github.com/repos") for api requests. If you are an idiot like me and try to use "https://github.com" you will get a confusing 403 "Cookies must be enabled to use GitHub" response.

@scrthq

This comment has been minimized.

Copy link

commented Jun 19, 2017

@troystarwalt - little late, but it would be hidden by default, since you're actually placing the Google Apps Script on the Google Sheet that the Form stores data on. The only way it would be visible to anyone but you is if you shared that Sheet with someone else.

@antoooks

This comment has been minimized.

Copy link

commented Sep 12, 2017

I want to correct this part: https://gist.github.com/bmcbride/62600e48274961819084#set-up-the-trigger

The Resources > Current project's triggers is actually Edit > Current project's triggers

@Rup1

This comment has been minimized.

Copy link

commented Oct 27, 2017

@tylerswartz with your code I still get cannot read property 'getResponse' of undefined

@southpawlife

This comment has been minimized.

Copy link

commented Nov 2, 2017

Worked great for me! Thanks for the guide!

@mattkasten

This comment has been minimized.

Copy link

commented Jan 12, 2018

@tylerswartz @Rup1 I also am getting the cannot read property 'getResponse' of undefined error.

This is the code:

var itemResponses = e.itemResponses.getItemResponses();
var item1 = itemResponses[1].getResponse();
var item2 = itemResponses[2].getResponse();
var item3 = itemResponses[3].getResponse();

is there a fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.