Skip to content

Commit 637cff1

Browse files
committed
feat(google): add Maps Pollen/Solar, expand Custom Search, fix Ads/Groups/Contacts/Slides
New capability: - Google Maps: add Pollen Forecast and Solar Potential tools (API-key, google_cloud BYOK) - Google Custom Search: add start/dateRestrict/fileType/safe/searchType/siteSearch/ siteSearchFilter/lr/gl/sort params, htmlTitle/htmlSnippet/formattedUrl/mime/fileFormat/ cacheId/image result fields, and nextPageStartIndex pagination Fixes (validated against live API docs): - Google Ads: bump all tools from sunset v19 to v24 - Google Groups: forward OAuth credential under oauthCredential (was dropping token in 11 ops), forward all update_settings fields, JSON.stringify update_settings/add_alias bodies - Google Contacts: include required metadata.sources[].etag in updateContact body (fixed 400) - Google Slides: remove unsupported GIF thumbnail mimeType (API only allows PNG) - Google Sheets: wire delete_rows/delete_sheet/delete_spreadsheet into the V2 block - Google Custom Search: throw on API error responses instead of returning empty success; num optional + Number-coerced; pagemap typed unknown
1 parent 9e9f2b9 commit 637cff1

22 files changed

Lines changed: 1051 additions & 50 deletions

apps/sim/blocks/blocks/google.ts

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,88 @@ Return ONLY the search query - no explanations, no quotes around the whole thing
6161
id: 'num',
6262
title: 'Number of Results',
6363
type: 'short-input',
64-
placeholder: '10',
65-
required: true,
64+
placeholder: '10 (1-10)',
65+
mode: 'advanced',
66+
},
67+
{
68+
id: 'start',
69+
title: 'Start Index',
70+
type: 'short-input',
71+
placeholder: '1 (for pagination; start + num <= 100)',
72+
mode: 'advanced',
73+
},
74+
{
75+
id: 'searchType',
76+
title: 'Search Type',
77+
type: 'dropdown',
78+
options: [
79+
{ label: 'Web', id: '' },
80+
{ label: 'Image', id: 'image' },
81+
],
82+
mode: 'advanced',
83+
},
84+
{
85+
id: 'dateRestrict',
86+
title: 'Date Restrict',
87+
type: 'short-input',
88+
placeholder: 'e.g., d7, w2, m1, y1',
89+
mode: 'advanced',
90+
},
91+
{
92+
id: 'fileType',
93+
title: 'File Type',
94+
type: 'short-input',
95+
placeholder: 'e.g., pdf, doc',
96+
mode: 'advanced',
97+
},
98+
{
99+
id: 'safe',
100+
title: 'SafeSearch',
101+
type: 'dropdown',
102+
options: [
103+
{ label: 'Off', id: '' },
104+
{ label: 'Active', id: 'active' },
105+
],
106+
mode: 'advanced',
107+
},
108+
{
109+
id: 'siteSearch',
110+
title: 'Site Search',
111+
type: 'short-input',
112+
placeholder: 'Domain to include or exclude (e.g., wikipedia.org)',
113+
mode: 'advanced',
114+
},
115+
{
116+
id: 'siteSearchFilter',
117+
title: 'Site Search Filter',
118+
type: 'dropdown',
119+
options: [
120+
{ label: 'Include', id: 'i' },
121+
{ label: 'Exclude', id: 'e' },
122+
],
123+
condition: { field: 'siteSearch', value: '', not: true },
124+
mode: 'advanced',
125+
},
126+
{
127+
id: 'lr',
128+
title: 'Language Restrict',
129+
type: 'short-input',
130+
placeholder: 'e.g., lang_en',
131+
mode: 'advanced',
132+
},
133+
{
134+
id: 'gl',
135+
title: 'Country (geolocation)',
136+
type: 'short-input',
137+
placeholder: 'Two-letter country code (e.g., us)',
138+
mode: 'advanced',
139+
},
140+
{
141+
id: 'sort',
142+
title: 'Sort',
143+
type: 'short-input',
144+
placeholder: 'e.g., date',
145+
mode: 'advanced',
66146
},
67147
],
68148

@@ -74,7 +154,17 @@ Return ONLY the search query - no explanations, no quotes around the whole thing
74154
query: params.query,
75155
apiKey: params.apiKey,
76156
searchEngineId: params.searchEngineId,
77-
num: params.num || undefined,
157+
num: params.num ? Number(params.num) : undefined,
158+
start: params.start ? Number(params.start) : undefined,
159+
dateRestrict: params.dateRestrict || undefined,
160+
fileType: params.fileType || undefined,
161+
safe: params.safe || undefined,
162+
searchType: params.searchType || undefined,
163+
siteSearch: params.siteSearch || undefined,
164+
siteSearchFilter: params.siteSearch ? params.siteSearchFilter || undefined : undefined,
165+
lr: params.lr || undefined,
166+
gl: params.gl || undefined,
167+
sort: params.sort || undefined,
78168
}),
79169
},
80170
},
@@ -83,12 +173,23 @@ Return ONLY the search query - no explanations, no quotes around the whole thing
83173
query: { type: 'string', description: 'Search query terms' },
84174
apiKey: { type: 'string', description: 'Google API key' },
85175
searchEngineId: { type: 'string', description: 'Custom search engine ID' },
86-
num: { type: 'string', description: 'Number of results' },
176+
num: { type: 'string', description: 'Number of results (1-10)' },
177+
start: { type: 'string', description: 'Start index for pagination (1-based)' },
178+
dateRestrict: { type: 'string', description: 'Restrict by recency (d/w/m/y notation)' },
179+
fileType: { type: 'string', description: 'Restrict to a file extension' },
180+
safe: { type: 'string', description: 'SafeSearch level (active/off)' },
181+
searchType: { type: 'string', description: 'Search type (image for image search)' },
182+
siteSearch: { type: 'string', description: 'Site to include or exclude' },
183+
siteSearchFilter: { type: 'string', description: 'Include (i) or exclude (e) the site' },
184+
lr: { type: 'string', description: 'Language restriction (e.g., lang_en)' },
185+
gl: { type: 'string', description: 'Country geolocation code' },
186+
sort: { type: 'string', description: 'Sort expression (e.g., date)' },
87187
},
88188

89189
outputs: {
90190
items: { type: 'json', description: 'Search result items' },
91191
searchInformation: { type: 'json', description: 'Search metadata' },
192+
nextPageStartIndex: { type: 'number', description: 'Start index for the next page of results' },
92193
},
93194
}
94195

apps/sim/blocks/blocks/google_groups.ts

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -337,66 +337,66 @@ Return ONLY the description text - no explanations, no quotes, no extra text.`,
337337
case 'get_group':
338338
case 'delete_group':
339339
return {
340-
credential: oauthCredential,
340+
oauthCredential,
341341
groupKey: rest.groupKey,
342342
}
343343
case 'create_group':
344344
return {
345-
credential: oauthCredential,
345+
oauthCredential,
346346
email: rest.email,
347347
name: rest.name,
348348
description: rest.description,
349349
}
350350
case 'update_group':
351351
return {
352-
credential: oauthCredential,
352+
oauthCredential,
353353
groupKey: rest.groupKey,
354354
name: rest.newName,
355355
email: rest.newEmail,
356356
description: rest.description,
357357
}
358358
case 'list_members':
359359
return {
360-
credential: oauthCredential,
360+
oauthCredential,
361361
groupKey: rest.groupKey,
362362
maxResults: rest.maxResults ? Number(rest.maxResults) : undefined,
363363
roles: rest.roles,
364364
}
365365
case 'get_member':
366366
case 'remove_member':
367367
return {
368-
credential: oauthCredential,
368+
oauthCredential,
369369
groupKey: rest.groupKey,
370370
memberKey: rest.memberKey,
371371
}
372372
case 'add_member':
373373
return {
374-
credential: oauthCredential,
374+
oauthCredential,
375375
groupKey: rest.groupKey,
376376
email: rest.memberEmail,
377377
role: rest.role,
378378
}
379379
case 'update_member':
380380
return {
381-
credential: oauthCredential,
381+
oauthCredential,
382382
groupKey: rest.groupKey,
383383
memberKey: rest.memberKey,
384384
role: rest.role,
385385
}
386386
case 'has_member':
387387
return {
388-
credential: oauthCredential,
388+
oauthCredential,
389389
groupKey: rest.groupKey,
390390
memberKey: rest.memberKey,
391391
}
392392
case 'list_aliases':
393393
return {
394-
credential: oauthCredential,
394+
oauthCredential,
395395
groupKey: rest.groupKey,
396396
}
397397
case 'add_alias':
398398
return {
399-
credential: oauthCredential,
399+
oauthCredential,
400400
groupKey: rest.groupKey,
401401
alias: rest.alias,
402402
}
@@ -415,6 +415,38 @@ Return ONLY the description text - no explanations, no quotes, no extra text.`,
415415
return {
416416
oauthCredential,
417417
groupEmail: rest.groupEmail,
418+
name: rest.name,
419+
description: rest.description,
420+
whoCanJoin: rest.whoCanJoin,
421+
whoCanViewMembership: rest.whoCanViewMembership,
422+
whoCanViewGroup: rest.whoCanViewGroup,
423+
whoCanPostMessage: rest.whoCanPostMessage,
424+
allowExternalMembers: rest.allowExternalMembers,
425+
allowWebPosting: rest.allowWebPosting,
426+
primaryLanguage: rest.primaryLanguage,
427+
isArchived: rest.isArchived,
428+
archiveOnly: rest.archiveOnly,
429+
messageModerationLevel: rest.messageModerationLevel,
430+
spamModerationLevel: rest.spamModerationLevel,
431+
replyTo: rest.replyTo,
432+
customReplyTo: rest.customReplyTo,
433+
includeCustomFooter: rest.includeCustomFooter,
434+
customFooterText: rest.customFooterText,
435+
sendMessageDenyNotification: rest.sendMessageDenyNotification,
436+
defaultMessageDenyNotificationText: rest.defaultMessageDenyNotificationText,
437+
membersCanPostAsTheGroup: rest.membersCanPostAsTheGroup,
438+
includeInGlobalAddressList: rest.includeInGlobalAddressList,
439+
whoCanLeaveGroup: rest.whoCanLeaveGroup,
440+
whoCanContactOwner: rest.whoCanContactOwner,
441+
favoriteRepliesOnTop: rest.favoriteRepliesOnTop,
442+
whoCanApproveMembers: rest.whoCanApproveMembers,
443+
whoCanBanUsers: rest.whoCanBanUsers,
444+
whoCanModerateMembers: rest.whoCanModerateMembers,
445+
whoCanModerateContent: rest.whoCanModerateContent,
446+
whoCanAssistContent: rest.whoCanAssistContent,
447+
enableCollaborativeInbox: rest.enableCollaborativeInbox,
448+
whoCanDiscoverGroup: rest.whoCanDiscoverGroup,
449+
defaultSender: rest.defaultSender,
418450
}
419451
default:
420452
return { oauthCredential, ...rest }

apps/sim/blocks/blocks/google_maps.ts

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export const GoogleMapsBlock: BlockConfig = {
3434
{ label: 'Validate Address', id: 'validate_address' },
3535
{ label: 'Geolocate (WiFi/Cell)', id: 'geolocate' },
3636
{ label: 'Air Quality', id: 'air_quality' },
37+
{ label: 'Pollen Forecast', id: 'pollen' },
38+
{ label: 'Solar Potential', id: 'solar' },
3739
],
3840
value: () => 'geocode',
3941
},
@@ -354,23 +356,53 @@ export const GoogleMapsBlock: BlockConfig = {
354356
title: 'Latitude',
355357
type: 'short-input',
356358
placeholder: '37.4224764',
357-
condition: { field: 'operation', value: 'air_quality' },
358-
required: { field: 'operation', value: 'air_quality' },
359+
condition: { field: 'operation', value: ['air_quality', 'pollen', 'solar'] },
360+
required: { field: 'operation', value: ['air_quality', 'pollen', 'solar'] },
359361
},
360362
{
361363
id: 'aqLongitude',
362364
title: 'Longitude',
363365
type: 'short-input',
364366
placeholder: '-122.0842499',
365-
condition: { field: 'operation', value: 'air_quality' },
366-
required: { field: 'operation', value: 'air_quality' },
367+
condition: { field: 'operation', value: ['air_quality', 'pollen', 'solar'] },
368+
required: { field: 'operation', value: ['air_quality', 'pollen', 'solar'] },
367369
},
368370
{
369371
id: 'languageCode',
370372
title: 'Language Code',
371373
type: 'short-input',
372374
placeholder: 'Language code (e.g., en, es)',
373-
condition: { field: 'operation', value: 'air_quality' },
375+
condition: { field: 'operation', value: ['air_quality', 'pollen'] },
376+
mode: 'advanced',
377+
},
378+
379+
{
380+
id: 'days',
381+
title: 'Forecast Days',
382+
type: 'short-input',
383+
placeholder: 'Number of days (1-5, defaults to 1)',
384+
condition: { field: 'operation', value: 'pollen' },
385+
mode: 'advanced',
386+
},
387+
{
388+
id: 'plantsDescription',
389+
title: 'Include Plant Descriptions',
390+
type: 'switch',
391+
condition: { field: 'operation', value: 'pollen' },
392+
mode: 'advanced',
393+
},
394+
395+
{
396+
id: 'requiredQuality',
397+
title: 'Minimum Imagery Quality',
398+
type: 'dropdown',
399+
options: [
400+
{ label: 'Any', id: '' },
401+
{ label: 'High', id: 'HIGH' },
402+
{ label: 'Medium', id: 'MEDIUM' },
403+
{ label: 'Low', id: 'LOW' },
404+
],
405+
condition: { field: 'operation', value: 'solar' },
374406
mode: 'advanced',
375407
},
376408

@@ -401,8 +433,10 @@ export const GoogleMapsBlock: BlockConfig = {
401433
'google_maps_geolocate',
402434
'google_maps_place_details',
403435
'google_maps_places_search',
436+
'google_maps_pollen',
404437
'google_maps_reverse_geocode',
405438
'google_maps_snap_to_roads',
439+
'google_maps_solar',
406440
'google_maps_speed_limits',
407441
'google_maps_timezone',
408442
'google_maps_validate_address',
@@ -503,6 +537,17 @@ export const GoogleMapsBlock: BlockConfig = {
503537
considerIp = params.considerIp === 'true' || params.considerIp === true
504538
}
505539

540+
let days: number | undefined
541+
if (params.days) {
542+
days = Number.parseInt(params.days, 10)
543+
}
544+
545+
let plantsDescription: boolean | undefined
546+
if (params.plantsDescription !== undefined) {
547+
plantsDescription =
548+
params.plantsDescription === 'true' || params.plantsDescription === true
549+
}
550+
506551
return {
507552
...rest,
508553
address,
@@ -519,6 +564,9 @@ export const GoogleMapsBlock: BlockConfig = {
519564
interpolate,
520565
enableUspsCass,
521566
considerIp,
567+
days,
568+
plantsDescription,
569+
requiredQuality: params.requiredQuality || undefined,
522570
type: params.placeType || undefined,
523571
avoid: params.avoid || undefined,
524572
radioType: params.radioType || undefined,
@@ -561,9 +609,12 @@ export const GoogleMapsBlock: BlockConfig = {
561609
carrier: { type: 'string', description: 'Carrier name' },
562610
wifiAccessPoints: { type: 'string', description: 'WiFi access points JSON' },
563611
cellTowers: { type: 'string', description: 'Cell towers JSON' },
564-
aqLatitude: { type: 'string', description: 'Latitude for air quality' },
565-
aqLongitude: { type: 'string', description: 'Longitude for air quality' },
566-
languageCode: { type: 'string', description: 'Language code for air quality' },
612+
aqLatitude: { type: 'string', description: 'Latitude for air quality, pollen, or solar' },
613+
aqLongitude: { type: 'string', description: 'Longitude for air quality, pollen, or solar' },
614+
languageCode: { type: 'string', description: 'Language code for air quality or pollen' },
615+
days: { type: 'string', description: 'Number of pollen forecast days (1-5)' },
616+
plantsDescription: { type: 'boolean', description: 'Include detailed plant descriptions' },
617+
requiredQuality: { type: 'string', description: 'Minimum solar imagery quality' },
567618
},
568619

569620
outputs: {
@@ -636,6 +687,21 @@ export const GoogleMapsBlock: BlockConfig = {
636687
indexes: { type: 'json', description: 'Air quality indexes' },
637688
pollutants: { type: 'json', description: 'Pollutant concentrations' },
638689
healthRecommendations: { type: 'json', description: 'Health recommendations' },
690+
691+
dailyInfo: { type: 'json', description: 'Daily pollen forecast (grass, tree, weed, plants)' },
692+
693+
center: { type: 'json', description: 'Center coordinate of the solar building' },
694+
imageryDate: { type: 'json', description: 'Date the solar imagery was captured' },
695+
imageryQuality: { type: 'string', description: 'Quality of the solar imagery used' },
696+
postalCode: { type: 'string', description: 'Postal code of the solar building' },
697+
administrativeArea: {
698+
type: 'string',
699+
description: 'Administrative area of the solar building',
700+
},
701+
solarPotential: {
702+
type: 'json',
703+
description: 'Solar potential, panel specs, and configurations',
704+
},
639705
},
640706
}
641707

0 commit comments

Comments
 (0)