Monday, 17 October 2011

How to make Trados Studio work with Google Translate API V2

UPDATE:(1.12.2011) A plugin allowing the use of Google Translate API v2 in Studio 2009 is also available for download through the SDL OpenExchange site (MT Enhanced using Google Translate).
UPDATE:(30.11.2011) SDL published cumulative update 2 for SDL Trados Studio 2011, which introduces support for Google Translate v2. The same hotfix for SDL Trados Studio 2009 SP3 should be available in a few weeks as  CU15. Therefore, you may choose to update your Trados and then (to make things simpler) you may not need this solution any more.
UPDATE:(28.10.2011) The first version of the script did not work for languages with extended language codes consisting of more than 2 characters (e.g. Chinese: zh-CN or zh-TW).
If you had any problems with the first version which could be caused by this, now you may try the updated version which should work for all languages (supported by Google).
If you use only languages with 2-character language codes (most of them, e.g. en, de, it, fr, pl...), you may as well stay with the previous version.
[Thanks to D.S. Translation for pointing this out.]

========================================================
As you know, the Google Translate service moves from V1 to the paid version V2 as of December 1st, 2011.
However, we have already started to experience the limitations in Trados Studio 2009 or 2011 – those who use Google Translate continuously get the "quota exceeded" error and Google Translate simply refuses to work.

What can we do to make it work?

Obviously, the perfect solution would be to get a patch from SDL; however, according to rumours, they only intend to publish one as part of SP2 for Studio 2011 at the end of November.

Of course, first we have to register at https://code.google.com/apis/console/ to activate the new paid Translate API and to get our unique key.

Unfortunately, in Trados Studio there is no dialog to enter this key, so it is unusable until we get the patch from SDL.

In this situation, I found a workaround to make Studio work with the new (paid) Google Translate API V2.

How does it work?
Trados Studio uses the old V1 format to send requests to Google Translate, which looks somehow like this:

https://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=Hello,%20my%20friend!&langpair=en%7Ces

The idea is to use a free external software tool (Fiddler2) to "capture" these requests and to translate them (using a custom script) to the new V2 format, for example:

https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&source=en&target=de&q=Hello%my%20friend!

First of all, I must point out that this is rather meant to be a temporary solution until SDL releases the official plugin. This is mainly due to the fact that the program I use, Fiddler2, captures all traffic to the web. As a result, it may slow down Web browsing a bit. However, with Trados Studio it works flawlessly, so I start Fiddler2 when using Trados Studio to capture the Google Translate requests, and I close Fiddler2 when I am done with the translation. It starts and closes instantaneously, so this is not a big hassle.

I tested this solution on Windows 7 64-bit with Trados Studio 2009 and the demo version of Trados Studio 2011. However, it seems that it should work equally well in other configurations (e.g. Win 32-bit).

OK than, let's get to the point. These are the steps to make it work:

1. Register at https://code.google.com/apis/console/ (if you have not done it yet) to activate the paid Google Translate API and to get your unique key.
Important information (thanks to Glen F.): You also need to activate billing in Google after activating the API, or else you will probably later get a "Forbidden" message from Google Translate.

2. Download Fiddler2 from http://www.getfiddler.com/dl/Fiddler2Setup.exe and install it.

3. The next step is to modify the custom scripts of Fiddler2 to teach it how to modify the Google Translate requests. You can do it in two ways, depending on which method you prefer:

3a. DOWNLOAD METHOD: Download this file: CustomRules.js (right-click and choose 'Save Target As...' to save). You must make one important change in this file, e.g. using Notepad: find the text "ENTER YOUR GOOGLE API KEY HERE"  and replace it with your personal Google Translate Key (see also step 5 below). Having entered your key, save the file, then use it to overwrite the original CustomRules.js file which in Win 7 is located in the folder
C:\Users\[USERNAME]\Documents\Fiddler2\Scripts (to open this folder, you can also click on the Windows button in the bottom left of your desktop and enter exactly the following path: %userprofile%\Documents\Fiddler2\Scripts). In other versions of Windows, this path may slightly differ. If you cannot find it, try using the Windows Search function to locate the original CustomRules.js file.

One thing can be confusing:
The CustomRules.js file to modify/overwrite IS NOT the file located in the directory where the program is installed (e.g. 'C:\Program Files\...\Fiddler2\Scripts\')! This is only a backup.
You should look for the CustomRules.js file to overwrite in a working folder similar to this: 'C:\Users\<YOUR USER NAME>\My Documents\Fiddler2\Scripts\'.

After you overwrite the original file, you can go straight to step 8.

3b. COPY-AND-PASTE METHOD: If you prefer to modify the file manually instead of downloading it, continue with the following steps:
Start Fiddler2 and select Rules --> Customize Rules... from the menu:


A text file named CustomRules.js should open in Notepad.

4. Now this is the important part that requires some attention.
In this opened text file named CustomRules.js you must find the following line (you may use CTRL+F):
static function OnBeforeRequest(oSession: Session)
{
Below this line, AND BELOW THE CURLY BRACKET SIGN, copy and paste the following lines:



//CUSTOM RULES FOR TRADOS STUDIO

if (oSession.HostnameIs("ajax.googleapis.com") && oSession.PathAndQuery=="/ajax/services/language/translate") {
oSession.hostname="www.googleapis.com";
oSession.PathAndQuery="/language/translate/v2";
oSession.oRequest.headers.UriScheme = "https";
oSession.oRequest.headers.Add("X-HTTP-Method-Override", "GET");

   var sText = oSession.GetRequestBodyAsString();
   var where = sText.search(/langpair\"\r\n\r\n/);
   var temp = sText.slice(where + 13);
   var sSourceChars = temp.search(/\|/);
   var sTargetChars = temp.search(/\r/) - sSourceChars - 1;
   var sSource = sText.substr(where + 13, sSourceChars);
var sTarget = sText.substr(where + 13 + sSourceChars + 1, sTargetChars);
   var sBoundary = oSession.oRequest.headers.GetTokenValue("Content-Type", "boundary");
var sKey = "ENTER YOUR GOOGLE API KEY HERE";
var sNewText = "key\"\r\n\r\n" + sKey + "\r\n--" + sBoundary + "\r\nContent-Disposition: form-data; name=\"source\"\r\n\r\n" + sSource + "\r\n--" + sBoundary +
"\r\nContent-Disposition: form-data; name=\"target\"\r\n\r\n" + sTarget + "\r\n--" + sBoundary + "\r\nContent-Disposition: form-data; name=\"langpair\"";
sText = sText.Replace("langpair\"", sNewText);
oSession.utilSetRequestBody(sText);
}


//END OF CUSTOM RULES FOR TRADOS STUDIO


Your Notepad window should look more or less as follows:


(Text indentation does not matter.)

These pasted custom rules basically "translate" the old format of Google Translate requests into the new format (API V2) before Fiddler2 sends the request to Google.

5. One more important step without which all this will not work:
Replace the text "ENTER YOUR GOOGLE API KEY HERE" in the pasted lines with your personal Google Translate Key (you can find it on the https://code.google.com/apis/console/ site, in the API Access tab).
The key should be placed in quotation marks; the entire line should look somehow like this (just with your own key, this is only an example):

var sKey = "CParDfOPWa5he1sAorD3F_-pqDLIEHFOEaj4DaB";


6. Again,  you must find the following line in the Notepad window (you may use CTRL+F):
static function OnBeforeResponse(oSession: Session)
{
Below this line, AND BELOW THE CURLY BRACKET SIGN, copy and paste the following lines:



//CUSTOM RULES ADDED


if (oSession.HostnameIs("www.googleapis.com") && oSession.PathAndQuery=="/language/translate/v2") {
var sText2 = oSession.GetResponseBodyAsString();
sText2 = sText2.Replace("\n \"data\": {\n  \"translations\": [\n   {\n    ", "\"responseData\": {");
sText2 = sText2.Replace("\n   }\n  ]\n }\n}\n", "}, \"responseDetails\": null, \"responseStatus\": 200}");
oSession.utilSetResponseBody(sText2);
}


//END OF CUSTOM RULES


Your Notepad window should look as follows:



(This is a script to translate the response received from Google to the old format so that Trados Studio accepts it.)

7. Save the modified file (File --> Save or CTRL-S) and close the Notepad window.

8. That's it – start Trados Studio with Fiddler2 running in the background, and you should be able to use Google Translate normally (the new paid API V2 version).

NOTES:
If you get an error message, e.g. "Status = 403 (Forbidden)" or "Translation Failed: Object reference not set to an instance of an object.", please check if you have activated billing in your Google API console. Please also make sure capturing is enabled in Fiddler ("File" --> "Capture traffic" must be checked in the menu; you may have disabled it inadvertently by clicking in the left bottom corner of the program window).

Remember that Fiddler2 may slow down Web browsing a bit, so you may choose to close it when browsing and re-open it when you start to translate again. It seems that overall performance can be slightly improved by changing "All processes" to "Non-Browser" in the status bar of the program (at the bottom of the window).
Please also remember that the program can log all traffic to the Web, which may be undesirable in some circumstances (for example, someone who sits at your computer could view a password you have entered in your browser when Fiddler was running).
In the main window of the program you may review the requests Trados Studio sends to Google Translate along with the responses.

I believe this method is safe and it is well working for me.
Please remember, however, that when using this method, each request from Trados Studio will be counted for billing in your Google Translate API console. What's more, it turns out that Studio sends a request to Google Translate every time you click in the Editor window, even in a segment which is already confirmed! With this in mind, try to limit unnecessary clicking (or navigating with the keyboard) in your document to avoid generating additional costs. Of course, you can always disable Google Translate in Project Settings and then no costs are generated. You can also first "pre-translate" the entire document with Google Translate enabled, then disable it in Project Settings to finish the work "offline".

If you have any questions about this method, please feel free to contact me at trados.GT@ceti.pl. Any comments are also welcome.


15 comments:

  1. Excellent post Pawel! I followed all your clear instructions and was able to set it up in my Trados 2011. Would you allow me to share it with my community of the English-Spanish Translators Forum? (http://www.english-spanish-translator.org)

    ReplyDelete
  2. Thank you Horacio.
    Of course you can share it.

    ReplyDelete
  3. Hi Pawel!

    I tested your solution on Trados 2009 and it's not working at all (Trados 2009 on Windows XP).

    I've to change your script, maybe we can merge them.

    Here's my CustomRules.js:


    static function OnBeforeRequest(oSession: Session)
    {
    //CUSTOM RULES FOR TRADOS STUDIO
    if (oSession.HostnameIs("ajax.googleapis.com") && oSession.uriContains("/ajax/services/language/translate")) {

    var sKey = "YOUR_KEY_GOES_HERE";

    oSession.hostname="www.googleapis.com";
    var queryString = oSession.url.toLowerCase().split("?");
    var queryFields = queryString[1].split("&");
    oSession.PathAndQuery="/language/translate/v2?key="+sKey+"&";
    oSession.oRequest.headers.UriScheme = "https";
    for (var key in queryFields){
    var keyValue = queryFields[key].split("=");
    if(keyValue[0] == "q"){
    oSession.PathAndQuery = oSession.PathAndQuery+queryFields[key]+"&";
    }else if(keyValue[0] == "langpair"){
    var languages = keyValue[1].split("%7c");
    var sSource = languages[0];
    var sTarget = languages[1];
    oSession.PathAndQuery = oSession.PathAndQuery+"source="+sSource+"&target="+sTarget+"&";
    }
    }
    }
    //END OF CUSTOM RULES FOR TRADOS STUDIO


    static function OnBeforeResponse(oSession: Session)
    {

    //CUSTOM RULES FOR TRADOS STUDIO
    if (oSession.HostnameIs("www.googleapis.com") && oSession.uriContains("/language/translate/v2")) {
    var sText2 = oSession.GetResponseBodyAsString();
    sText2 = sText2.Replace("\n \"data\": {\n \"translations\": [\n {\n ", "\"responseData\": {");
    sText2 = sText2.Replace("\n }\n ]\n }\n}\n", "}, \"responseDetails\": null, \"responseStatus\": 200}");
    oSession.utilSetResponseBody(sText2);
    }
    //END OF CUSTOM RULES FOR TRADOS STUDIO

    ReplyDelete
  4. To Ariel S.:
    Thank you for your feedback.
    Your code seems much more elegant indeed.
    However, it cannot work because the requests from Trados are made using the POST method, and they actually contain more than a single line of text. Referring to your script, 'oSession.url' only contains the path, without the query (namely: 'ajax.googleapis.com/ajax/services/language/translate'), so there is nothing to split. The example requests at the top of this page are only illustratory.
    You can view what the requests actually contain in the right panel of Fiddler (e.g. in the Raw tab).

    That's why I used the GetRequestBodyAsString method, which returns a multi-line string for manipulations.

    There surely must be a more elegant solution than my script. However, since it was meant as a temporary solution and it worked for many people, I didn't strive to refine it any more.

    I understand that you activated the billing, your Google key is correct etc. Perhaps in your specific configuration the requests from Trados have a slightly different structure and that's the reason for failure? If you could send me the entire contents of the HexView or Raw tabs from Fiddler, I could compare them with mine.

    ReplyDelete
  5. Thank you Pawel! I am sure our colleagues from the forum will find it quite useful. Here's the link to that post http://www.english-spanish-translator.org/trados/12092-setting-up-new-api-google-translate-trados-2011-a.html#post51400
    Just so you know, I have already done quite a few projects and it never failed! :-)

    ReplyDelete
  6. Super work-around! Worked right away ... Thanks a million

    ReplyDelete
  7. Excellent work Pawel, thanks for sharing this!

    ReplyDelete
  8. Excellent work, Pawel! It works like a charm. Thanks.
    Found this blog via the German ProZ forum.

    ReplyDelete
  9. Haitham

    Excellent work, Pawel! It works like a charm. Thanks.Just needed to restart my computer

    ReplyDelete
  10. I confirmed it also worked with Jap.

    The object err still occurs even after installing SP3 over Trados Studio 2009.
    So, this was my last hope.

    Thx Pawel :)

    ReplyDelete
  11. Language translation is now a great area to consider for a career. In light of our growing global economy, an increasing variety of various languages are being used in business as well as in social settings. The need for individuals with the ability to translate languages is ever increasing and jobs can now be found in practically every industry imaginable for skilled translators and interpreters.

    ReplyDelete
  12. I found an offline version of Google Translate. Is there any possibility to use the offline version together with Studio 2011? A few customers don't approve the use of online Google Translate, but they can't say a thing if I use it offline. Just wonder how to make Studio use the offline version ...

    ReplyDelete
  13. Greetings, buddy.

    Can you tell me if this trick works with Trados 2014?

    This is a great post! Congratulations!

    ReplyDelete
  14. Interesting post. I Have Been wondering about this issue, so thanks for posting. Pretty cool post.It 's really very nice and Useful post.Thanks
    Translation services near me

    ReplyDelete