Skip to content

Commit 486a76d

Browse files
committed
feat(google-translate): add Google Translate integration (#3337)
* feat(google-translate): add Google Translate integration * fix(google-translate): api key as query param, fix docsLink, rename tool file
1 parent 1f2306e commit 486a76d

File tree

12 files changed

+470
-0
lines changed

12 files changed

+470
-0
lines changed

apps/docs/components/icons.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5445,6 +5445,34 @@ export function GoogleMapsIcon(props: SVGProps<SVGSVGElement>) {
54455445
)
54465446
}
54475447

5448+
export function GoogleTranslateIcon(props: SVGProps<SVGSVGElement>) {
5449+
return (
5450+
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 998.1 998.3'>
5451+
<path
5452+
fill='#DBDBDB'
5453+
d='M931.7 998.3c36.5 0 66.4-29.4 66.4-65.4V265.8c0-36-29.9-65.4-66.4-65.4H283.6l260.1 797.9h388z'
5454+
/>
5455+
<path
5456+
fill='#DCDCDC'
5457+
d='M931.7 230.4c9.7 0 18.9 3.8 25.8 10.6 6.8 6.7 10.6 15.5 10.6 24.8v667.1c0 9.3-3.7 18.1-10.6 24.8-6.9 6.8-16.1 10.6-25.8 10.6H565.5L324.9 230.4h606.8m0-30H283.6l260.1 797.9h388c36.5 0 66.4-29.4 66.4-65.4V265.8c0-36-29.9-65.4-66.4-65.4z'
5458+
/>
5459+
<polygon fill='#4352B8' points='482.3,809.8 543.7,998.3 714.4,809.8' />
5460+
<path
5461+
fill='#607988'
5462+
d='M936.1 476.1V437H747.6v-63.2h-61.2V437H566.1v39.1h239.4c-12.8 45.1-41.1 87.7-68.7 120.8-48.9-57.9-49.1-76.7-49.1-76.7h-50.8s2.1 28.2 70.7 108.6c-22.3 22.8-39.2 36.3-39.2 36.3l15.6 48.8s23.6-20.3 53.1-51.6c29.6 32.1 67.8 70.7 117.2 116.7l32.1-32.1c-52.9-48-91.7-86.1-120.2-116.7 38.2-45.2 77-102.1 85.2-154.2H936v.1z'
5463+
/>
5464+
<path
5465+
fill='#4285F4'
5466+
d='M66.4 0C29.9 0 0 29.9 0 66.5v677c0 36.5 29.9 66.4 66.4 66.4h648.1L454.4 0h-388z'
5467+
/>
5468+
<path
5469+
fill='#EEEEEE'
5470+
d='M371.4 430.6c-2.5 30.3-28.4 75.2-91.1 75.2-54.3 0-98.3-44.9-98.3-100.2s44-100.2 98.3-100.2c30.9 0 51.5 13.4 63.3 24.3l41.2-39.6c-27.1-25-62.4-40.6-104.5-40.6-86.1 0-156 69.9-156 156s69.9 156 156 156c90.2 0 149.8-63.3 149.8-152.6 0-12.8-1.6-22.2-3.7-31.8h-146v53.4l91 .1z'
5471+
/>
5472+
</svg>
5473+
)
5474+
}
5475+
54485476
export function DsPyIcon(props: SVGProps<SVGSVGElement>) {
54495477
return (
54505478
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='30 28 185 175' fill='none'>

apps/docs/components/ui/icon-mapping.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import {
5252
GoogleMapsIcon,
5353
GoogleSheetsIcon,
5454
GoogleSlidesIcon,
55+
GoogleTranslateIcon,
5556
GoogleVaultIcon,
5657
GrafanaIcon,
5758
GrainIcon,
@@ -197,6 +198,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
197198
google_search: GoogleIcon,
198199
google_sheets_v2: GoogleSheetsIcon,
199200
google_slides_v2: GoogleSlidesIcon,
201+
google_translate: GoogleTranslateIcon,
200202
google_vault: GoogleVaultIcon,
201203
grafana: GrafanaIcon,
202204
grain: GrainIcon,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
title: Google Translate
3+
description: Translate text using Google Cloud Translation
4+
---
5+
6+
import { BlockInfoCard } from "@/components/ui/block-info-card"
7+
8+
<BlockInfoCard
9+
type="google_translate"
10+
color="#E0E0E0"
11+
/>
12+
13+
## Usage Instructions
14+
15+
Translate and detect languages using the Google Cloud Translation API. Supports auto-detection of the source language.
16+
17+
18+
19+
## Tools
20+
21+
### `google_translate_text`
22+
23+
Translate text between languages using the Google Cloud Translation API. Supports auto-detection of the source language.
24+
25+
#### Input
26+
27+
| Parameter | Type | Required | Description |
28+
| --------- | ---- | -------- | ----------- |
29+
| `apiKey` | string | Yes | Google Cloud API key with Cloud Translation API enabled |
30+
| `text` | string | Yes | The text to translate |
31+
| `target` | string | Yes | Target language code \(e.g., "es", "fr", "de", "ja"\) |
32+
| `source` | string | No | Source language code. If omitted, the API will auto-detect the source language. |
33+
| `format` | string | No | Format of the text: "text" for plain text, "html" for HTML content |
34+
35+
#### Output
36+
37+
| Parameter | Type | Description |
38+
| --------- | ---- | ----------- |
39+
| `translatedText` | string | The translated text |
40+
| `detectedSourceLanguage` | string | The detected source language code \(if source was not specified\) |
41+
42+
### `google_translate_detect`
43+
44+
Detect the language of text using the Google Cloud Translation API.
45+
46+
#### Input
47+
48+
| Parameter | Type | Required | Description |
49+
| --------- | ---- | -------- | ----------- |
50+
| `apiKey` | string | Yes | Google Cloud API key with Cloud Translation API enabled |
51+
| `text` | string | Yes | The text to detect the language of |
52+
53+
#### Output
54+
55+
| Parameter | Type | Description |
56+
| --------- | ---- | ----------- |
57+
| `language` | string | The detected language code \(e.g., "en", "es", "fr"\) |
58+
| `confidence` | number | Confidence score of the detection |
59+
60+

apps/docs/content/docs/en/tools/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"google_search",
4848
"google_sheets",
4949
"google_slides",
50+
"google_translate",
5051
"google_vault",
5152
"grafana",
5253
"grain",
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { GoogleTranslateIcon } from '@/components/icons'
2+
import { AuthMode, type BlockConfig } from '@/blocks/types'
3+
4+
export const GoogleTranslateBlock: BlockConfig = {
5+
type: 'google_translate',
6+
name: 'Google Translate',
7+
description: 'Translate text using Google Cloud Translation',
8+
longDescription:
9+
'Translate and detect languages using the Google Cloud Translation API. Supports auto-detection of the source language.',
10+
docsLink: 'https://docs.sim.ai/tools/google_translate',
11+
category: 'tools',
12+
bgColor: '#E0E0E0',
13+
icon: GoogleTranslateIcon,
14+
authMode: AuthMode.ApiKey,
15+
subBlocks: [
16+
{
17+
id: 'operation',
18+
title: 'Operation',
19+
type: 'dropdown',
20+
options: [
21+
{ label: 'Translate Text', id: 'text' },
22+
{ label: 'Detect Language', id: 'detect' },
23+
],
24+
value: () => 'text',
25+
},
26+
{
27+
id: 'text',
28+
title: 'Text',
29+
type: 'long-input',
30+
placeholder: 'Enter text...',
31+
required: true,
32+
},
33+
{
34+
id: 'target',
35+
title: 'Target Language',
36+
type: 'dropdown',
37+
condition: { field: 'operation', value: 'text' },
38+
options: [
39+
{ label: 'English', id: 'en' },
40+
{ label: 'Spanish', id: 'es' },
41+
{ label: 'French', id: 'fr' },
42+
{ label: 'German', id: 'de' },
43+
{ label: 'Italian', id: 'it' },
44+
{ label: 'Portuguese', id: 'pt' },
45+
{ label: 'Russian', id: 'ru' },
46+
{ label: 'Japanese', id: 'ja' },
47+
{ label: 'Korean', id: 'ko' },
48+
{ label: 'Chinese (Simplified)', id: 'zh-CN' },
49+
{ label: 'Chinese (Traditional)', id: 'zh-TW' },
50+
{ label: 'Arabic', id: 'ar' },
51+
{ label: 'Hindi', id: 'hi' },
52+
{ label: 'Turkish', id: 'tr' },
53+
{ label: 'Dutch', id: 'nl' },
54+
{ label: 'Polish', id: 'pl' },
55+
{ label: 'Swedish', id: 'sv' },
56+
{ label: 'Thai', id: 'th' },
57+
{ label: 'Vietnamese', id: 'vi' },
58+
{ label: 'Indonesian', id: 'id' },
59+
{ label: 'Ukrainian', id: 'uk' },
60+
{ label: 'Czech', id: 'cs' },
61+
{ label: 'Greek', id: 'el' },
62+
{ label: 'Hebrew', id: 'he' },
63+
{ label: 'Romanian', id: 'ro' },
64+
{ label: 'Hungarian', id: 'hu' },
65+
{ label: 'Danish', id: 'da' },
66+
{ label: 'Finnish', id: 'fi' },
67+
{ label: 'Norwegian', id: 'no' },
68+
{ label: 'Bengali', id: 'bn' },
69+
{ label: 'Malay', id: 'ms' },
70+
{ label: 'Filipino', id: 'tl' },
71+
{ label: 'Swahili', id: 'sw' },
72+
{ label: 'Urdu', id: 'ur' },
73+
],
74+
value: () => 'es',
75+
required: { field: 'operation', value: 'text' },
76+
},
77+
{
78+
id: 'source',
79+
title: 'Source Language',
80+
type: 'dropdown',
81+
condition: { field: 'operation', value: 'text' },
82+
options: [
83+
{ label: 'Auto-detect', id: '' },
84+
{ label: 'English', id: 'en' },
85+
{ label: 'Spanish', id: 'es' },
86+
{ label: 'French', id: 'fr' },
87+
{ label: 'German', id: 'de' },
88+
{ label: 'Italian', id: 'it' },
89+
{ label: 'Portuguese', id: 'pt' },
90+
{ label: 'Russian', id: 'ru' },
91+
{ label: 'Japanese', id: 'ja' },
92+
{ label: 'Korean', id: 'ko' },
93+
{ label: 'Chinese (Simplified)', id: 'zh-CN' },
94+
{ label: 'Chinese (Traditional)', id: 'zh-TW' },
95+
{ label: 'Arabic', id: 'ar' },
96+
{ label: 'Hindi', id: 'hi' },
97+
{ label: 'Turkish', id: 'tr' },
98+
{ label: 'Dutch', id: 'nl' },
99+
{ label: 'Polish', id: 'pl' },
100+
],
101+
value: () => '',
102+
},
103+
{
104+
id: 'apiKey',
105+
title: 'API Key',
106+
type: 'short-input',
107+
placeholder: 'Enter your Google Cloud API key',
108+
password: true,
109+
required: true,
110+
},
111+
],
112+
tools: {
113+
access: ['google_translate_text', 'google_translate_detect'],
114+
config: {
115+
tool: (params) => `google_translate_${params.operation}`,
116+
},
117+
},
118+
inputs: {
119+
text: { type: 'string', description: 'Text to translate or detect language of' },
120+
target: { type: 'string', description: 'Target language code' },
121+
source: { type: 'string', description: 'Source language code (optional, auto-detected)' },
122+
apiKey: { type: 'string', description: 'Google Cloud API key' },
123+
},
124+
outputs: {
125+
translatedText: { type: 'string', description: 'Translated text' },
126+
detectedSourceLanguage: { type: 'string', description: 'Detected source language code' },
127+
language: { type: 'string', description: 'Detected language code' },
128+
confidence: { type: 'number', description: 'Detection confidence score' },
129+
},
130+
}

apps/sim/blocks/registry.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { GoogleGroupsBlock } from '@/blocks/blocks/google_groups'
5252
import { GoogleMapsBlock } from '@/blocks/blocks/google_maps'
5353
import { GoogleSheetsBlock, GoogleSheetsV2Block } from '@/blocks/blocks/google_sheets'
5454
import { GoogleSlidesBlock, GoogleSlidesV2Block } from '@/blocks/blocks/google_slides'
55+
import { GoogleTranslateBlock } from '@/blocks/blocks/google_translate'
5556
import { GoogleVaultBlock } from '@/blocks/blocks/google_vault'
5657
import { GrafanaBlock } from '@/blocks/blocks/grafana'
5758
import { GrainBlock } from '@/blocks/blocks/grain'
@@ -234,6 +235,7 @@ export const registry: Record<string, BlockConfig> = {
234235
google_forms: GoogleFormsBlock,
235236
google_groups: GoogleGroupsBlock,
236237
google_maps: GoogleMapsBlock,
238+
google_translate: GoogleTranslateBlock,
237239
gong: GongBlock,
238240
google_search: GoogleSearchBlock,
239241
google_sheets: GoogleSheetsBlock,

apps/sim/components/icons.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5445,6 +5445,34 @@ export function GoogleMapsIcon(props: SVGProps<SVGSVGElement>) {
54455445
)
54465446
}
54475447

5448+
export function GoogleTranslateIcon(props: SVGProps<SVGSVGElement>) {
5449+
return (
5450+
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 998.1 998.3'>
5451+
<path
5452+
fill='#DBDBDB'
5453+
d='M931.7 998.3c36.5 0 66.4-29.4 66.4-65.4V265.8c0-36-29.9-65.4-66.4-65.4H283.6l260.1 797.9h388z'
5454+
/>
5455+
<path
5456+
fill='#DCDCDC'
5457+
d='M931.7 230.4c9.7 0 18.9 3.8 25.8 10.6 6.8 6.7 10.6 15.5 10.6 24.8v667.1c0 9.3-3.7 18.1-10.6 24.8-6.9 6.8-16.1 10.6-25.8 10.6H565.5L324.9 230.4h606.8m0-30H283.6l260.1 797.9h388c36.5 0 66.4-29.4 66.4-65.4V265.8c0-36-29.9-65.4-66.4-65.4z'
5458+
/>
5459+
<polygon fill='#4352B8' points='482.3,809.8 543.7,998.3 714.4,809.8' />
5460+
<path
5461+
fill='#607988'
5462+
d='M936.1 476.1V437H747.6v-63.2h-61.2V437H566.1v39.1h239.4c-12.8 45.1-41.1 87.7-68.7 120.8-48.9-57.9-49.1-76.7-49.1-76.7h-50.8s2.1 28.2 70.7 108.6c-22.3 22.8-39.2 36.3-39.2 36.3l15.6 48.8s23.6-20.3 53.1-51.6c29.6 32.1 67.8 70.7 117.2 116.7l32.1-32.1c-52.9-48-91.7-86.1-120.2-116.7 38.2-45.2 77-102.1 85.2-154.2H936v.1z'
5463+
/>
5464+
<path
5465+
fill='#4285F4'
5466+
d='M66.4 0C29.9 0 0 29.9 0 66.5v677c0 36.5 29.9 66.4 66.4 66.4h648.1L454.4 0h-388z'
5467+
/>
5468+
<path
5469+
fill='#EEEEEE'
5470+
d='M371.4 430.6c-2.5 30.3-28.4 75.2-91.1 75.2-54.3 0-98.3-44.9-98.3-100.2s44-100.2 98.3-100.2c30.9 0 51.5 13.4 63.3 24.3l41.2-39.6c-27.1-25-62.4-40.6-104.5-40.6-86.1 0-156 69.9-156 156s69.9 156 156 156c90.2 0 149.8-63.3 149.8-152.6 0-12.8-1.6-22.2-3.7-31.8h-146v53.4l91 .1z'
5471+
/>
5472+
</svg>
5473+
)
5474+
}
5475+
54485476
export function DsPyIcon(props: SVGProps<SVGSVGElement>) {
54495477
return (
54505478
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='30 28 185 175' fill='none'>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import type {
2+
GoogleTranslateDetectParams,
3+
GoogleTranslateDetectResponse,
4+
} from '@/tools/google_translate/types'
5+
import type { ToolConfig } from '@/tools/types'
6+
7+
export const googleTranslateDetectTool: ToolConfig<
8+
GoogleTranslateDetectParams,
9+
GoogleTranslateDetectResponse
10+
> = {
11+
id: 'google_translate_detect',
12+
name: 'Google Translate Detect Language',
13+
description: 'Detect the language of text using the Google Cloud Translation API.',
14+
version: '1.0.0',
15+
16+
params: {
17+
apiKey: {
18+
type: 'string',
19+
required: true,
20+
visibility: 'user-only',
21+
description: 'Google Cloud API key with Cloud Translation API enabled',
22+
},
23+
text: {
24+
type: 'string',
25+
required: true,
26+
visibility: 'user-or-llm',
27+
description: 'The text to detect the language of',
28+
},
29+
},
30+
31+
request: {
32+
url: (params) => {
33+
const url = new URL('https://translation.googleapis.com/language/translate/v2/detect')
34+
url.searchParams.set('key', params.apiKey)
35+
return url.toString()
36+
},
37+
method: 'POST',
38+
headers: () => ({
39+
'Content-Type': 'application/json',
40+
}),
41+
body: (params) => ({
42+
q: params.text,
43+
}),
44+
},
45+
46+
transformResponse: async (response: Response) => {
47+
const data = await response.json()
48+
49+
if (data.error) {
50+
return {
51+
success: false,
52+
output: {
53+
language: '',
54+
confidence: null,
55+
},
56+
error: data.error.message ?? 'Google Translate API error',
57+
}
58+
}
59+
60+
const detection = data.data?.detections?.[0]?.[0]
61+
62+
return {
63+
success: true,
64+
output: {
65+
language: detection?.language ?? '',
66+
confidence: detection?.confidence ?? null,
67+
},
68+
}
69+
},
70+
71+
outputs: {
72+
language: {
73+
type: 'string',
74+
description: 'The detected language code (e.g., "en", "es", "fr")',
75+
},
76+
confidence: {
77+
type: 'number',
78+
description: 'Confidence score of the detection',
79+
optional: true,
80+
},
81+
},
82+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { googleTranslateDetectTool } from './detect'
2+
import { googleTranslateTool } from './text'
3+
4+
export { googleTranslateDetectTool, googleTranslateTool }

0 commit comments

Comments
 (0)