Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
aeef2b7
v0.3.19: openai oss models, invite & search modal fixes
waleedlatif1 Aug 5, 2025
9f2ff7e
Merge pull request #883 from simstudioai/staging
icecrasher321 Aug 5, 2025
85cdca2
v0.3.21: gpt-5, copilot files, configurable rate limits, fix deployed…
waleedlatif1 Aug 7, 2025
aedf5e7
v0.3.22: handle files, trigger mode, email validation, tag dropdown t…
waleedlatif1 Aug 9, 2025
1c818b2
v0.3.23: multiplayer variables, api key fixes, kb improvements, trigg…
icecrasher321 Aug 12, 2025
8fccd5c
Merge pull request #948 from simstudioai/staging
icecrasher321 Aug 12, 2025
f7573fa
v0.3.24: api block fixes
waleedlatif1 Aug 13, 2025
4107948
Merge pull request #954 from simstudioai/staging
waleedlatif1 Aug 13, 2025
56ffb53
Merge pull request #964 from simstudioai/staging
icecrasher321 Aug 14, 2025
e1f04f4
v0.3.26: fix billing, bubble up workflow block errors, credentials se…
icecrasher321 Aug 14, 2025
6133db5
v0.3.27: oauth/webhook fixes, whitelabel fixes, code cleanups
icecrasher321 Aug 15, 2025
a0cf003
Merge pull request #986 from simstudioai/staging
icecrasher321 Aug 15, 2025
97b6bcc
v0.3.28: autolayout, export, copilot, kb ui improvements
waleedlatif1 Aug 16, 2025
570c07b
Merge pull request #1004 from simstudioai/staging
icecrasher321 Aug 18, 2025
af60ccd
fix: migration mem issues bypass
icecrasher321 Aug 18, 2025
3873f44
Merge pull request #1007 from simstudioai/staging
icecrasher321 Aug 18, 2025
5c56cbd
Merge pull request #1008 from simstudioai/staging
icecrasher321 Aug 18, 2025
60a9a25
Merge pull request #1009 from simstudioai/staging
icecrasher321 Aug 18, 2025
d75cc1e
v0.3.30: duplication, control bar fixes
waleedlatif1 Aug 18, 2025
1619d63
v0.3.31: webhook fixes, advanced mode parameter filtering, credential…
waleedlatif1 Aug 19, 2025
6b185be
v0.3.32: loop block max increase, url-encoded API calls, subflow logs…
waleedlatif1 Aug 20, 2025
5d74db5
v0.3.33: update copilot docs
icecrasher321 Aug 20, 2025
2c47cf4
v0.3.34: azure-openai options, billing fixes, mistral OCR via Azure, …
waleedlatif1 Aug 21, 2025
cd1bd95
fix(nextjs): downgrade nextjs due to known issue with bun commonjs mo…
waleedlatif1 Aug 21, 2025
abad362
fix(build): clear docker build cache to use correct Next.js version
waleedlatif1 Aug 21, 2025
e107363
v0.3.35: migrations, custom email address support
waleedlatif1 Aug 21, 2025
991f044
v0.3.36: workflow block logs, whitelabeling configurability, session …
waleedlatif1 Aug 22, 2025
4846f6c
v0.3.37: azure OCR api key, wand SSE, CRON helm
waleedlatif1 Aug 22, 2025
fdfa935
v0.3.38: billing cron job fix
icecrasher321 Aug 23, 2025
ed9b9ad
v0.3.39: billing fixes, custom tools fixes, copilot client-side migra…
waleedlatif1 Aug 24, 2025
fd6d927
v0.3.40: copilot improvements, knowledgebase improvements, security i…
waleedlatif1 Aug 29, 2025
8739a3d
fix(ssl): add envvar for optional ssl cert (#1179)
waleedlatif1 Aug 29, 2025
9213202
fix(db): accept self-signed certs (#1181)
waleedlatif1 Aug 29, 2025
921c755
v0.3.40: drizzle fixes, custom postgres port support
waleedlatif1 Aug 29, 2025
7ac89e3
revert(dep-changes): revert drizzle-orm version and change CI yaml sc…
icecrasher321 Aug 29, 2025
316c970
Merge pull request #1189 from simstudioai/staging
icecrasher321 Aug 29, 2025
76fac13
v0.3.41: wand with azure openai, generic mysql and postgres blocks
waleedlatif1 Aug 30, 2025
0bc7781
v0.3.42: kb config defaults, downgrade nextjs
waleedlatif1 Aug 30, 2025
ee17cf4
v0.3.43: added additional parsers, mysql block improvements, billing …
waleedlatif1 Aug 31, 2025
0cf87e6
v0.3.44: removing unused routes, whitelabeling terms & policy URLs, e…
waleedlatif1 Sep 3, 2025
581929b
v0.3.45: fixes for organization invites, custom tool execution
waleedlatif1 Sep 3, 2025
fce1423
v0.3.46: fix copilot stats updates
Sg312 Sep 3, 2025
60a061e
v0.3.47: race condition fixes, store rehydration consolidation, other…
waleedlatif1 Sep 5, 2025
bd6d4a9
0.3.48: revert trigger dev bypass for enterprise users
icecrasher321 Sep 5, 2025
a0bb754
0.3.49: readme updates, router block and variables improvements
waleedlatif1 Sep 5, 2025
d45324b
fix(sidebar): draggable cursor on sidebar when switching workflows (#…
waleedlatif1 Sep 7, 2025
784992f
v0.3.50: debounce moved server side, hasWorkflowChanged fixes, advanc…
icecrasher321 Sep 8, 2025
ea8762e
v0.3.51: mcp support, copilot improvements, polling for live executio…
waleedlatif1 Sep 10, 2025
1ad31c9
v0.3.52: docs updates, deployment version tables, workspace-level api…
icecrasher321 Sep 12, 2025
a06ae0d
v0.3.53: logs search, idempotency for webhooks, billing fixes for ove…
waleedlatif1 Sep 16, 2025
9cbc51f
added google form tool to read forms
Sep 16, 2025
03d3883
added trigger mode and block docs
Sep 16, 2025
47800ae
updated docs
Sep 16, 2025
bc141b6
removed file
Sep 16, 2025
41f8152
reverted diff
Sep 16, 2025
e12f81c
greptile comments
Sep 16, 2025
7201e65
Reverted bun file
Sep 17, 2025
ebbd883
remove outdated code for old webhook modal
waleedlatif1 Sep 17, 2025
43423d9
restore ui changes to webhooks
waleedlatif1 Sep 17, 2025
73332ca
removed provider specific logic
Sep 17, 2025
5839ae2
Merge branch 'staging' into feat/google-forms
icecrasher321 Sep 17, 2025
146e547
fix lint
icecrasher321 Sep 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions apps/docs/content/docs/en/tools/google_forms.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: Google Forms
description: Read responses from a Google Form
---

import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
type="google_forms"
color="#E0E0E0"
icon={true}
iconSvg={`<svg className="block-icon" xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 65' fill='none'>
<path
d='M29.583 0H4.438C1.997 0 0 1.997 0 4.438v56.208C0 63.086 1.997 65.083 4.438 65.083h38.458c2.44 0 4.437-1.997 4.437-4.437V17.75L36.979 10.354 29.583 0Z'
fill='#673AB7'
/>
<path
d='M29.583 0v10.354c0 2.45 1.986 4.438 4.438 4.438h13.312L36.979 10.354 29.583 0Z'
fill='#B39DDB'
/>
<path
d='M19.229 50.292h16.271v-2.959H19.229v2.959Zm0-17.75v2.958h16.271v-2.958H19.229Zm-3.698 1.479c0 1.224-0.995 2.219-2.219 2.219s-2.219-0.995-2.219-2.219c0-1.224 0.995-2.219 2.219-2.219s2.219 0.995 2.219 2.219Zm0 7.396c0 1.224-0.995 2.219-2.219 2.219s-2.219-0.995-2.219-2.219c0-1.224 0.995-2.219 2.219-2.219s2.219 0.995 2.219 2.219Zm0 7.396c0 1.224-0.995 2.219-2.219 2.219s-2.219-0.995-2.219-2.219c0-1.224 0.995-2.219 2.219-2.219s2.219 0.995 2.219 2.219Zm3.698-5.917h16.271v-2.959H19.229v2.959Z'
fill='#F1F1F1'
/>
<defs>
<linearGradient
id='gf-gradient'
x1='30.881'
y1='16.452'
x2='47.333'
y2='32.9'
gradientUnits='userSpaceOnUse'
>
<stop stopColor='#9575CD' />
<stop offset='1' stopColor='#7E57C2' />
</linearGradient>
</defs>
</svg>`}
/>

{/* MANUAL-CONTENT-START:intro */}
[Google Forms](https://forms.google.com) is Google's online survey and form tool that allows users to create forms, collect responses, and analyze results. As part of Google's productivity suite, Google Forms makes it easy to gather information, feedback, and data from users.

Learn how to integrate the Google Forms tool in Sim to automatically read and process form responses in your workflows. This tutorial walks you through connecting Google Forms, retrieving responses, and using collected data to power automation. Perfect for syncing survey results, registrations, or feedback with your agents in real-time.

With Google Forms, you can:

- **Create surveys and forms**: Design custom forms for feedback, registration, quizzes, and more
- **Collect responses automatically**: Gather data from users in real-time
- **Analyze results**: View responses in Google Forms or export to Google Sheets for further analysis
- **Collaborate easily**: Share forms and work with others to build and review questions
- **Integrate with other Google services**: Connect with Google Sheets, Drive, and more

In Sim, the Google Forms integration enables your agents to programmatically access form responses. This allows for powerful automation scenarios such as processing survey data, triggering workflows based on new submissions, and syncing form results with other tools. Your agents can fetch all responses for a form, retrieve a specific response, and use the data to drive intelligent automation. By connecting Sim with Google Forms, you can automate data collection, streamline feedback processing, and incorporate form responses into your agent's capabilities.
{/* MANUAL-CONTENT-END */}

## Usage Instructions

Integrate Google Forms into your workflow. Provide a Form ID to list responses, or specify a Response ID to fetch a single response. Requires OAuth.



## Tools

### `google_forms_get_responses`

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| formId | string | Yes | The ID of the Google Form |
| responseId | string | No | If provided, returns this specific response |
| pageSize | number | No | Max responses to return (service may return fewer). Defaults to 5000 |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `data` | json | Response or list of responses |



## Notes

- Category: `tools`
- Type: `google_forms`
31 changes: 31 additions & 0 deletions apps/sim/app/api/webhooks/trigger/[path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,37 @@ export async function POST(
}
}

// Handle Google Forms shared-secret authentication (Apps Script forwarder)
if (foundWebhook.provider === 'google_forms') {
const providerConfig = (foundWebhook.providerConfig as Record<string, any>) || {}
const expectedToken = providerConfig.token as string | undefined
const secretHeaderName = providerConfig.secretHeaderName as string | undefined

if (expectedToken) {
let isTokenValid = false

if (secretHeaderName) {
const headerValue = request.headers.get(secretHeaderName.toLowerCase())
if (headerValue === expectedToken) {
isTokenValid = true
}
} else {
const authHeader = request.headers.get('authorization')
if (authHeader?.toLowerCase().startsWith('bearer ')) {
const token = authHeader.substring(7)
if (token === expectedToken) {
isTokenValid = true
}
}
}

if (!isTokenValid) {
logger.warn(`[${requestId}] Google Forms webhook authentication failed for path: ${path}`)
return new NextResponse('Unauthorized - Invalid secret', { status: 401 })
}
}
}

// Handle generic webhook authentication if enabled
if (foundWebhook.provider === 'generic') {
const providerConfig = (foundWebhook.providerConfig as Record<string, any>) || {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ export function AuthSelector({
className={cn(
'group h-7 w-7 rounded-md p-0',
'text-muted-foreground/60 transition-all duration-200',
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
'active:scale-95',
'hover:bg-muted/50 hover:text-foreground',
'disabled:cursor-not-allowed disabled:opacity-50',
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
Expand All @@ -162,16 +161,15 @@ export function AuthSelector({
className={cn(
'group h-7 w-7 rounded-md p-0',
'text-muted-foreground/60 transition-all duration-200',
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
'active:scale-95',
'hover:bg-muted/50 hover:text-foreground',
'disabled:cursor-not-allowed disabled:opacity-30',
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
>
{copySuccess ? (
<Check className='h-3.5 w-3.5 text-foreground' />
) : (
<Copy className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Copy className='h-3.5 w-3.5 ' />
)}
<span className='sr-only'>Copy password</span>
</Button>
Expand All @@ -184,15 +182,14 @@ export function AuthSelector({
className={cn(
'group h-7 w-7 rounded-md p-0',
'text-muted-foreground/60 transition-all duration-200',
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
'active:scale-95',
'hover:bg-muted/50 hover:text-foreground',
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
>
{showPassword ? (
<EyeOff className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<EyeOff className='h-3.5 w-3.5 ' />
) : (
<Eye className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Eye className='h-3.5 w-3.5 ' />
)}
<span className='sr-only'>
{showPassword ? 'Hide password' : 'Show password'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
{copySuccess[webhook.id] ? (
<Check className='h-3.5 w-3.5 text-foreground' />
) : (
<Copy className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Copy className='h-3.5 w-3.5' />
)}
<span className='sr-only'>Copy webhook URL</span>
</Button>
Expand Down Expand Up @@ -643,7 +643,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
>
<Play className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Play className='h-3.5 w-3.5' />
<span className='sr-only'>Test webhook</span>
</Button>
</TooltipTrigger>
Expand All @@ -665,7 +665,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
>
<Pencil className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Pencil className='h-3.5 w-3.5' />
<span className='sr-only'>Edit webhook</span>
</Button>
</TooltipTrigger>
Expand All @@ -687,7 +687,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
>
<Trash2 className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Trash2 className='h-3.5 w-3.5' />
<span className='sr-only'>Delete webhook</span>
</Button>
</TooltipTrigger>
Expand Down Expand Up @@ -874,16 +874,15 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
className={cn(
'group h-7 w-7 rounded-md p-0',
'text-muted-foreground/60 transition-all duration-200',
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
'active:scale-95',
'hover:bg-muted/50 hover:text-foreground',
'disabled:cursor-not-allowed disabled:opacity-30',
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
>
{copySuccess.form ? (
<Check className='h-3.5 w-3.5 text-foreground' />
) : (
<Copy className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Copy className='h-3.5 w-3.5' />
)}
<span className='sr-only'>Copy secret</span>
</Button>
Expand All @@ -901,16 +900,15 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
className={cn(
'group h-7 w-7 rounded-md p-0',
'text-muted-foreground/60 transition-all duration-200',
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
'active:scale-95',
'hover:bg-muted/50 hover:text-foreground',
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
)}
onClick={() => setShowSecret(!showSecret)}
>
{showSecret ? (
<EyeOff className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<EyeOff className='h-3.5 w-3.5' />
) : (
<Eye className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
<Eye className='h-3.5 w-3.5' />
)}
<span className='sr-only'>
{showSecret ? 'Hide secret' : 'Show secret'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export function ShortInput({
<Input
ref={inputRef}
className={cn(
'allow-scroll w-full overflow-auto text-transparent caret-foreground placeholder:text-muted-foreground/50',
'allow-scroll w-full overflow-auto text-transparent caret-foreground [-ms-overflow-style:none] [scrollbar-width:none] placeholder:text-muted-foreground/50 [&::-webkit-scrollbar]:hidden',
isConnecting &&
config?.connectionDroppable !== false &&
'ring-2 ring-blue-500 ring-offset-2 focus-visible:ring-blue-500'
Expand Down Expand Up @@ -403,13 +403,13 @@ export function ShortInput({
onWheel={handleWheel}
onKeyDown={handleKeyDown}
autoComplete='off'
style={{ overflowX: 'auto' }}
style={{ overflowX: 'auto', scrollbarWidth: 'none', msOverflowStyle: 'none' }}
disabled={disabled}
/>
<div
ref={overlayRef}
className='pointer-events-none absolute inset-0 flex items-center overflow-x-auto bg-transparent px-3 text-sm'
style={{ overflowX: 'auto' }}
className='pointer-events-none absolute inset-0 flex items-center overflow-x-auto bg-transparent px-3 text-sm [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden'
style={{ overflowX: 'auto', scrollbarWidth: 'none', msOverflowStyle: 'none' }}
>
<div
className='w-full whitespace-pre'
Expand Down
Loading
Loading