Google Sheets Form Responses to Teams Digest
On a schedule, the flow reads new rows from a Google Form's linked Google Sheet, summarizes them (counts, averages, notable answers), posts a digest to a Teams channel, and marks rows as processed. Turns a Google Form response sheet into a recurring team readout.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
On a daily schedule this cloud flow reads the response rows from a Google Form's linked Google Sheet, identifies the responses it hasn't reported yet, summarizes them (a count, an average rating, and a per-response line), posts the digest to a Microsoft Teams channel, emails the same digest to a distribution address, and then stamps each reported row as processed so it isn't counted again. It turns a Google Form response sheet into a recurring, self-deduplicating team readout — no manual copy/paste and no double-reporting.
Use Case
Teams that collect feedback, intake requests, or survey answers through a Google Form often end up with a response sheet nobody watches. This flow gives Operations and Marketing a hands-off daily summary in the channel they already live in (Teams) plus an email for stakeholders who aren't in that channel. Because it marks rows processed, each response is reported exactly once, and the run is idempotent — if it's off for a day, the next run catches everything new.
Flow Architecture
Run Daily Form Scan
RecurrenceFires once per day at 08:00 UTC. Google Sheets has no native new-row trigger, so the short-poll pattern (Recurrence + GetItems) is used.
Get Form Responses
Google Sheets — GetItemsReads every row from the linked sheet; rows keyed by form-question header plus __PowerAppsId__.
Filter New Responses
Filter arrayKeeps only rows whose Processed column is empty — the de-duplication gate.
Check New Responses Exist
ConditionOnly proceeds when at least one new response is found.
Aggregate New Responses
Apply to eachPer response: increment count, add to rating sum/count when rated, append an HTML digest line.
Compose Average Rating
ComposeratingSum divided by ratingCount, guarded against divide-by-zero.
Compose Digest Html
ComposeAssembles the full HTML digest (header, count, average, per-response list).
Post Digest To Teams
Microsoft Teams — PostMessageToConversationPosts the digest to the configured channel.
Email Digest
Office 365 Outlook — SendEmailV2Emails the same digest to the distribution address.
Mark Rows Processed
Google Sheets — PatchItemStamps each reported row's Processed column, preserving all other answers.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_GSheetId | String | <configure> | Spreadsheet file ID of the Google Form response sheet. |
| flowlibs_GSheetTab | String | <configure> | Worksheet/tab name holding the responses. |
| flowlibs_TeamsGroupId | String | <your-team-id> | Target Teams team (group) GUID. |
| flowlibs_TeamsChannelId | String | <your-channel-id> | Target Teams channel ID. |
| flowlibs_DigestRecipientEmail | String | alerts@yourcompany.com | Email recipient for the digest. |
| flowlibs_ProcessedColumn | String | Processed | Header of the column stamped after a row is reported. |
| flowlibs_RatingColumn | String | Rating | Header of the numeric column to average. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Google Sheets | shared_googlesheet | GetItems PatchItem |
| Microsoft Teams | shared_teams | PostMessageToConversation |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Point at your response sheet
- Set flowlibs_GSheetId / flowlibs_GSheetTab to your Google Form response sheet and tab.
- Rating column
- Set flowlibs_RatingColumn to your form's rating-question header; leave as-is if you have no rating and the average simply reports 0.
- Processed marker
- Add a Processed column to the sheet, or set flowlibs_ProcessedColumn to an existing marker column.
- Cadence
- Change the Run Daily Form Scan recurrence for a different cadence (e.g. hourly).
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01New-response gate (Filter array where)
Keeps only rows whose Processed column is empty.
EXPR.02Has-a-rating check (Condition)
True when the response supplied a rating.
EXPR.03Average rating
Guards against divide-by-zero.
EXPR.04Mark row processed (PatchItem item body)
Passes the whole row object as one expression so dynamic-schema validation stays clean.
EXPR.05Row key for PatchItem
Stable row key used to patch the correct row.
Customize & download
Generate a ready-to-import copy of this solution with your environment-variable values baked in — available on Base, Pro, or Team.
Upgrade to customize
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.