0

I have this code which I am trying to use to translate my website page content:

  $url = "https://translation.googleapis.com/language/translate/v2";
  $sendParamsObj = [
      "key" => "insert api key" 
      ,
      "source" => 'en-us'
      ,
      "target" => 'da-dk' 
      ,
      "q" => 'smaller amount of <strong>content</strong> to translate'
  ];                    
  $myBodyReturn = null;          
  if (true) {
    /*
      This errors: Failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
    */  
    $sendParamsStrJson = json_encode($sendParamsObj);
    $sendOptions = array(
      'http' => array(
        'method'  => 'POST',
        'content' => $sendParamsStrJson,                
        'header'=>  'Content-Type: application/json'
      )
    );                          
    $myContext = stream_context_create($sendOptions);            
    $myBodyReturn = file_get_contents($url, false, $myContext); 
  }  
  else {            
    /*
     For large text/html pieces this probably exceeds GET length (?) and erros: 
       Failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request 
    */ 
    $sendParamsQuery = http_build_query($sendParamsObj);
    $myBodyReturn = file_get_contents($url . "?" . $sendParamsQuery);                        
  }
 var_dump($myBodyReturn);          

As can be seen, if I use the top "if (true)" solution using POST and JSON I get error 403...

But if I use "else" solution building GET query this fails with error 400 for large text/HTML pieces

...

Trying something different also gives 403:

$url = "https://translation.googleapis.com/language/translate/v2";
$sendParamsArr = array(
    "key" => "my key" 
    ,
    "source" => 'en-us'
    ,
    "target" => 'da-dk' 
    ,
    "q" => 'smaller amount of <strong>content</strong> to translate'
);                                                  
$data_json = json_encode($sendParamsArr);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data_json)
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$myBodyReturn = curl_exec($ch);
$res_responsecode_page = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);                  
curl_close($ch);

...

So it appears to work when using GET (but that only supports short text pieces) but not when using POST/JSON

Since it works using GET it is probably not API key issue. Any ideas?

Tom
  • 3,587
  • 9
  • 69
  • 124
  • 1
    Try and remove the `\r\n` from the end of your content-type header. – CBroe May 11 '23 at 10:12
  • No difference. (But it is possible Google does not support POST method. But if that is the case, how does one correctly translate larger pieces of text.) – Tom May 11 '23 at 15:02
  • POST should be supported, but I don't see https://cloud.google.com/translate/docs/reference/rest/v2/translate mentioning JSON, it says "query parameters". Have you tried making an `application/x-www-form-urlencoded` request? – CBroe May 12 '23 at 05:44
  • @CBroe if you make it an answer I will accept it :) Only difference now between POST and GET version bow are POST versions return HTML tags changed, e.g. "<" becomes "u003c". I will look into that. (And of course the difference POST can translate entire pages unlike GET requests.) – Tom May 12 '23 at 06:53

3 Answers3

2

I recommend using google translate API with translate.googleapis.com to make it easier to translate without API KEY.

<?php
function translate($txt, $sourceLang, $targetLang)
{
  $url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=" . $sourceLang . "&tl=" . $targetLang . "&dt=t&q=" . urlencode($txt);
  $response = file_get_contents($url);
  $data = json_decode($response);
  $finaltext = '';
  if ($data[0]) $finaltext = '';
  for ($i = 0; $i < count($data[0]); $i++) {
    $finaltext .= $data[0][$i][0];
  };
  return $finaltext;
}

echo translate('smaller amount of <strong>content</strong> to translate', 'en', 'da');

output: mindre mængde indhold at oversætte

Jordy
  • 1,802
  • 2
  • 6
  • 25
2

POST should be supported, but I don't see https://cloud.google.com/translate/docs/reference/rest/v2/translate mentioning JSON, it says "query parameters".

Try making an application/x-www-form-urlencoded request.

return HTML tags changed, e.g. "<" becomes "u003c"

Actually \u003C, I suppose? That is what you would get with PHP's json_encode with the JSON_HEX_TAG flag set. Not sure why they would use different encoding options for GET vs POST, but after you decoded this JSON, you should get a < either way.

CBroe
  • 91,630
  • 14
  • 92
  • 150
0

It is indeed a get request and not a post request (better since it will cache queries). So it is not an API key issue if it is a valid key that you got it from the cloud console.

otm99
  • 1