Skip to content
The Road to Delphi — Delphi, VCL, VCL Styles, UxTheme and WinAPI

Using the Google Translate API V2 (Labs) from Delphi

, , , , , ,

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:

https://www.googleapis.com/language/translate/v2?parameters

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

[sourcecode wraplines=”false” language=”text”]
{"data":{"translations":[{"translatedText":"Hola Mundo"}]}}
[/sourcecode]

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

[sourcecode wraplines=”false” language=”text”]
{"data":{"translations":[{"translatedText":"Hola a todos","detectedSourceLanguage":"en"}]}
[/sourcecode]

if you pass incorrect parameters the response will look like this

[sourcecode wraplines=”false” language=”text”]
{"error":{"errors":[{"domain":"global","reason":"invalid","message":"Invalid Value"}],"code":400,"message":"Invalid Value"}}
[/sourcecode]

some conversions between languages are not allowed by the API, in thi case you will get a response of this type

[sourcecode wraplines=”false” language=”text”]
{"error":{"errors":[{"domain":"global","reason":"badRequest","message":"Bad language pair: en|zh-TW"}],"code":400,"message":"Bad language pair: en|zh-TW"}}
[/sourcecode]

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).

[sourcecode wraplines=”false” language=”delphi”]
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;
[/sourcecode]

Using the DBXJSON unit included since Delphi 2010

[sourcecode wraplines=”false” language=”delphi”]
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;
[/sourcecode]

and finally without using JSON, a very ugly way, but works.

[sourcecode wraplines=”false” language=”delphi”]
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;
[/sourcecode]

Check the full source showing the 3 ways to access the Google Translate API, listed in this entry.

[sourcecode wraplines=”false” language=”delphi”]
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&#8217;;
GoogleTranslateUrlAuto =’https://www.googleapis.com/language/translate/v2?key=%s&target=%s&q=%s&#8217;;

{$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.
[/sourcecode]

Check this link  <a href=”http://code.google.com/apis/language/translate/terms.html&#8221; rel=”nofollow”>Google Translate API Terms of Use</a>.

19 responses

  1. 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!

  2. […] This post was mentioned on Twitter by Delphi.cz and Radek Červinka, S.Amirhossain Gtt. S.Amirhossain Gtt said: Using the Google Translate API V2 (Labs) from Delphi http://ff.im/-uH9yn […]

  3. 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?

  4. 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

    1. AmirGT, check the InternetOpen function, by the way you can make this type of questions in StackOverflow.

  5. […] this past post we use the Google translate API v2 to translate from an language to another. today will show how […]

  6. Fernando Barbi Avatar
    Fernando Barbi

    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

    1. Gracias por tus comentarios Fernando.

  7. Not work

    from portuguese to japanese, Yiddish, urdu

  8. Thank you, colegue! I have been searching this for my DLLs for some time already… :)

  9. Simon Waters Avatar
    Simon Waters

    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

  10. Muhammad Shoaib Avatar
    Muhammad Shoaib

    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

  11. Denholm Avatar
    Denholm

    Does this code work with the new paid API key?

    1. I’m sorry but I have not used the new paid API yet, so I can’t tell you if this code will work.

    2. Nikolaj Henrichsen Avatar
      Nikolaj Henrichsen

      It works with the paid API. I just tested it.

  12. Nikolaj Henrichsen Avatar
    Nikolaj Henrichsen

    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?

  13. Burhan SK-VD Avatar
    Burhan SK-VD

    Very thanks for your post. – :-D –

  14. kStarbe Avatar
    kStarbe

    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.

Leave a Reply