Jump to content
chkaufmann

Request to Google Translate API

Recommended Posts

Hi,

 

if I enter the following url in my browser, I get a result file with the name "Müller" translated to russian characters:

 

https://translate.googleapis.com/translate_a/single?client=gtx&sl=de&tl=ru&dt=t&q=Müller

 

I tried to implement that with TIdHTTP, but something is missing and I don't find the problem. Here is my code:

var
  data  : String;
  http  : TIdHTTP;
  sslIO : TIdSSLIOHandlerSocketOpenSSL;
  tmp   : TStringStream;
  url   : String;
begin
  http := TIdHTTP.Create(nil);
  http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];

  sslIO := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  sslIO.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
  sslIO.SSLOptions.Mode        := sslmUnassigned;
  sslIO.SSLOptions.VerifyMode  := [];
  sslIO.SSLOptions.VerifyDepth := 0;
  http.IOHandler := sslIO;

  url := TIdUri.UrlEncode('https://translate.googleapis.com/translate_a/single?client=gtx&sl=de&tl=ru&dt=t&q=Müller');
  tmp := TStringStream.Create;
  http.Get(url, tmp);
  data := tmp.DataString;

  tmp.Free;
  http.Free;

end;

I expect to get the following string (like in the browser):

 

[[["мельник","Müller",null,null,0]],null,"de"]

 

Can somebody tell me what is wrong in my code?

 

Christian

Share this post


Link to post
6 hours ago, chkaufmann said:

if I enter the following url in my browser, I get a result file with the name "Müller" translated to russian characters:

 

https://translate.googleapis.com/translate_a/single?client=gtx&sl=de&tl=ru&dt=t&q=Müller

 

I tried to implement that with TIdHTTP, but something is missing and I don't find the problem.

 

In general, when creating a URL by hand, I suggest NOT using TIdURI.URLEncode() on the entire URL, but instead use TIdURI.PathEncode() and TIdURI.ParamsEncode() on individual components that actually need to be encoded.

 

Also, the default encoding for TStringStream is the OS default charset, but JSON typically uses UTF-8 instead.  If you know the actual charset the server uses for the response, you could hard-code it in the TStringStream constructor.  But, it is generally better to just let TIdHTTP handle charset decoding of strings for you instead.

 

Try something more like this:

 

var
  http  : TIdHTTP;
  sslIO : TIdSSLIOHandlerSocketOpenSSL;
  url, data  : String;
begin
  http := TIdHTTP.Create(nil);
  try
    http.HTTPOptions := http.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];

    sslIO := TIdSSLIOHandlerSocketOpenSSL.Create(http);
    sslIO.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
    sslIO.SSLOptions.Mode        := sslmClient;
    sslIO.SSLOptions.VerifyMode  := [];
    sslIO.SSLOptions.VerifyDepth := 0;
    http.IOHandler := sslIO;

    url := 'https://translate.googleapis.com/translate_a/single?client=gtx&sl=de&tl=ru&dt=t&q=' + TIdURI.ParamsEncode('Müller');
    data := http.Get(url);
  finally
    http.Free;
  end;
end;

 

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post

Thanks for the corrections. However, it still doesn't work and I don't get the translated name in the answer. There must be something else that is done different by the browser.

 

Christian

Share this post


Link to post

In what way exactly does it not work?  Please show the expected and actual results.  Have you tried sniffing the HTTP traffic to see exactly what is different between TIdHTTP's traffic vs a web browser's traffic?  To see the browser's traffic (since you are using HTTPS), you can use a debugging proxy like Fiddler, or your web browser's own built-in debugger.  To see TIdHTTP's traffic, you can use a debugging proxy, or assign one of Indy's TIdLog... components to the TIdHTTP.Intercept property.

Share this post


Link to post

I had to set the Accept-Language header, now it works, at least with Russian names.

 

I wasn't aware of the TIdLog components. Good to know because my simple test did not work with Thai and Hebrew names, but I have to investigate there further first because when I paste these characters to the source code file, they look different even though my source file is UTF-8.

 

Christian

Share this post


Link to post
15 minutes ago, chkaufmann said:

I had to set the Accept-Language header, now it works, at least with Russian names.

That is odd, because the TIdHTTP.Request.AcceptLanguage property is empty by default, and according to the HTTP spec:

 

Quote

A request without any Accept-Language header field implies that the user agent will accept any language in response.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×