Automate Typeform Feedback to Google Sheets with n8n
Collecting course feedback is only useful if you can quickly turn it into structured, actionable data. This guide explains, in a technical and reference-style format, how to implement a complete Typeform → n8n → Google Sheets workflow. The workflow listens for new Typeform submissions, normalizes the payload, evaluates a numeric rating, and routes positive and negative feedback into separate Google Sheets.
The walkthrough is based on the sample template JSON referenced in the original article and focuses on node configuration, data flow, and practical implementation details. All steps and parameters are preserved, but organized in a more systematic, documentation-style layout.
1. Workflow Overview
This automation uses an n8n workflow template composed of five core nodes:
- Typeform Trigger – Receives new form submissions via webhook.
- Set – Extracts and normalizes key fields from the Typeform payload.
- IF – Evaluates a numeric rating to determine feedback polarity.
- Google Sheets (positive_feedback) – Appends positive responses to a specific sheet.
- Google Sheets (negative_feedback) – Appends negative responses to a separate sheet.
The result is a fully automated pipeline that:
- Captures all Typeform responses in real time.
- Segments feedback based on a rating threshold.
- Stores positive and negative feedback in separate, structured Google Sheets.
- Provides a base for further automations, such as alerts or follow-up actions.
2. Architecture & Data Flow
2.1 Logical Flow
- Typeform submits a response to the configured form.
- Typeform Trigger node in n8n receives the webhook payload.
- Set node reads the incoming JSON, extracts the rating and free-text opinion, and outputs a minimal, normalized object.
- IF node evaluates the numeric rating against a predefined threshold (e.g. rating ≥ 3 is considered positive).
- If the condition is true, the item flows to the positive Google Sheets node, which appends a row to the
positive_feedbacksheet. - If the condition is false, the item flows to the negative Google Sheets node, which appends a row to the
negative_feedbacksheet.
2.2 Core Use Cases
- Automated segmentation of course feedback by sentiment or satisfaction score.
- Continuous, timestamped logging of feedback in Sheets for reporting and analysis.
- Triggering downstream workflows for negative feedback (support alerts, tickets, follow-up emails).
3. Node-by-Node Breakdown
3.1 Typeform Trigger Node
Role: Ingest new Typeform submissions into n8n via webhook.
3.1.1 Essential Configuration
- webhookId:
1234567890(template placeholder) - formId:
yxcvbnm(template placeholder) - Credentials: Typeform credentials configured in n8n (API key or Typeform integration)
In n8n, the Typeform Trigger node typically registers a webhook with Typeform. When a respondent submits the form, Typeform sends an HTTP POST to n8n containing the response payload.
3.1.2 Connectivity & Webhook Activation
- Ensure the webhook is enabled in your Typeform account for the specified
formId. - If n8n is self-hosted, expose your instance via a public URL or tunneling solution so Typeform can reach the webhook endpoint.
- Use a test submission in Typeform to confirm that:
- The webhook is firing correctly.
- n8n receives the payload without errors.
- The payload structure matches what the downstream nodes expect.
3.1.3 Edge Cases
- If no data appears in n8n, check the webhook status in Typeform and verify that the n8n URL is accessible from the internet.
- For form changes (new questions, label changes), re-check the payload structure before adjusting mappings in the Set node.
3.2 Set Node (Capture & Normalize Typeform Data)
Role: Transform the raw Typeform JSON into a compact, normalized object that contains only the fields required for routing and storage.
3.2.1 Template Configuration
The template uses a Set node configured with explicit mappings:
{ "values": { "number": [ { "name": "usefulness", "value": "={{$json[\"How useful was the course?\"]}}" } ], "string": [ { "name": "opinion", "value": "={{$json[\"Your opinion on the course:\"]}}" } ] }, "keepOnlySet": true
}
This configuration:
- Defines a numeric field
usefulnessmapped from the question labeled"How useful was the course?". - Defines a string field
opinionmapped from the question labeled"Your opinion on the course:". - Enables
keepOnlySetto remove all other properties from the incoming JSON, leaving only the normalized fields.
3.2.2 Label vs Key-Based Mapping
- Using the text labels (as in the example) is convenient but sensitive to label changes in Typeform.
- For more stable workflows, you can map using the underlying response keys from the raw payload instead of the human-readable labels.
3.2.3 Practical Notes
- Ensure the Typeform question labels in the expressions match exactly, including punctuation and capitalization.
- If the rating is delivered as a string, the IF node will still work if n8n can coerce it to a number, but for safety you can cast explicitly in the expression if needed.
keepOnlySet: trueis recommended for clarity and performance, especially when you only need a small subset of the payload.
3.3 IF Node (Feedback Segmentation)
Role: Route feedback to different branches based on the numeric rating.
3.3.1 Template Condition
The IF node checks the usefulness value created by the Set node:
{ "conditions": { "number": [ { "value1": "={{$json[\"usefulness\"]}}", "operation": "largerEqual", "value2": 3 } ] }
}
Behavior:
- If
usefulness ≥ 3, the item is routed to the true branch (index 0), considered positive feedback. - If
usefulness < 3or not provided (and cannot be parsed), the item goes to the false branch (index 1), treated as negative or non-positive feedback.
3.3.2 Threshold Selection
- The example uses
3as the cutoff for a typical 1-5 scale. - For stricter segmentation, many teams prefer
≥ 4as the threshold for positive feedback. - Adjust the
value2parameter to match your rating policy.
3.3.3 Edge Cases & Data Types
- If the rating is missing or not a valid number, the condition may fail or behave unexpectedly. Inspect the raw payload if routing does not match your expectations.
- To avoid type issues, you can ensure the value is numeric in the Set node (for example, by using an expression that parses the value) before it reaches the IF node.
3.4 Google Sheets Nodes (Append Positive & Negative Feedback)
Role: Persist feedback into two separate Google Sheets ranges for later analysis and reporting.
3.4.1 Positive Feedback Node
Template configuration for the positive branch:
- Operation:
append - Range:
positive_feedback!A:C - sheetId:
asdfghjklöä(placeholder, replace with your actual sheet ID) - Authentication:
oAuth2
This node appends a new row to the positive_feedback sheet in the specified Google Spreadsheet for each item that passes the IF condition.
3.4.2 Negative Feedback Node
Template configuration for the negative branch:
- Operation:
append - Range:
negative_feedback!A:C - sheetId:
qwertzuiop(placeholder, replace with your actual sheet ID) - Authentication: Typically the same OAuth2 credential as the positive node
This node appends rows to the negative_feedback sheet whenever the rating does not meet the positive threshold.
3.4.3 Sheet Structure & Headers
- Create descriptive header rows in both sheets (e.g.
Timestamp,Usefulness,Opinion,Submission ID). - Enable keyRow in the Google Sheets node if you want to reference columns by name in n8n.
- Ensure that the
range(e.g.A:C) covers all columns you intend to populate.
3.4.4 Credentials & Access
- Use a dedicated OAuth2 credential or service account to limit access and make the integration easier to maintain.
- Verify that the configured account has write access to the target spreadsheet.
3.4.5 Failure Modes
- Incorrect
sheetIdor sheet name will cause append operations to fail. - If the OAuth token is expired or revoked, n8n will return authentication errors until reauthorized.
- Mismatched ranges (e.g. fewer columns than provided data) can lead to unexpected alignments in the sheet.
4. Configuration Notes & Best Practices
4.1 Mapping Fields From Typeform
- Always check the raw webhook payload from Typeform when you first configure the workflow.
- Use stable identifiers (question IDs or keys) where possible to reduce breakage when labels change.
- Document which Typeform questions map to which n8n fields, especially for multi-question forms.
4.2 Avoiding Duplicates and Ensuring Auditability
- Store a unique submission identifier (if available in the payload) in your sheets.
- Include timestamps so you can track when each response was received and processed.
- These fields make it easier to detect duplicates and perform historical analysis.
4.3 Security & Privacy Considerations
- Only capture and persist fields that are strictly necessary for your analysis or follow-up.
- Avoid storing sensitive personal data in Google Sheets unless you have a clear policy and safeguards.
- Use OAuth2 with the minimal required scopes for Google Sheets access.
- Secure your n8n instance with HTTPS, strong credentials, and IP allowlists where possible.
5. Enhancements & Real-World Improvements
5.1 Add Timestamps and Responder Metadata
To provide context for each row in Google Sheets, you can extend the Set node to include metadata from the Typeform payload, such as submission time.
Example expression for a timestamp field:
timestamp: ={{$json["submitted_at"] || new Date().toISOString()}}
This expression attempts to use the submitted_at field from Typeform and falls back to the current time if it is not present.
5.2 Sanitize and Validate Input
Before writing to Google Sheets, you can introduce additional nodes to clean and validate data:
- Function node to:
- Trim whitespace from text responses.
- Remove or escape HTML if present.
- Limit text length for very long comments.
- IF nodes to:
- Skip rows that lack required fields.
- Handle invalid or out-of-range ratings.
5.3 Automatic Follow-Up Actions for Negative Feedback
For responses routed to the negative branch (rating below the threshold), you can extend the workflow with additional nodes, such as:
- Slack node to send an immediate alert to a support or course team channel.
- Helpdesk integration node (e.g. Zendesk, Freshdesk) to create a support ticket.
- Email node to send a personalized follow-up or apology email, optionally including a link to a more detailed feedback form.
These actions can be chained after the negative Google Sheets node or in parallel, depending on your process.
5.4 Error Handling & Retries
Google Sheets API calls may occasionally fail due to rate limits or transient network issues. To handle this robustly:
- Use n8n’s built-in retry options where available on the Sheets nodes.
- Alternatively, implement a retry pattern by:
- Wrapping the Sheets node in a sub-workflow or using additional nodes to:
- On failure, wait for X seconds and retry up to N times.
- For permanent failures, log the problematic payloads to:
- A dedicated “errors” sheet, or
- An external error tracking or logging service.
6. Troubleshooting Reference
6.1 No Incoming Data in n8n
- Verify that the Typeform webhook is enabled and associated with the correct
formId. - Check that the public URL of your n8n instance is reachable from the internet.
- Send a test submission from Typeform and inspect the execution logs in n8n.
6.2 Missing or Empty Field Values
- Compare the question labels used in the Set node with the actual labels in Typeform.
- Inspect the raw JSON payload from the Typeform Trigger node to identify the exact keys.
- Update the Set node expressions if labels or structure have changed.
6.3 Google Sheets Append Errors
- Confirm that the
sheetIdmatches the target spreadsheet. - Ensure that the specified
range(e.g.positive_feedback!A:C) exists and that the sheet name is correct. - Check that
