UPDATE
The Google Translate API has been officially deprecated an alternative is the Microsoft Translator V2, check this article for more details.
In this post i will show you how work with the Google Translate API V2 (Labs), this API lets you automatically translates text from one language to another.
Disclaimer
- This version of the Google Translate API is in Labs, and its features might change unexpectedly until it graduates.
- The Google Translate API requires the use of an API key, which you can get from the Google APIs console
- Before to use this API check the Google Translate API Terms of Use.
To use the Google Translate API you must send a HTTP GET request to its URI.
The URI for a request has the following format:
Example to making a request to translate the Hello World text from English (en) to Spanish (es) the URI must be constructed in this way
https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&source=en&target=es&q=Hello%20world
The response in JSON format will be
{"data":{"translations":[{"translatedText":"Hola Mundo"}]}}
To activate the auto-detection of the source language you must avoid the use of the source keyword
https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&target=es&q=Hello%20world
and the JSON response in this case will be
{"data":{"translations":[{"translatedText":"Hola a todos","detectedSourceLanguage":"en"}]}
if you pass incorrect parameters the response will look like this
{"error":{"errors":[{"domain":"global","reason":"invalid","message":"Invalid Value"}],"code":400,"message":"Invalid Value"}}
some conversions between languages are not allowed by the API, in thi case you will get a response of this type
{"error":{"errors":[{"domain":"global","reason":"badRequest","message":"Bad language pair: en|zh-TW"}],"code":400,"message":"Bad language pair: en|zh-TW"}}
Now I will show 3 ways to process the data
Using the JSON – SuperObject , this library is very well written and is very easy to use, also is compatible with olders versions of Delphi and Freepascal (win32/64 linux32/64).
function Translate_JSONsuperobject(const Text:string;Source,Dest:TGoogleLanguages):string; var XMLHTTPRequest: IXMLHTTPRequest; EncodedRequest: string; Response : string; begin Result:=''; if Source=Autodetect then //build the URI EncodedRequest:=Format(GoogleTranslateUrlAuto,[GoogleLanguageApiKey,GoogleLanguagesArr[Dest],HTTPEncode(Text)]) else EncodedRequest:=Format(GoogleTranslateUrl,[GoogleLanguageApiKey,HTTPEncode(Text),GoogleLanguagesArr[Source],GoogleLanguagesArr[Dest]]); XMLHTTPRequest := CoXMLHTTP.Create; XMLHTTPRequest.open('GET', EncodedRequest, False, EmptyParam, EmptyParam); //Make the request XMLHTTPRequest.send(''); Response:=XMLHTTPRequest.responseText; if Response<>'' then begin if SO(Response)['error']=nil then //all ok Result := SO(Response)['data.translations[0].translatedText'].AsString else //exist an error response Result := Format('Error Code %d message %s',[SO(Response)['error.code'].AsInteger,SO(Response)['error.message'].AsString]); Result:=HTMLDecode(Result); end; end;
Using the DBXJSON unit included since Delphi 2010
function Translate_DBXJSON(const Text:string;Source,Dest:TGoogleLanguages):string; var XMLHTTPRequest: IXMLHTTPRequest; EncodedRequest: string; json : TJSONObject; jPair : TJSONPair; jValue : TJSONValue; Response : string; begin Result:=''; if Source=Autodetect then //buil the URI EncodedRequest:=Format(GoogleTranslateUrlAuto,[GoogleLanguageApiKey,GoogleLanguagesArr[Dest],HTTPEncode(Text)]) else EncodedRequest:=Format(GoogleTranslateUrl,[GoogleLanguageApiKey,HTTPEncode(Text),GoogleLanguagesArr[Source],GoogleLanguagesArr[Dest]]); XMLHTTPRequest := CoXMLHTTP.Create; XMLHTTPRequest.open('GET', EncodedRequest, False, EmptyParam, EmptyParam); //make the request XMLHTTPRequest.send(''); Response:=XMLHTTPRequest.responseText; if Response<>'' then begin json := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(Response),0) as TJSONObject; //create a TJSONObject instance try jPair := json.Get(0); if jPair.JsonString.value='error' then //if error in response Result := Format('Error Code %s message %s',[TJSONObject(jPair.JsonValue).Get(1).JsonValue.Value,TJSONObject(jPair.JsonValue).Get(2).JsonValue.Value]) else //all ok, show the response, begin jValue := TJSONArray(TJSONObject(jPair.JsonValue).Get(0).JsonValue).Get(0); Result := TJSONObject(jValue).Get(0).JsonValue.Value; end; finally json.Free; end; Result:=HTMLDecode(Result); end; end;
and finally without using JSON, a very ugly way, but works.
function Translate_JSONLess(const Text:string;Source,Dest:TGoogleLanguages):string; const TagIOk='{"data":{"translations":[{"translatedText":"'; TagFOk='"}]}}'; TagErr='{"error":{"errors":[{'; TagAut=',"detectedSourceLanguage":"'; var XMLHTTPRequest: IXMLHTTPRequest; EncodedRequest: string; Response : string; begin Result:=''; if Source=Autodetect then //build the URI EncodedRequest:=Format(GoogleTranslateUrlAuto,[GoogleLanguageApiKey,GoogleLanguagesArr[Dest],HTTPEncode(Text)]) else EncodedRequest:=Format(GoogleTranslateUrl,[GoogleLanguageApiKey,HTTPEncode(Text),GoogleLanguagesArr[Source],GoogleLanguagesArr[Dest]]); XMLHTTPRequest := CoXMLHTTP.Create; XMLHTTPRequest.open('GET', EncodedRequest, False, EmptyParam, EmptyParam); //make the request XMLHTTPRequest.send(''); Response:=XMLHTTPRequest.responseText; if Response<>'' then begin if StartsStr(TagErr,(Response)) then //Response Error begin Result:='Error' end else begin //Response Ok if Source=Autodetect then begin Result:=StringReplace(Response,TagIOk,'',[rfReplaceAll]); //remove tags Result:=Copy(Result,1,Pos(TagAut,Result)-2);//remove tags end else begin Result:=StringReplace(Response,TagIOk,'',[rfReplaceAll]);//remove tags Result:=StringReplace(Result,TagFOk,'',[rfReplaceAll]);//remove tags end; end; Result:=HTMLDecode(Result); end; end;
Check the full source showing the 3 ways to access the Google Translate API, listed in this entry.
program GoogleAPITranslate; //Author : Rodrigo Ruz V. 2010-12-03 03;30 A.M {$APPTYPE CONSOLE} {$DEFINE USE_SUPER_OBJECT} {$DEFINE USE_DBXJSON} {$DEFINE USE_JSONLess} uses msxml ,Activex ,HTTPApp ,Variants ,SysUtils {$IFDEF USE_JSONLess} ,StrUtils {$ENDIF} {$IFDEF USE_SUPER_OBJECT} ,superobject {$ENDIF} {$IFDEF USE_DBXJSON} ,DBXJSON {$ENDIF} ; type TGoogleLanguages= (Autodetect,Afrikaans,Albanian,Arabic,Basque,Belarusian,Bulgarian,Catalan,Chinese,Chinese_Traditional, Croatian,Czech,Danish,Dutch,English,Estonian,Filipino,Finnish,French,Galician,German,Greek, Haitian_Creole,Hebrew,Hindi,Hungarian,Icelandic,Indonesian,Irish,Italian,Japanese,Latvian, Lithuanian,Macedonian,Malay,Maltese,Norwegian,Persian,Polish,Portuguese,Romanian,Russian, Serbian,Slovak,Slovenian,Spanish,Swahili,Swedish,Thai,Turkish,Ukrainian,Vietnamese,Welsh,Yiddish); const GoogleLanguagesArr : array[TGoogleLanguages] of string = ( 'Autodetect','af','sq','ar','eu','be','bg','ca','zh-CN','zh-TW','hr','cs','da','nl','en','et','tl','fi','fr','gl', 'de','el','ht','iw','hi','hu','is','id','ga','it','ja','lv','lt','mk','ms','mt','no','fa','pl','pt', 'ro','ru','sr','sk','sl','es','sw','sv','th','tr','uk','vi','cy','yi'); //¡¡¡¡¡¡Please be nice and create your own Google Api Key ¡¡¡¡¡¡¡ GoogleLanguageApiKey ='AIzaSyDb18pd1IfkYyupC2XUIANcRoB3f9J2DJg'; GoogleTranslateUrl ='https://www.googleapis.com/language/translate/v2?key=%s&q=%s&source=%s&target=%s'; GoogleTranslateUrlAuto ='https://www.googleapis.com/language/translate/v2?key=%s&target=%s&q=%s'; {$IFDEF USE_DBXJSON} function Translate_DBXJSON(const Text:string;Source,Dest:TGoogleLanguages):string; var XMLHTTPRequest: IXMLHTTPRequest; EncodedRequest: string; json : TJSONObject; jPair : TJSONPair; jValue : TJSONValue; Response : string; begin Result:=''; if Source=Autodetect then EncodedRequest:=Format(GoogleTranslateUrlAuto,[GoogleLanguageApiKey,GoogleLanguagesArr[Dest],HTTPEncode(Text)]) else EncodedRequest:=Format(GoogleTranslateUrl,[GoogleLanguageApiKey,HTTPEncode(Text),GoogleLanguagesArr[Source],GoogleLanguagesArr[Dest]]); XMLHTTPRequest := CoXMLHTTP.Create; XMLHTTPRequest.open('GET', EncodedRequest, False, EmptyParam, EmptyParam); XMLHTTPRequest.send(''); Response:=XMLHTTPRequest.responseText; if Response<>'' then begin json := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(Response),0) as TJSONObject; try jPair := json.Get(0); if jPair.JsonString.value='error' then //{"error":{"errors":[{"domain":"global","reason":"invalid","message":"Invalid Value"}],"code":400,"message":"Invalid Value"}} Result := Format('Error Code %s message %s',[TJSONObject(jPair.JsonValue).Get(1).JsonValue.Value,TJSONObject(jPair.JsonValue).Get(2).JsonValue.Value]) else begin //{"data":{"translations":[{"translatedText":"Hola a todos","detectedSourceLanguage":"en"}]}} jValue := TJSONArray(TJSONObject(jPair.JsonValue).Get(0).JsonValue).Get(0); Result := TJSONObject(jValue).Get(0).JsonValue.Value; end; finally json.Free; end; Result:=HTMLDecode(Result); end; end; {$ENDIF} {$IFDEF USE_SUPER_OBJECT} function Translate_JSONsuperobject(const Text:string;Source,Dest:TGoogleLanguages):string; var XMLHTTPRequest: IXMLHTTPRequest; EncodedRequest: string; Response : string; begin Result:=''; if Source=Autodetect then EncodedRequest:=Format(GoogleTranslateUrlAuto,[GoogleLanguageApiKey,GoogleLanguagesArr[Dest],HTTPEncode(Text)]) else EncodedRequest:=Format(GoogleTranslateUrl,[GoogleLanguageApiKey,HTTPEncode(Text),GoogleLanguagesArr[Source],GoogleLanguagesArr[Dest]]); XMLHTTPRequest := CoXMLHTTP.Create; XMLHTTPRequest.open('GET', EncodedRequest, False, EmptyParam, EmptyParam); XMLHTTPRequest.send(''); Response:=XMLHTTPRequest.responseText; if Response<>'' then begin //{"data":{"translations":[{"translatedText":"Hola a todos","detectedSourceLanguage":"en"}]}} if SO(Response)['error']=nil then Result := SO(Response)['data.translations[0].translatedText'].AsString else //{"error":{"errors":[{"domain":"global","reason":"invalid","message":"Invalid Value"}],"code":400,"message":"Invalid Value"}} //{"error":{"errors":[{"domain":"global","reason":"badRequest","message":"Bad language pair: en|zh-TW"}],"code":400,"message":"Bad language pair: en|zh-TW"}} Result := Format('Error Code %d message %s',[SO(Response)['error.code'].AsInteger,SO(Response)['error.message'].AsString]); Result:=HTMLDecode(Result); end; end; {$ENDIF} {$IFDEF USE_JSONLess} function Translate_JSONLess(const Text:string;Source,Dest:TGoogleLanguages):string; const TagIOk='{"data":{"translations":[{"translatedText":"'; TagFOk='"}]}}'; TagErr='{"error":{"errors":[{'; TagAut=',"detectedSourceLanguage":"'; var XMLHTTPRequest: IXMLHTTPRequest; EncodedRequest: string; Response : string; begin Result:=''; if Source=Autodetect then EncodedRequest:=Format(GoogleTranslateUrlAuto,[GoogleLanguageApiKey,GoogleLanguagesArr[Dest],HTTPEncode(Text)]) else EncodedRequest:=Format(GoogleTranslateUrl,[GoogleLanguageApiKey,HTTPEncode(Text),GoogleLanguagesArr[Source],GoogleLanguagesArr[Dest]]); XMLHTTPRequest := CoXMLHTTP.Create; XMLHTTPRequest.open('GET', EncodedRequest, False, EmptyParam, EmptyParam); XMLHTTPRequest.send(''); Response:=XMLHTTPRequest.responseText; if Response<>'' then begin if StartsStr(TagErr,(Response)) then //Response Error begin Result:='Error' end else begin //Response Ok if Source=Autodetect then begin Result:=StringReplace(Response,TagIOk,'',[rfReplaceAll]); Result:=Copy(Result,1,Pos(TagAut,Result)-2); end else begin Result:=StringReplace(Response,TagIOk,'',[rfReplaceAll]); Result:=StringReplace(Result,TagFOk,'',[rfReplaceAll]); end; end; Result:=HTMLDecode(Result); end; end; {$ENDIF} Const Text ='"Hello World"'; Var TranslatedText : string; begin try CoInitialize(nil); try {$IFDEF USE_JSONLess} Writeln('Without JSON (very ugly)'); Writeln(''); TranslatedText:=Translate_JSONLess(Text,Autodetect,Spanish); Writeln(TranslatedText); TranslatedText:=Translate_JSONLess(Text,English,Chinese_Traditional); Writeln(TranslatedText); TranslatedText:=Translate_JSONLess(Text,English,German); Writeln(TranslatedText); TranslatedText:=Translate_JSONLess(Text,English,Danish); Writeln(TranslatedText); TranslatedText:=Translate_JSONLess(Text,English,Portuguese); Writeln(TranslatedText); Writeln(''); {$ENDIF} {$IFDEF USE_SUPER_OBJECT} Writeln('Using the superobject library'); Writeln(''); TranslatedText:=Translate_JSONsuperobject(Text,Autodetect,Spanish); Writeln(TranslatedText); TranslatedText:=Translate_JSONsuperobject(Text,English,Chinese_Traditional); Writeln(TranslatedText); TranslatedText:=Translate_JSONsuperobject(Text,English,German); Writeln(TranslatedText); TranslatedText:=Translate_JSONsuperobject(Text,English,Danish); Writeln(TranslatedText); TranslatedText:=Translate_JSONsuperobject(Text,English,Portuguese); Writeln(TranslatedText); Writeln(''); {$ENDIF} {$IFDEF USE_DBXJSON} Writeln('Using the DBXJSON unit'); Writeln(''); TranslatedText:=Translate_DBXJSON(Text,Autodetect,Spanish); Writeln(TranslatedText); TranslatedText:=Translate_DBXJSON(Text,English,Chinese_Traditional); Writeln(TranslatedText); TranslatedText:=Translate_DBXJSON(Text,English,German); Writeln(TranslatedText); TranslatedText:=Translate_DBXJSON(Text,English,Danish); Writeln(TranslatedText); TranslatedText:=Translate_DBXJSON(Text,English,Portuguese); Writeln(TranslatedText); Writeln(''); {$ENDIF} finally CoUninitialize; end; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end.
December 4, 2010 at 8:03 am
Rodrigo,
As usual, you gave explicit examples and of general interest! Keep up the good job, is always a pleasure to visit your site and see a lot of goodies :)
Have a nice day!
Pingback: Tweets that mention Using the Google Translate API V2 (Labs) from Delphi « The Road to Delphi – a Blog About Delphi Programming (mostly) -- Topsy.com
December 4, 2010 at 2:17 pm
Nice article.
Do anyone know something about the legal permissions when code like this is used in a commercial application? Is it still free when it’s used commercially?
December 4, 2010 at 2:23 pm
Check this link Google Translate API Terms of Use.
December 4, 2010 at 3:07 pm
hi
very thanks for your post.
do you know any solution for testing internet connection availability in delphi?
it means that internet is available or not , disconnect?
thanks
December 4, 2010 at 3:41 pm
AmirGT, check the InternetOpen function, by the way you can make this type of questions in StackOverflow.
Pingback: Detecting the language from a text using the Google translate API v1 « The Road to Delphi – a Blog About Delphi Programming (mostly)
March 8, 2011 at 12:40 pm
Rodrigo,
I used to code in Delphi (since version 1) but now I just do ‘pet projects’ in D2010. I am doing a little application to speed up my German studies and your code just nailed it. I was amazed to find your code, so well documented and robust. Thank you so much!!!
Fernando
March 8, 2011 at 12:44 pm
Gracias por tus comentarios Fernando.
June 12, 2011 at 12:15 pm
Not work
from portuguese to japanese, Yiddish, urdu
June 13, 2011 at 2:03 pm
Thank you, colegue! I have been searching this for my DLLs for some time already… :)
June 20, 2011 at 1:47 am
Rodrigo,
I try your example and it worked with the expected results.
I obtained my own application key and pasted it over yours and I now get
“Error Code 400 message Bad Request”
after each request.
Do you have any idea why this is?
My key was 86 characters long, where yours was 39. I’m not sure if that is the reason.
Thanks,
Simon
July 14, 2011 at 8:35 am
Dear Rodrigo,
Very outstanding job you did. But it does not compiles on D2007 which I fixed the following line, after changing this one, compiles and run perfectly.
XMLHTTPRequest := CoXMLHTTPRequest.Create;
instead of
XMLHTTPRequest := CoXMLHTTP.Create;
thanks
Muhammad Shoaib
July 16, 2013 at 9:55 am
Does this code work with the new paid API key?
July 16, 2013 at 12:17 pm
I’m sorry but I have not used the new paid API yet, so I can’t tell you if this code will work.
November 19, 2014 at 3:31 pm
It works with the paid API. I just tested it.
November 19, 2014 at 3:34 pm
Dear Rodrigo, thank you for your very constructive examples. Unfortunately, the DBXJSON example doesn’t seem to work with unicode. Example: German word “Groß” becomes “Gro?”.
Am I missing something?
December 20, 2015 at 3:33 pm
Very thanks for your post. – :-D –
June 12, 2020 at 1:23 am
These 2 units need to be added to the implementation (Delphi Seattle +) : System.JSON, System.JSONConsts
And if you look for the Google types, go directly to the last code fragment: they are defined there.