# How to Get Google Forms Response Notifications on Your Phone

> Use a Forms-bound Apps Script trigger to send one privacy-minimal Ping when a new Google Form response arrives.

- Published: 2026-10-20
- Author: PingRoom
- Category: Developers
- Topics: Google Forms response notifications, Google Forms push notifications, Apps Script form submit notification
- Canonical: https://pingroom.io/blog/google-forms-response-push-notifications
- Cover image: https://pingroom.io/blog/google-forms-response-push-notifications.webp
- Cover description: Two PingRoom avatars receive one blank response card from a wooden chute while Pingo watches beside the tray.

To get a phone notification when someone submits a Google Form, attach an **installable form-submit trigger** to a Forms-bound Apps Script and send one fixed, privacy-minimal message to a PingRoom incoming webhook.

This guide sends **New form response — Workshop request received a response.** It does not put the respondent's answers, name, or email on a lock screen. Google Forms remains the response record; PingRoom carries the small update that tells a shared team to look.

This is a webhook recipe you configure, not a native Google Forms integration.

## Choose the simplest notification that fits

Google Forms can already [email a form editor for every new response](https://support.google.com/docs/answer/139706?hl=en). Use that when one editor checks email and no shared phone alert is needed.

| Need                                                          | Better fit                                                                            |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| One form editor wants an email for every response             | Google Forms' built-in email notification                                             |
| A selected PingRoom Room should receive one short phone alert | The Apps Script recipe below                                                          |
| A service needs every response body for processing            | The Google Forms API, Apps Script, or another approved backend—not a lock-screen Ping |

The Room should contain only the people who need to notice the event. It is not a substitute for the form's access controls, response history, review process, or retention policy.

## Keep the answers in Google Forms

Create a safe label for the form, such as **Workshop request**, **Volunteer signup**, or **Equipment check**. The script uses that fixed label instead of reading submitted answers.

For an illustrative workshop request, a submission produces:

> **New form response**
>
> Workshop request received a response.

The team opens Google Forms through its normal authorized route to review the details. The notification reveals no answer fields and does not claim that anyone accepted, approved, or completed the request.

[Pingo the Pigeon](/Pingo), our fictional CMO, approves of the closed-box rule: the detailed cards stay in the form; one small signal leaves the desk. He has no access to the form or the private Room. The human team chooses the copy and membership.

## Prepare the Room and script

The destination Room's owner needs active **PingRoom Pro** for incoming webhooks. Room members who want a native alert need PingRoom on a supported device with notifications allowed.

Follow the [incoming webhook setup](/blog/webhook-to-push-notification): open the Room's **Settings → Connections → From another app**, add a webhook named **Google Forms**, choose **Custom message**, and copy its URL. The complete URL is a credential. Keep it out of form questions, response sheets, source control, screenshots, and logs.

In Google Forms, open the form, select **More → Apps Script**, and name the bound project. In Apps Script, open **Project Settings → Script Properties** and add:

| Property               | Value                                                   |
| ---------------------- | ------------------------------------------------------- |
| `PINGROOM_WEBHOOK_URL` | The complete incoming webhook URL                       |
| `PINGROOM_FORM_LABEL`  | A short, non-sensitive label such as `Workshop request` |

A Forms-bound script shares the form's editor access. Use it only when you trust the form editors with the script and its configuration. Rotate the PingRoom webhook URL if it is exposed.

## Add the submit handler

Paste this function into the Apps Script editor and save it:

```javascript
function notifyFormResponse(e) {
  if (!e || !e.response || !e.source) return;

  const responseId = e.response.getId();
  const formId = e.source.getId();
  if (!responseId || !formId) {
    throw new Error("The submitted response has no stable identity.");
  }

  const properties = PropertiesService.getScriptProperties();
  const url = properties.getProperty("PINGROOM_WEBHOOK_URL");
  if (
    !url ||
    !/^https:\/\/api\.pingroom\.io\/api\/webhooks\/[^/?#\s]+\/[^/?#\s]+$/.test(
      url,
    )
  ) {
    throw new Error("Set a valid PingRoom webhook URL in Script Properties.");
  }

  const label = (properties.getProperty("PINGROOM_FORM_LABEL") || "").trim();
  if (!label || Array.from(label).length > 70 || /[\r\n\t]/.test(label)) {
    throw new Error("Set a one-line form label of 70 characters or fewer.");
  }

  const identity = formId + ":" + responseId;
  const digest = Utilities.computeDigest(
    Utilities.DigestAlgorithm.SHA_256,
    identity,
    Utilities.Charset.UTF_8,
  )
    .map(function (byte) {
      return ((byte + 256) % 256).toString(16).padStart(2, "0");
    })
    .join("");
  const eventKey = "gform-" + digest;

  let response;
  try {
    response = UrlFetchApp.fetch(url, {
      method: "post",
      contentType: "application/json",
      headers: { "Idempotency-Key": eventKey },
      payload: JSON.stringify({
        action: null,
        title: "New form response",
        message: label + " received a response.",
        correlation_id: eventKey,
      }),
      followRedirects: false,
      muteHttpExceptions: true,
    });
  } catch {
    throw new Error("Request failed. Check the webhook configuration.");
  }

  let accepted = false;
  try {
    accepted = JSON.parse(response.getContentText()).success === true;
  } catch {
    // A non-JSON response cannot confirm acceptance.
  }
  const status = response.getResponseCode();
  if (status !== 200 || !accepted) {
    throw new Error("PingRoom did not accept the Ping (HTTP " + status + ").");
  }
}
```

Google's Forms-specific submit event provides a `FormResponse` and the source `Form`. The script uses only their IDs. It never calls `getItemResponses()` or `getRespondentEmail()`.

The response ID and form ID are hashed into a stable `Idempotency-Key`. If Apps Script retries the same submission with the same fixed label, PingRoom can return the original accepted result instead of creating another Ping. Changing the label after an ambiguous failure changes the request body, so check Room history before retrying manually.

## Install one authorized trigger

In Apps Script, select **Triggers → Add Trigger** and choose:

| Setting      | Value                |
| ------------ | -------------------- |
| Function     | `notifyFormResponse` |
| Deployment   | `Head`               |
| Event source | From form            |
| Event type   | On form submit       |

Save and complete Google's authorization prompt. The trigger runs as the account that created it and needs permission to read the form event and make an external request. Install it from one responsible account. If several editors install the same trigger, one form response can run the handler several times.

![A PingRoom avatar closes the response archive while another carries one blank signal token past Pingo toward a face-down phone.](/blog/google-forms-response-push-notifications-1.webp)

_AI-generated editorial illustration. Pingo is PingRoom's fictional mascot; the people and workflow are illustrative._

## Test without exposing a real response

Create a harmless test form with no personal or sensitive questions, then submit one sample response.

Check four things:

1. Apps Script's **Executions** list shows one completed `notifyFormResponse` run.
2. Room history contains one **New form response** Ping.
3. Replaying the same test event does not create an extra Ping with the same event identity.
4. The lock-screen preview contains only the fixed label you approved.

For this article, we ran the exact embedded handler against a local mock of Apps Script and PingRoom's documented webhook contract. The check covered the expected payload, privacy boundary, stable identity, exact replay, changed-body conflict, invalid configuration, non-200 responses, malformed responses, and request failures. It did not use a live Google Form, PingRoom Room, phone, or delivery receipt.

## Know what this recipe does not guarantee

Apps Script quotas and authorization still apply. Trigger failures appear in Apps Script, and Google may email the trigger owner about failures. A successful PingRoom response means the event was accepted and queued; it does not guarantee that every device displayed an alert under every network, Focus, mute, or notification setting.

If the form controls healthcare, safeguarding, payment, legal, emergency, or regulated work, keep the approved case system, access controls, audit record, and escalation path authoritative. This recipe is an attention cue, not proof that a response was reviewed or acted on.

To pause the workflow, delete or disable the Apps Script trigger. To revoke the destination, regenerate or delete the incoming webhook in PingRoom.

Start with one harmless form and a small [PingRoom Room](/app/rooms). For a manual spreadsheet status change instead of a form submission, use the separate [Google Sheets phone-notification recipe](/blog/google-sheets-push-notifications).
