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
This commit is contained in:
Waleed
2026-02-25 13:24:22 -08:00
committed by GitHub
parent 870d4b55c6
commit 063ec87ced
12 changed files with 470 additions and 0 deletions

View File

@@ -5445,6 +5445,34 @@ export function GoogleMapsIcon(props: SVGProps<SVGSVGElement>) {
)
}
export function GoogleTranslateIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 998.1 998.3'>
<path
fill='#DBDBDB'
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'
/>
<path
fill='#DCDCDC'
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'
/>
<polygon fill='#4352B8' points='482.3,809.8 543.7,998.3 714.4,809.8' />
<path
fill='#607988'
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'
/>
<path
fill='#4285F4'
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'
/>
<path
fill='#EEEEEE'
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'
/>
</svg>
)
}
export function DsPyIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='30 28 185 175' fill='none'>

View File

@@ -52,6 +52,7 @@ import {
GoogleMapsIcon,
GoogleSheetsIcon,
GoogleSlidesIcon,
GoogleTranslateIcon,
GoogleVaultIcon,
GrafanaIcon,
GrainIcon,
@@ -197,6 +198,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
google_search: GoogleIcon,
google_sheets_v2: GoogleSheetsIcon,
google_slides_v2: GoogleSlidesIcon,
google_translate: GoogleTranslateIcon,
google_vault: GoogleVaultIcon,
grafana: GrafanaIcon,
grain: GrainIcon,

View File

@@ -0,0 +1,60 @@
---
title: Google Translate
description: Translate text using Google Cloud Translation
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="google_translate"
color="#E0E0E0"
/>
## Usage Instructions
Translate and detect languages using the Google Cloud Translation API. Supports auto-detection of the source language.
## Tools
### `google_translate_text`
Translate text between languages using the Google Cloud Translation API. Supports auto-detection of the source language.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Google Cloud API key with Cloud Translation API enabled |
| `text` | string | Yes | The text to translate |
| `target` | string | Yes | Target language code \(e.g., "es", "fr", "de", "ja"\) |
| `source` | string | No | Source language code. If omitted, the API will auto-detect the source language. |
| `format` | string | No | Format of the text: "text" for plain text, "html" for HTML content |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `translatedText` | string | The translated text |
| `detectedSourceLanguage` | string | The detected source language code \(if source was not specified\) |
### `google_translate_detect`
Detect the language of text using the Google Cloud Translation API.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Google Cloud API key with Cloud Translation API enabled |
| `text` | string | Yes | The text to detect the language of |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `language` | string | The detected language code \(e.g., "en", "es", "fr"\) |
| `confidence` | number | Confidence score of the detection |

View File

@@ -47,6 +47,7 @@
"google_search",
"google_sheets",
"google_slides",
"google_translate",
"google_vault",
"grafana",
"grain",

View File

@@ -0,0 +1,130 @@
import { GoogleTranslateIcon } from '@/components/icons'
import { AuthMode, type BlockConfig } from '@/blocks/types'
export const GoogleTranslateBlock: BlockConfig = {
type: 'google_translate',
name: 'Google Translate',
description: 'Translate text using Google Cloud Translation',
longDescription:
'Translate and detect languages using the Google Cloud Translation API. Supports auto-detection of the source language.',
docsLink: 'https://docs.sim.ai/tools/google_translate',
category: 'tools',
bgColor: '#E0E0E0',
icon: GoogleTranslateIcon,
authMode: AuthMode.ApiKey,
subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
options: [
{ label: 'Translate Text', id: 'text' },
{ label: 'Detect Language', id: 'detect' },
],
value: () => 'text',
},
{
id: 'text',
title: 'Text',
type: 'long-input',
placeholder: 'Enter text...',
required: true,
},
{
id: 'target',
title: 'Target Language',
type: 'dropdown',
condition: { field: 'operation', value: 'text' },
options: [
{ label: 'English', id: 'en' },
{ label: 'Spanish', id: 'es' },
{ label: 'French', id: 'fr' },
{ label: 'German', id: 'de' },
{ label: 'Italian', id: 'it' },
{ label: 'Portuguese', id: 'pt' },
{ label: 'Russian', id: 'ru' },
{ label: 'Japanese', id: 'ja' },
{ label: 'Korean', id: 'ko' },
{ label: 'Chinese (Simplified)', id: 'zh-CN' },
{ label: 'Chinese (Traditional)', id: 'zh-TW' },
{ label: 'Arabic', id: 'ar' },
{ label: 'Hindi', id: 'hi' },
{ label: 'Turkish', id: 'tr' },
{ label: 'Dutch', id: 'nl' },
{ label: 'Polish', id: 'pl' },
{ label: 'Swedish', id: 'sv' },
{ label: 'Thai', id: 'th' },
{ label: 'Vietnamese', id: 'vi' },
{ label: 'Indonesian', id: 'id' },
{ label: 'Ukrainian', id: 'uk' },
{ label: 'Czech', id: 'cs' },
{ label: 'Greek', id: 'el' },
{ label: 'Hebrew', id: 'he' },
{ label: 'Romanian', id: 'ro' },
{ label: 'Hungarian', id: 'hu' },
{ label: 'Danish', id: 'da' },
{ label: 'Finnish', id: 'fi' },
{ label: 'Norwegian', id: 'no' },
{ label: 'Bengali', id: 'bn' },
{ label: 'Malay', id: 'ms' },
{ label: 'Filipino', id: 'tl' },
{ label: 'Swahili', id: 'sw' },
{ label: 'Urdu', id: 'ur' },
],
value: () => 'es',
required: { field: 'operation', value: 'text' },
},
{
id: 'source',
title: 'Source Language',
type: 'dropdown',
condition: { field: 'operation', value: 'text' },
options: [
{ label: 'Auto-detect', id: '' },
{ label: 'English', id: 'en' },
{ label: 'Spanish', id: 'es' },
{ label: 'French', id: 'fr' },
{ label: 'German', id: 'de' },
{ label: 'Italian', id: 'it' },
{ label: 'Portuguese', id: 'pt' },
{ label: 'Russian', id: 'ru' },
{ label: 'Japanese', id: 'ja' },
{ label: 'Korean', id: 'ko' },
{ label: 'Chinese (Simplified)', id: 'zh-CN' },
{ label: 'Chinese (Traditional)', id: 'zh-TW' },
{ label: 'Arabic', id: 'ar' },
{ label: 'Hindi', id: 'hi' },
{ label: 'Turkish', id: 'tr' },
{ label: 'Dutch', id: 'nl' },
{ label: 'Polish', id: 'pl' },
],
value: () => '',
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
placeholder: 'Enter your Google Cloud API key',
password: true,
required: true,
},
],
tools: {
access: ['google_translate_text', 'google_translate_detect'],
config: {
tool: (params) => `google_translate_${params.operation}`,
},
},
inputs: {
text: { type: 'string', description: 'Text to translate or detect language of' },
target: { type: 'string', description: 'Target language code' },
source: { type: 'string', description: 'Source language code (optional, auto-detected)' },
apiKey: { type: 'string', description: 'Google Cloud API key' },
},
outputs: {
translatedText: { type: 'string', description: 'Translated text' },
detectedSourceLanguage: { type: 'string', description: 'Detected source language code' },
language: { type: 'string', description: 'Detected language code' },
confidence: { type: 'number', description: 'Detection confidence score' },
},
}

View File

@@ -52,6 +52,7 @@ import { GoogleGroupsBlock } from '@/blocks/blocks/google_groups'
import { GoogleMapsBlock } from '@/blocks/blocks/google_maps'
import { GoogleSheetsBlock, GoogleSheetsV2Block } from '@/blocks/blocks/google_sheets'
import { GoogleSlidesBlock, GoogleSlidesV2Block } from '@/blocks/blocks/google_slides'
import { GoogleTranslateBlock } from '@/blocks/blocks/google_translate'
import { GoogleVaultBlock } from '@/blocks/blocks/google_vault'
import { GrafanaBlock } from '@/blocks/blocks/grafana'
import { GrainBlock } from '@/blocks/blocks/grain'
@@ -234,6 +235,7 @@ export const registry: Record<string, BlockConfig> = {
google_forms: GoogleFormsBlock,
google_groups: GoogleGroupsBlock,
google_maps: GoogleMapsBlock,
google_translate: GoogleTranslateBlock,
gong: GongBlock,
google_search: GoogleSearchBlock,
google_sheets: GoogleSheetsBlock,

View File

@@ -5445,6 +5445,34 @@ export function GoogleMapsIcon(props: SVGProps<SVGSVGElement>) {
)
}
export function GoogleTranslateIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 998.1 998.3'>
<path
fill='#DBDBDB'
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'
/>
<path
fill='#DCDCDC'
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'
/>
<polygon fill='#4352B8' points='482.3,809.8 543.7,998.3 714.4,809.8' />
<path
fill='#607988'
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'
/>
<path
fill='#4285F4'
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'
/>
<path
fill='#EEEEEE'
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'
/>
</svg>
)
}
export function DsPyIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='30 28 185 175' fill='none'>

View File

@@ -0,0 +1,82 @@
import type {
GoogleTranslateDetectParams,
GoogleTranslateDetectResponse,
} from '@/tools/google_translate/types'
import type { ToolConfig } from '@/tools/types'
export const googleTranslateDetectTool: ToolConfig<
GoogleTranslateDetectParams,
GoogleTranslateDetectResponse
> = {
id: 'google_translate_detect',
name: 'Google Translate Detect Language',
description: 'Detect the language of text using the Google Cloud Translation API.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Google Cloud API key with Cloud Translation API enabled',
},
text: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The text to detect the language of',
},
},
request: {
url: (params) => {
const url = new URL('https://translation.googleapis.com/language/translate/v2/detect')
url.searchParams.set('key', params.apiKey)
return url.toString()
},
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
q: params.text,
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (data.error) {
return {
success: false,
output: {
language: '',
confidence: null,
},
error: data.error.message ?? 'Google Translate API error',
}
}
const detection = data.data?.detections?.[0]?.[0]
return {
success: true,
output: {
language: detection?.language ?? '',
confidence: detection?.confidence ?? null,
},
}
},
outputs: {
language: {
type: 'string',
description: 'The detected language code (e.g., "en", "es", "fr")',
},
confidence: {
type: 'number',
description: 'Confidence score of the detection',
optional: true,
},
},
}

View File

@@ -0,0 +1,4 @@
import { googleTranslateDetectTool } from './detect'
import { googleTranslateTool } from './text'
export { googleTranslateDetectTool, googleTranslateTool }

View File

@@ -0,0 +1,102 @@
import type { GoogleTranslateParams, GoogleTranslateResponse } from '@/tools/google_translate/types'
import type { ToolConfig } from '@/tools/types'
export const googleTranslateTool: ToolConfig<GoogleTranslateParams, GoogleTranslateResponse> = {
id: 'google_translate_text',
name: 'Google Translate',
description:
'Translate text between languages using the Google Cloud Translation API. Supports auto-detection of the source language.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Google Cloud API key with Cloud Translation API enabled',
},
text: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The text to translate',
},
target: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Target language code (e.g., "es", "fr", "de", "ja")',
},
source: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Source language code. If omitted, the API will auto-detect the source language.',
},
format: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Format of the text: "text" for plain text, "html" for HTML content',
},
},
request: {
url: (params) => {
const url = new URL('https://translation.googleapis.com/language/translate/v2')
url.searchParams.set('key', params.apiKey)
return url.toString()
},
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
q: params.text,
target: params.target,
}
if (params.source) body.source = params.source
if (params.format) body.format = params.format
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (data.error) {
return {
success: false,
output: {
translatedText: '',
detectedSourceLanguage: null,
},
error: data.error.message ?? 'Google Translate API error',
}
}
const translation = data.data?.translations?.[0]
return {
success: true,
output: {
translatedText: translation?.translatedText ?? '',
detectedSourceLanguage: translation?.detectedSourceLanguage ?? null,
},
}
},
outputs: {
translatedText: {
type: 'string',
description: 'The translated text',
},
detectedSourceLanguage: {
type: 'string',
description: 'The detected source language code (if source was not specified)',
optional: true,
},
},
}

View File

@@ -0,0 +1,28 @@
import type { ToolResponse } from '@/tools/types'
export interface GoogleTranslateParams {
apiKey: string
text: string
target: string
source?: string
format?: 'text' | 'html'
}
export interface GoogleTranslateResponse extends ToolResponse {
output: {
translatedText: string
detectedSourceLanguage: string | null
}
}
export interface GoogleTranslateDetectParams {
apiKey: string
text: string
}
export interface GoogleTranslateDetectResponse extends ToolResponse {
output: {
language: string
confidence: number | null
}
}

View File

@@ -738,6 +738,7 @@ import {
googleSlidesUpdateSlidesPositionTool,
googleSlidesWriteTool,
} from '@/tools/google_slides'
import { googleTranslateDetectTool, googleTranslateTool } from '@/tools/google_translate'
import {
createMattersExportTool,
createMattersHoldsTool,
@@ -2891,6 +2892,8 @@ export const tools: Record<string, ToolConfig> = {
google_maps_speed_limits: googleMapsSpeedLimitsTool,
google_maps_timezone: googleMapsTimezoneTool,
google_maps_validate_address: googleMapsValidateAddressTool,
google_translate_detect: googleTranslateDetectTool,
google_translate_text: googleTranslateTool,
google_sheets_read: googleSheetsReadTool,
google_sheets_write: googleSheetsWriteTool,
google_sheets_update: googleSheetsUpdateTool,