Skip to content

Commit 4b5c2b4

Browse files
aadamgoughwaleedlatif1icecrasher321greptile-apps[bot]Adam Gough
authored
feat(google-forms): added google forms block (#1343)
* fix(sidebar): draggable cursor on sidebar when switching workflows (#1276) * added google form tool to read forms * added trigger mode and block docs * updated docs * removed file * reverted diff * greptile comments * Reverted bun file * remove outdated code for old webhook modal * restore ui changes to webhooks * removed provider specific logic * fix lint --------- Co-authored-by: Waleed Latif <walif6@gmail.com> Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai> Co-authored-by: Adam Gough <adamgough@Mac.attlocal.net> Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
1 parent bd402cd commit 4b5c2b4

File tree

22 files changed

+826
-90
lines changed

22 files changed

+826
-90
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
title: Google Forms
3+
description: Read responses from a Google Form
4+
---
5+
6+
import { BlockInfoCard } from "@/components/ui/block-info-card"
7+
8+
<BlockInfoCard
9+
type="google_forms"
10+
color="#E0E0E0"
11+
icon={true}
12+
iconSvg={`<svg className="block-icon" xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 65' fill='none'>
13+
<path
14+
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'
15+
fill='#673AB7'
16+
/>
17+
<path
18+
d='M29.583 0v10.354c0 2.45 1.986 4.438 4.438 4.438h13.312L36.979 10.354 29.583 0Z'
19+
fill='#B39DDB'
20+
/>
21+
<path
22+
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'
23+
fill='#F1F1F1'
24+
/>
25+
<defs>
26+
<linearGradient
27+
id='gf-gradient'
28+
x1='30.881'
29+
y1='16.452'
30+
x2='47.333'
31+
y2='32.9'
32+
gradientUnits='userSpaceOnUse'
33+
>
34+
<stop stopColor='#9575CD' />
35+
<stop offset='1' stopColor='#7E57C2' />
36+
</linearGradient>
37+
</defs>
38+
</svg>`}
39+
/>
40+
41+
{/* MANUAL-CONTENT-START:intro */}
42+
[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.
43+
44+
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.
45+
46+
With Google Forms, you can:
47+
48+
- **Create surveys and forms**: Design custom forms for feedback, registration, quizzes, and more
49+
- **Collect responses automatically**: Gather data from users in real-time
50+
- **Analyze results**: View responses in Google Forms or export to Google Sheets for further analysis
51+
- **Collaborate easily**: Share forms and work with others to build and review questions
52+
- **Integrate with other Google services**: Connect with Google Sheets, Drive, and more
53+
54+
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.
55+
{/* MANUAL-CONTENT-END */}
56+
57+
## Usage Instructions
58+
59+
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.
60+
61+
62+
63+
## Tools
64+
65+
### `google_forms_get_responses`
66+
67+
#### Input
68+
69+
| Parameter | Type | Required | Description |
70+
| --------- | ---- | -------- | ----------- |
71+
| formId | string | Yes | The ID of the Google Form |
72+
| responseId | string | No | If provided, returns this specific response |
73+
| pageSize | number | No | Max responses to return (service may return fewer). Defaults to 5000 |
74+
75+
#### Output
76+
77+
| Parameter | Type | Description |
78+
| --------- | ---- | ----------- |
79+
| `data` | json | Response or list of responses |
80+
81+
82+
83+
## Notes
84+
85+
- Category: `tools`
86+
- Type: `google_forms`

apps/sim/app/api/webhooks/trigger/[path]/route.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,37 @@ export async function POST(
201201
}
202202
}
203203

204+
// Handle Google Forms shared-secret authentication (Apps Script forwarder)
205+
if (foundWebhook.provider === 'google_forms') {
206+
const providerConfig = (foundWebhook.providerConfig as Record<string, any>) || {}
207+
const expectedToken = providerConfig.token as string | undefined
208+
const secretHeaderName = providerConfig.secretHeaderName as string | undefined
209+
210+
if (expectedToken) {
211+
let isTokenValid = false
212+
213+
if (secretHeaderName) {
214+
const headerValue = request.headers.get(secretHeaderName.toLowerCase())
215+
if (headerValue === expectedToken) {
216+
isTokenValid = true
217+
}
218+
} else {
219+
const authHeader = request.headers.get('authorization')
220+
if (authHeader?.toLowerCase().startsWith('bearer ')) {
221+
const token = authHeader.substring(7)
222+
if (token === expectedToken) {
223+
isTokenValid = true
224+
}
225+
}
226+
}
227+
228+
if (!isTokenValid) {
229+
logger.warn(`[${requestId}] Google Forms webhook authentication failed for path: ${path}`)
230+
return new NextResponse('Unauthorized - Invalid secret', { status: 401 })
231+
}
232+
}
233+
}
234+
204235
// Handle generic webhook authentication if enabled
205236
if (foundWebhook.provider === 'generic') {
206237
const providerConfig = (foundWebhook.providerConfig as Record<string, any>) || {}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/chat-deploy/components/auth-selector.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ export function AuthSelector({
144144
className={cn(
145145
'group h-7 w-7 rounded-md p-0',
146146
'text-muted-foreground/60 transition-all duration-200',
147-
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
148-
'active:scale-95',
147+
'hover:bg-muted/50 hover:text-foreground',
149148
'disabled:cursor-not-allowed disabled:opacity-50',
150149
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
151150
)}
@@ -162,16 +161,15 @@ export function AuthSelector({
162161
className={cn(
163162
'group h-7 w-7 rounded-md p-0',
164163
'text-muted-foreground/60 transition-all duration-200',
165-
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
166-
'active:scale-95',
164+
'hover:bg-muted/50 hover:text-foreground',
167165
'disabled:cursor-not-allowed disabled:opacity-30',
168166
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
169167
)}
170168
>
171169
{copySuccess ? (
172170
<Check className='h-3.5 w-3.5 text-foreground' />
173171
) : (
174-
<Copy className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
172+
<Copy className='h-3.5 w-3.5 ' />
175173
)}
176174
<span className='sr-only'>Copy password</span>
177175
</Button>
@@ -184,15 +182,14 @@ export function AuthSelector({
184182
className={cn(
185183
'group h-7 w-7 rounded-md p-0',
186184
'text-muted-foreground/60 transition-all duration-200',
187-
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
188-
'active:scale-95',
185+
'hover:bg-muted/50 hover:text-foreground',
189186
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
190187
)}
191188
>
192189
{showPassword ? (
193-
<EyeOff className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
190+
<EyeOff className='h-3.5 w-3.5 ' />
194191
) : (
195-
<Eye className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
192+
<Eye className='h-3.5 w-3.5 ' />
196193
)}
197194
<span className='sr-only'>
198195
{showPassword ? 'Hide password' : 'Show password'}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/webhook-settings/webhook-settings.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
605605
{copySuccess[webhook.id] ? (
606606
<Check className='h-3.5 w-3.5 text-foreground' />
607607
) : (
608-
<Copy className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
608+
<Copy className='h-3.5 w-3.5' />
609609
)}
610610
<span className='sr-only'>Copy webhook URL</span>
611611
</Button>
@@ -643,7 +643,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
643643
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
644644
)}
645645
>
646-
<Play className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
646+
<Play className='h-3.5 w-3.5' />
647647
<span className='sr-only'>Test webhook</span>
648648
</Button>
649649
</TooltipTrigger>
@@ -665,7 +665,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
665665
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
666666
)}
667667
>
668-
<Pencil className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
668+
<Pencil className='h-3.5 w-3.5' />
669669
<span className='sr-only'>Edit webhook</span>
670670
</Button>
671671
</TooltipTrigger>
@@ -687,7 +687,7 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
687687
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
688688
)}
689689
>
690-
<Trash2 className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
690+
<Trash2 className='h-3.5 w-3.5' />
691691
<span className='sr-only'>Delete webhook</span>
692692
</Button>
693693
</TooltipTrigger>
@@ -874,16 +874,15 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
874874
className={cn(
875875
'group h-7 w-7 rounded-md p-0',
876876
'text-muted-foreground/60 transition-all duration-200',
877-
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
878-
'active:scale-95',
877+
'hover:bg-muted/50 hover:text-foreground',
879878
'disabled:cursor-not-allowed disabled:opacity-30',
880879
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
881880
)}
882881
>
883882
{copySuccess.form ? (
884883
<Check className='h-3.5 w-3.5 text-foreground' />
885884
) : (
886-
<Copy className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
885+
<Copy className='h-3.5 w-3.5' />
887886
)}
888887
<span className='sr-only'>Copy secret</span>
889888
</Button>
@@ -901,16 +900,15 @@ export function WebhookSettings({ workflowId, open, onOpenChange }: WebhookSetti
901900
className={cn(
902901
'group h-7 w-7 rounded-md p-0',
903902
'text-muted-foreground/60 transition-all duration-200',
904-
'hover:scale-105 hover:bg-muted/50 hover:text-foreground',
905-
'active:scale-95',
903+
'hover:bg-muted/50 hover:text-foreground',
906904
'focus-visible:ring-2 focus-visible:ring-muted-foreground/20 focus-visible:ring-offset-1'
907905
)}
908906
onClick={() => setShowSecret(!showSecret)}
909907
>
910908
{showSecret ? (
911-
<EyeOff className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
909+
<EyeOff className='h-3.5 w-3.5' />
912910
) : (
913-
<Eye className='h-3.5 w-3.5 transition-transform duration-200 group-hover:scale-110' />
911+
<Eye className='h-3.5 w-3.5' />
914912
)}
915913
<span className='sr-only'>
916914
{showSecret ? 'Hide secret' : 'Show secret'}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/short-input.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ export function ShortInput({
366366
<Input
367367
ref={inputRef}
368368
className={cn(
369-
'allow-scroll w-full overflow-auto text-transparent caret-foreground placeholder:text-muted-foreground/50',
369+
'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',
370370
isConnecting &&
371371
config?.connectionDroppable !== false &&
372372
'ring-2 ring-blue-500 ring-offset-2 focus-visible:ring-blue-500'
@@ -403,13 +403,13 @@ export function ShortInput({
403403
onWheel={handleWheel}
404404
onKeyDown={handleKeyDown}
405405
autoComplete='off'
406-
style={{ overflowX: 'auto' }}
406+
style={{ overflowX: 'auto', scrollbarWidth: 'none', msOverflowStyle: 'none' }}
407407
disabled={disabled}
408408
/>
409409
<div
410410
ref={overlayRef}
411-
className='pointer-events-none absolute inset-0 flex items-center overflow-x-auto bg-transparent px-3 text-sm'
412-
style={{ overflowX: 'auto' }}
411+
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'
412+
style={{ overflowX: 'auto', scrollbarWidth: 'none', msOverflowStyle: 'none' }}
413413
>
414414
<div
415415
className='w-full whitespace-pre'

0 commit comments

Comments
 (0)