Skip to main content

Receive Google Forms responses

Guides

Google Forms has no webhook of its own. An Apps Script attached to the form sends each response to DataLug and signs it with the DataLug signature. Receive a webhook from any system covers the shared settings.

Create the webhook​

  1. In Manage Account > Webhooks, select New webhook, enter a name and keep Signature as DataLug signature.
  2. Set Event id for duplicates to Field path and enter responseId.
  3. Press Create webhook and copy the webhook URL and the secret.

Add the script​

  1. Open Apps Script from the form editor.
  2. In Project Settings, add a script property named DATALUG_WEBHOOK_SECRET with the secret.
  3. Replace the script with the code below and set WEBHOOK_URL to the webhook URL.
  4. Add a trigger for onFormSubmit with the event type On form submit.
const WEBHOOK_URL = "PASTE_THE_WEBHOOK_URL_HERE";

function onFormSubmit(e) {
const secret = PropertiesService.getScriptProperties().getProperty("DATALUG_WEBHOOK_SECRET");
const answers = {};
e.response.getItemResponses().forEach(function (item) {
answers[item.getItem().getTitle()] = item.getResponse();
});
const body = JSON.stringify({
responseId: e.response.getId(),
submittedAt: e.response.getTimestamp().toISOString(),
email: e.response.getRespondentEmail(),
answers: answers,
});

// X-DataLug-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "t.body">
const t = Math.floor(Date.now() / 1000);
const mac = Utilities.computeHmacSha256Signature(t + "." + body, secret, Utilities.Charset.UTF_8);
const hex = mac
.map(function (b) {
return ("0" + (b & 0xff).toString(16)).slice(-2);
})
.join("");

const res = UrlFetchApp.fetch(WEBHOOK_URL, {
method: "post",
contentType: "application/json; charset=utf-8",
payload: body,
headers: { "X-DataLug-Signature": "t=" + t + ",v1=" + hex },
muteHttpExceptions: true,
});
if (res.getResponseCode() !== 202) {
throw new Error("DataLug answered " + res.getResponseCode());
}
}
Keep the secret out of the code

The script reads the secret from its script properties, so the code can be shared without it.

What arrives​

One row per response, with responseId, submittedAt, email and an answers object keyed by question title. email is empty unless the form collects email addresses.

Duplicates and responses​

responseId is the event id, so a response sent twice runs once. An accepted request is answered 202; the script raises an error on any other status, and the failure shows in the script's executions.