The Road to Delphi

Delphi – Free Pascal – Oxygene


3 Comments

Detecting the language from a text using the Google translate API v1

UPDATE

The Google Translate API has been officially deprecated  an alternative  is the Microsoft Translator V2, check this article for more details.

 

In this past post we use the Google translate API v2 to translate from an language to another. today will show how use the current version of this API (v1) which include a nice functionality to detect the language from a given text.

This API can be accessed via JavaScript  in a web page or using a HTTP request. in the next sample i will use the second option.

Before to continue you must aware of this warning of Google.

Note: The Google Translate API must be used for user-generated translations. Automated or batched queries of any kind are strictly prohibited.

Here you can find the Terms of Service of this API.

The next code is for educational purposes only.

To detect the language from a text you must make  a request to his URI

https://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=Hello+World

As you can see the only required parameter is the encoded text to detect.

the  JSON response to this request will be something like this

{ "responseData" : { "confidence" : 0.11489271400000001,
      "isReliable" : false,
      "language" : "en"
    },
  "responseDetails" : null,
  "responseStatus" : 200
}

the responseStatus contain the result of the operation, the 200 indicate which the language from text was successfully detected.

So now we need to define a few types, functions and constants to make the work more easy.

type
  //the supported languages
  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,Unknow);

  //the string representation for the enumerated types
  const
  GoogleLanguagesStr : array[TGoogleLanguages] of string =
  ('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','Unknow');

  //The languages code to be used in HTTP request
  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','Unknow');

  //URI to translate a text using the V1 from the API
  GoogleTranslateUrl='https://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=%s';
  //URI to detect the language from a text
  GoogleLngDetectUrl='https://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=%s';

//return a stream containing the HTTP response InternetOpen
procedure WinInet_HttpGet(const Url: string;Stream:TStream);overload;
const
BuffSize = 1024*1024;
var
  hInter   : HINTERNET;
  UrlHandle: HINTERNET;
  BytesRead: DWORD;
  Buffer   : Pointer;
begin
  hInter := InternetOpen('', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(hInter) then
  begin
    Stream.Seek(0,0);
    GetMem(Buffer,BuffSize);
    try
        UrlHandle := InternetOpenUrl(hInter, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
        if Assigned(UrlHandle) then
        begin
          repeat
            InternetReadFile(UrlHandle, Buffer, BuffSize, BytesRead);
            if BytesRead>0 then
             Stream.WriteBuffer(Buffer^,BytesRead);
          until BytesRead = 0;
          InternetCloseHandle(UrlHandle);
        end;
    finally
      FreeMem(Buffer);
    end;
    InternetCloseHandle(hInter);
  end
end;

//return a string containing the HTTP response.
function WinInet_HttpGet(const Url: string): string;overload;
Var
  StringStream : TStringStream;
begin
  Result:='';
    StringStream:=TStringStream.Create('',TEncoding.UTF8);
    try
        WinInet_HttpGet(Url,StringStream);
        if StringStream.Size>0 then
        begin
          StringStream.Seek(0,0);
          Result:=StringStream.ReadString(StringStream.Size);
        end;
    finally
      StringStream.Free;
    end;
end;

And now to process the response using the DBXJSON unit

function DetectLanguage_DBXJSON(const Text:string):TGoogleLanguages;
var
  EncodedRequest: string;
  json          : TJSONObject;
  jPair         : TJSONPair;
  jValue        : TJSONValue;
  Response      : string;
  Lng           : TGoogleLanguages;
  LngStr        : string;
begin
  Result:=Unknow;
  EncodedRequest:=Format(GoogleLngDetectUrl,[HTTPEncode(Text)]);
  Response:=WinInet_HttpGet(EncodedRequest);

  if Response<>'' then
  begin
      json    := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(Response),0) as TJSONObject;
    try
      jPair   := json.Get(2);//get the responseStatus
      if jPair.JsonValue.ToString<>'200' then  //200 is all ok
        Result := Unknow
      else
      begin
        jPair  := json.Get(0);
        jValue := TJSONObject(jPair.JsonValue).Get(0).JsonValue;
        LngStr := jValue.Value;
        for lng:=Low(TGoogleLanguages) to High(TGoogleLanguages)  do
        if GoogleLanguagesArr[Lng]=LngStr then
        begin
         Result:=lng;
         exit;
        end;
      end;
    finally
       json.Free;
    end;
  end;
end;

Another alternative using the JSON superobject library

function DetectLanguage_JSONsuperobject(const Text:string):TGoogleLanguages;
var
  EncodedRequest: string;
  Response      : string;
  Lng           : TGoogleLanguages;
  LngStr        : string;
begin
  Result:=Unknow;
  EncodedRequest:=Format(GoogleLngDetectUrl,[HTTPEncode(Text)]);
  Response:=WinInet_HttpGet(EncodedRequest);
  if Response<>'' then
  begin
    if SO(Response)['responseStatus'].AsInteger<>200 then   //if responseStatus<>200 then exist a error in the response
      Result:=Unknow
    else
    begin
      LngStr:=SO(Response)['responseData.language'].AsString;
      for lng:=Low(TGoogleLanguages) to High(TGoogleLanguages)  do
      if GoogleLanguagesArr[Lng]=LngStr then
      begin
       Result:=lng;
       exit;
      end;
    end;
  end;
end;

and finally a option without JSON

function DetectLanguage_JSONLess(const Text:string):TGoogleLanguages;
const
  TagErr='{"responseData": null,';
  TagIOk='{"responseData": {"language":"';
  TagFOk='","isReliable":';
var
  EncodedRequest: string;
  Response      : string;
  Lng           : TGoogleLanguages;
  LngStr        : string;
begin
  Result:=Unknow;
  EncodedRequest:=Format(GoogleLngDetectUrl,[HTTPEncode(Text)]);
  Response:=WinInet_HttpGet(EncodedRequest);

  if Response<>'' then
  begin
    if StartsStr(TagErr,(Response)) then  //Response  Error
    begin
      Result:=Unknow
    end
    else
    begin  //Response Ok
      LngStr:=StringReplace(Response,TagIOk,'',[rfReplaceAll]);
      LngStr:=Copy(LngStr,1,Pos(TagFOk,LngStr)-1);
        for lng:=Low(TGoogleLanguages) to High(TGoogleLanguages)  do
        if GoogleLanguagesArr[Lng]=LngStr then
        begin
         Result:=lng;
         exit;
        end;
    end;
  end;
end;

To finish here i leave the full source code from a console application which show all the alternatives to decode the JSON response and as extra include the routine to translate a text using the Google translate API v1.

program GoogleAPITranslateV1;

{$APPTYPE CONSOLE}
{$DEFINE USE_SUPER_OBJECT}
{$DEFINE USE_DBXJSON}
{$DEFINE USE_JSONLess}

uses
  Windows
  ,Classes
  ,WinInet
  ,Activex
  ,HTTPApp
  ,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,Unknow);

  const
  GoogleLanguagesStr : array[TGoogleLanguages] of string =
  ('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','Unknow');

  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','Unknow');

  GoogleTranslateUrl='https://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=%s';
  //http://code.google.com/apis/language/translate/v1/using_rest_translate.html
  GoogleLngDetectUrl='https://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=%s';

procedure WinInet_HttpGet(const Url: string;Stream:TStream);overload;
const
BuffSize = 1024*1024;
var
  hInter   : HINTERNET;
  UrlHandle: HINTERNET;
  BytesRead: DWORD;
  Buffer   : Pointer;
begin
  hInter := InternetOpen('Mozilla/3.0', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(hInter) then
  begin
    Stream.Seek(0,0);
    GetMem(Buffer,BuffSize);
    try
        UrlHandle := InternetOpenUrl(hInter, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
        if Assigned(UrlHandle) then
        begin
          repeat
            InternetReadFile(UrlHandle, Buffer, BuffSize, BytesRead);
            if BytesRead>0 then
             Stream.WriteBuffer(Buffer^,BytesRead);
          until BytesRead = 0;
          InternetCloseHandle(UrlHandle);
        end;
    finally
      FreeMem(Buffer);
    end;
    InternetCloseHandle(hInter);
  end
end;

function WinInet_HttpGet(const Url: string): string;overload;
Var
  StringStream : TStringStream;
begin
  Result:='';
    StringStream:=TStringStream.Create('',TEncoding.UTF8);
    try
        WinInet_HttpGet(Url,StringStream);
        if StringStream.Size>0 then
        begin
          StringStream.Seek(0,0);
          Result:=StringStream.ReadString(StringStream.Size);
        end;
    finally
      StringStream.Free;
    end;
end;

{$IFDEF USE_SUPER_OBJECT}
function DetectLanguage_JSONsuperobject(const Text:string):TGoogleLanguages;
var
  EncodedRequest: string;
  Response      : string;
  Lng           : TGoogleLanguages;
  LngStr        : string;
begin
  Result:=Unknow;
  EncodedRequest:=Format(GoogleLngDetectUrl,[HTTPEncode(Text)]);
  Response:=WinInet_HttpGet(EncodedRequest);
  if Response<>'' then
  begin
    if SO(Response)['responseStatus'].AsInteger<>200 then   //if responseStatus<>200 then exist a error in the response
      Result:=Unknow
    else
    begin
      LngStr:=SO(Response)['responseData.language'].AsString;
      for lng:=Low(TGoogleLanguages) to High(TGoogleLanguages)  do
      if GoogleLanguagesArr[Lng]=LngStr then
      begin
       Result:=lng;
       exit;
      end;
    end;
  end;
end;

function Translate_JSONsuperobject(const Text:string;Source,Dest:TGoogleLanguages):string;
var
  EncodedRequest: string;
  Response      : string;
begin
  Result:='';
  if Source=Autodetect then
   EncodedRequest:=Format(GoogleTranslateUrl,[HTTPEncode(Text),'%7C'+GoogleLanguagesArr[Dest]])
  else
   EncodedRequest:=Format(GoogleTranslateUrl,[HTTPEncode(Text),GoogleLanguagesArr[Source]+'%7C'+GoogleLanguagesArr[Dest]]);

  Response:=WinInet_HttpGet(EncodedRequest);
  if Response<>'' then
  begin
    if SO(Response)['responseData'].AsObject=nil then   //if the first element is null then ocurrs an error
      Result:=Format('Error Code %d %s',[SO(Response)['responseStatus'].AsInteger,SO(Response)['responseDetails'].AsString])
    else
      Result:=SO(Response)['responseData.translatedText'].AsString;
  end;
end;
{$ENDIF}

{$IFDEF USE_DBXJSON}
function DetectLanguage_DBXJSON(const Text:string):TGoogleLanguages;
var
  EncodedRequest: string;
  json          : TJSONObject;
  jPair         : TJSONPair;
  jValue        : TJSONValue;
  Response      : string;
  Lng           : TGoogleLanguages;
  LngStr        : string;
begin
  Result:=Unknow;
  EncodedRequest:=Format(GoogleLngDetectUrl,[HTTPEncode(Text)]);
  Response:=WinInet_HttpGet(EncodedRequest);
  if Response<>'' then
  begin
      json    := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(Response),0) as TJSONObject;
    try
      jPair   := json.Get(2);//get the responseStatus
      if jPair.JsonValue.ToString<>'200' then  //200 is all ok
        Result := Unknow
      else
      begin
        jPair  := json.Get(0);
        jValue := TJSONObject(jPair.JsonValue).Get(0).JsonValue;
        LngStr := jValue.Value;
        for lng:=Low(TGoogleLanguages) to High(TGoogleLanguages)  do
        if GoogleLanguagesArr[Lng]=LngStr then
        begin
         Result:=lng;
         exit;
        end;
      end;
    finally
       json.Free;
    end;
  end;
end;

function Translate_DBXJSON(const Text:string;Source,Dest:TGoogleLanguages):string;
var
  EncodedRequest: string;
  json          : TJSONObject;
  jPair         : TJSONPair;
  jValue        : TJSONValue;
  Response      : string;
begin
  Result:='';
  if Source=Autodetect then
   EncodedRequest:=Format(GoogleTranslateUrl,[HTTPEncode(Text),'%7C'+GoogleLanguagesArr[Dest]])
  else
   EncodedRequest:=Format(GoogleTranslateUrl,[HTTPEncode(Text),GoogleLanguagesArr[Source]+'%7C'+GoogleLanguagesArr[Dest]]);

  Response:=WinInet_HttpGet(EncodedRequest);
  if Response<>'' then
  begin
      json    := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(Response),0) as TJSONObject;
    try
      jPair   := json.Get(2);//get the responseStatus
      if jPair.JsonValue.ToString<>'200' then  //200 is all ok
        //{"responseData": null, "responseDetails": "invalid translation language pair", "responseStatus": 400}
        Result := Format('Error Code %s message %s',[json.Get(2).JsonValue.ToString,json.Get(1).JsonValue.ToString])
      else
      begin
        jPair  := json.Get(0);
        jValue := TJSONObject(jPair.JsonValue).Get(0).JsonValue;
        Result := jValue.ToString;
      end;
    finally
       json.Free;
    end;
      Result:=HTMLDecode(Result);
  end;
end;
{$ENDIF}

{$IFDEF USE_JSONLess}
function DetectLanguage_JSONLess(const Text:string):TGoogleLanguages;
const
  TagErr='{"responseData": null,';
  TagIOk='{"responseData": {"language":"';
  TagFOk='","isReliable":';
var
  EncodedRequest: string;
  Response      : string;
  Lng           : TGoogleLanguages;
  LngStr        : string;
begin
  Result:=Unknow;
  EncodedRequest:=Format(GoogleLngDetectUrl,[HTTPEncode(Text)]);
  Response:=WinInet_HttpGet(EncodedRequest); //{"responseData": {"language":"en","isReliable":false,"confidence":0.114892714},"responseDetails": null, "responseStatus": 200}

  if Response<>'' then
  begin
    if StartsStr(TagErr,(Response)) then  //Response  Error
    begin
      Result:=Unknow
    end
    else
    begin  //Response Ok
      LngStr:=StringReplace(Response,TagIOk,'',[rfReplaceAll]);
      LngStr:=Copy(LngStr,1,Pos(TagFOk,LngStr)-1);
        for lng:=Low(TGoogleLanguages) to High(TGoogleLanguages)  do
        if GoogleLanguagesArr[Lng]=LngStr then
        begin
         Result:=lng;
         exit;
        end;
    end;
  end;
end;

function Translate_JSONLess(const Text:string;Source,Dest:TGoogleLanguages):string;
const
  TagErr='{"responseData": null,';

  TagIOk='{"responseData": {"translatedText":"';
  TagAut=',"detectedSourceLanguage":"';

  TagFOk='"}, "responseDetails":';
var
  EncodedRequest: string;
  Response      : string;
begin
  Result:='';
  if Source=Autodetect then
   EncodedRequest:=Format(GoogleTranslateUrl,[HTTPEncode(Text),'%7C'+GoogleLanguagesArr[Dest]])
  else
   EncodedRequest:=Format(GoogleTranslateUrl,[HTTPEncode(Text),GoogleLanguagesArr[Source]+'%7C'+GoogleLanguagesArr[Dest]]);

  Response:=WinInet_HttpGet(EncodedRequest);
  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:=Copy(Result,1,Pos(TagFOk,Result)-1);
      end;
    end;

    Result:=HTMLDecode(Result);
  end;
end;
{$ENDIF}

Const
 Text   ='Hello World';
 TextEn ='Hello World';
 TextEs ='Hola Mundo';
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('');

       Writeln('Detecting language Without JSON');
       Writeln('');
       Writeln(Format('language detected for "%s"  : %s',[TextEn,GoogleLanguagesStr[DetectLanguage_JSONLess(TextEn)]]));
       Writeln(Format('language detected for "%s"  : %s',[TextEs,GoogleLanguagesStr[DetectLanguage_JSONLess(TextEs)]]));
       {$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('');

       Writeln('Detecting language using the superobject library');
       Writeln('');
       Writeln(Format('language detected for "%s"  : %s',[TextEn,GoogleLanguagesStr[DetectLanguage_JSONsuperobject(TextEn)]]));
       Writeln(Format('language detected for "%s"  : %s',[TextEs,GoogleLanguagesStr[DetectLanguage_JSONsuperobject(TextEs)]]));
       {$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('');

       Writeln('Detecting language using the DBXJSON unit');
       Writeln('');
       Writeln(Format('language detected for "%s"  : %s',[TextEn,GoogleLanguagesStr[DetectLanguage_DBXJSON(TextEn)]]));
       Writeln(Format('language detected for "%s"  : %s',[TextEs,GoogleLanguagesStr[DetectLanguage_DBXJSON(TextEs)]]));
       {$ENDIF}

    finally
     CoUninitialize;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.


19 Comments

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

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