Using Google Translate to automate text translation

Post your working scripts, libraries and tools for AHK v1.1 and older
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Using Google Translate to automate text translation

20 Apr 2019, 19:21

For AHK v1:

Code: Select all

MsgBox, % GoogleTranslate("今日の天気はとても良いです")
MsgBox, % GoogleTranslate("Hello, World!", "en", "ru")

GoogleTranslate(str, from := "auto", to := "en") {
   static JS := CreateScriptObj(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject; delete GetObject;")
   
   json := SendRequest(JS, str, to, from, proxy := "")
   oJSON := JS.("(" . json . ")")

   if !IsObject(oJSON[1]) {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
   }
   else {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
   }
   if !IsObject(oJSON[1])
      MainTransText := trans := Trim(trans, ",+`n ")
   else
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")

   from := oJSON[2]
   trans := Trim(trans, ",+`n ")
   Return trans
}

SendRequest(JS, str, tl, sl, proxy) {
   static http
   ComObjError(false)
   if !http
   {
      http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
      ( proxy && http.SetProxy(2, proxy) )
      http.open("GET", "https://translate.google.com", true)
      http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
      http.send()
      http.WaitForResponse(-1)
   }
   http.open("POST", "https://translate.googleapis.com/translate_a/single?client=gtx"
                ; or "https://clients5.google.com/translate_a/t?client=dict-chrome-ex"
      . "&sl=" . sl . "&tl=" . tl . "&hl=" . tl
      . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1"
      . "&tk=" . JS.("tk").(str), true)

   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . URIEncode(str))
   http.WaitForResponse(-1)
   Return http.responsetext
}

URIEncode(str, encoding := "UTF-8")  {
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)

   while code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}

GetJScript()
{
   script =
   (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());

      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }

      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
   )
   Return script
}

CreateScriptObj() {
   static doc, JS, _JS
   if !doc {
      doc := ComObjCreate("htmlfile")
      doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
      JS := doc.parentWindow
      if (doc.documentMode < 9)
         JS.execScript()
      _JS := ObjBindMethod(JS, "eval")
   }
   Return _JS
}
Upd: SendRequest() was edited as @malcev advised.

For AHK v2:

Code: Select all

#Requires AutoHotkey v2

text := GoogleTranslate('今日の天気はとても良いです', &from := 'auto')
MsgBox 'from: ' . from . '`ntranslate: ' . text, 'from auto to English'

text := GoogleTranslate('test', 'en', 'fr', &variants)
MsgBox 'main translate: ' text . '`n`nvariants:`n' . variants, 'from English to French'

GoogleTranslate(str, from := 'auto', to := 'en', &variants := '') {
    static JS := ObjBindMethod(GetJsObject(), 'eval'), _ := JS(GetJScript())
    
    json := SendRequest(str, Type(from) = 'VarRef' ? %from% : from, to)
    return ExtractTranslation(json, from, &variants)

    GetJsObject() {
        static document := '', JS
        if !document {
            document := ComObject('HTMLFILE')
            document.write('<meta http-equiv="X-UA-Compatible" content="IE=9">')
            JS := document.parentWindow
            (document.documentMode < 9 && JS.execScript())
        }
        return JS
    }

    GetJScript() {
        return '
        ( Join
            var TKK="406398.2087938574";function b(r,_){for(var t=0;t<_.length-2;t+=3){var $=_.charAt(t+2),$="a"<=$?$
            .charCodeAt(0)-87:Number($),$="+"==_.charAt(t+1)?r>>>$:r<<$;r="+"==_.charAt(t)?r+$&4294967295:r^$}return r}
            function tk(r){for(var _=TKK.split("."),t=Number(_[0])||0,$=[],a=0,h=0;h<r.length;h++){var n=r.charCodeAt(h);
            128>n?$[a++]=n:(2048>n?$[a++]=n>>6|192:(55296==(64512&n)&&h+1<r.length&&56320==(64512&r.charCodeAt(h+1))?
            (n=65536+((1023&n)<<10)+(1023&r.charCodeAt(++h)),$[a++]=n>>18|240,$[a++]=n>>12&63|128):$[a++]=n>>12|224,$
            [a++]=n>>6&63|128),$[a++]=63&n|128)}for(a=0,r=t;a<$.length;a++)r+=$[a],r=b(r,"+-a^+6");return r=b(r,
            "+-3^+b+-f"),0>(r^=Number(_[1])||0)&&(r=(2147483647&r)+2147483648),(r%=1e6).toString()+"."+(r^t)}
        )'
    }

    SendRequest(str, sl, tl) {
        static WR := ''
             , headers := Map('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8',
                              'User-Agent'  , 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0')
        if !WR {
            WR := WebRequest()
            WR.Fetch('https://translate.google.com',, headers)
        }
        url := 'https://translate.googleapis.com/translate_a/single?client=gtx'
             . '&sl=' . sl . '&tl=' . tl . '&hl=' . tl
             . '&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1'
             . '&tk=' . JS('tk')(str)
        return WR.Fetch(url, 'POST', headers, 'q=' . JS('encodeURIComponent')(str))
    }

    ExtractTranslation(json, from, &variants) {
        jsObj := JS('(' . json . ')')
        if !IsObject(jsObj.1) {
            Loop jsObj.0.length {
                variants .= jsObj.0.%A_Index - 1%.0
            }
        } else {
            mainTrans := jsObj.0.0.0
            Loop jsObj.1.length {
                variants .= '`n+'
                obj := jsObj.1.%A_Index - 1%.1
                Loop obj.length {
                    txt := obj.%A_Index - 1%
                    variants .= (mainTrans = txt ? '' : '`n' . txt)
                }
            }
        }
        if !IsObject(jsObj.1)
            mainTrans := variants := Trim(variants, ',+`n ')
        else
            variants := mainTrans . '`n+`n' . Trim(variants, ',+`n ')

        (Type(from) = 'VarRef' && %from% := jsObj.8.3.0)
        return mainTrans
    }
}

class WebRequest
{
    __New() {
        this.whr := ComObject('WinHttp.WinHttpRequest.5.1')
    }

    __Delete() {
        this.whr := ''
    }

    Fetch(url, method := 'GET', HeadersMap := '', body := '', getRawData := false) {
        this.whr.Open(method, url, true)
        for name, value in HeadersMap
            this.whr.SetRequestHeader(name, value)
        this.error := ''
        this.whr.Send(body)
        this.whr.WaitForResponse()
        status := this.whr.status
        if (status != 200)
            this.error := 'HttpRequest error, status: ' . status . ' — ' . this.whr.StatusText
        SafeArray := this.whr.responseBody
        pData := NumGet(ComObjValue(SafeArray) + 8 + A_PtrSize, 'Ptr')
        length := SafeArray.MaxIndex() + 1
        if !getRawData
            res := StrGet(pData, length, 'UTF-8')
        else {
            outData := Buffer(length, 0)
            DllCall('RtlMoveMemory', 'Ptr', outData, 'Ptr', pData, 'Ptr', length)
            res := outData
        }
        return res
    }
}
Last edited by teadrinker on 18 Feb 2023, 17:44, edited 14 times in total.
Osprey
Posts: 453
Joined: 18 Nov 2017, 05:50

Re: Using Google Translate to automate text translation

20 Apr 2019, 19:39

Many thanks to teadrinker for his script.

I've slightly modified it in a few ways to suit my purposes, but also make it more adaptable for others:

1. It'll now automatically translate to the user's system language. In other words, if you don't supply any parameters to the GoogleTranslate function other than the string, it'll translate it to your Windows language, rather than to English. This makes it easier to use for non-English speakers and for people writing scripts that they want to be automatically translated for all end users.

2. If you supply the original language as the 2nd parameter and that happens to be the same as the user's system language, no attempt at translation will be performed. That improves performance by not sending unneeded translation requests to Google. So, for example, if your messages are in English, you can improve performance for yourself and other English speakers by doing GoogleTranslate("Sample text", "en").

3. If a response isn't received back from Google, it'll return the original, untranslated string. This way, your scripts won't break if there's no internet or Google's servers detect spam. Strings will just be in the script's original language until the connection is restored.

Code: Select all

; Google Translate script
; Take a string in any language and translate to any other language.
;
; Credited to teadrinker: https://www.autohotkey.com/boards/viewtopic.php?f=5&t=40876#p186877
; Slightly modified by Osprey to allow for determining and using the system language.
; Should be run with the Unicode version of AutoHotkey.
;
; Sample usage
; MsgBox, % GoogleTranslate("今日の天気はとても良いです")			; Translate string from auto-detected language to system language
; MsgBox, % GoogleTranslate("今日の天気はとても良いです", "jp", "en")	; Translate string from Japanese to English

GoogleTranslate(str, from := "auto", to := 0) {
   static JS := GetJScripObject(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject; delete GetObject;")
   
   if(!to)				; If no "to" parameter was passed
      to := GetISOLanguageCode()	; Assign the system (OS) language to "to"

   if(from = to)			; If the "from" and "to" parameters are the same
      Return str			; Abort translation and return the original string

   json := SendRequest(JS, str, to, from, proxy := "")
   if(!json or InStr(json, "document.getElementById('captcha-form')"))	; If no response (ex. internet down) or spam is detetected
     Return str				; Return the original, untranslated string
   oJSON := JS.("(" . json . ")")

   if !IsObject(oJSON[1])  {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
   }
   else  {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length  {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length  {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
   }
   if !IsObject(oJSON[1])
      MainTransText := trans := Trim(trans, ",+`n ")
   else
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")

   from := oJSON[2]
   trans := Trim(trans, ",+`n ")
   Return trans
}

; Take a 4-digit language code or (if no parameter) the current language code and return the corresponding 2-digit ISO code
GetISOLanguageCode(lang := 0) {
   LanguageCodeArray := { 0436: "af" ; Afrikaans
			, 041c: "sq" ; Albanian
			, 0401: "ar" ; Arabic_Saudi_Arabia
			, 0801: "ar" ; Arabic_Iraq
			, 0c01: "ar" ; Arabic_Egypt
			, 1001: "ar" ; Arabic_Libya
			, 1401: "ar" ; Arabic_Algeria
			, 1801: "ar" ; Arabic_Morocco
			, 1c01: "ar" ; Arabic_Tunisia
			, 2001: "ar" ; Arabic_Oman
			, 2401: "ar" ; Arabic_Yemen
			, 2801: "ar" ; Arabic_Syria
			, 2c01: "ar" ; Arabic_Jordan
			, 3001: "ar" ; Arabic_Lebanon
			, 3401: "ar" ; Arabic_Kuwait
			, 3801: "ar" ; Arabic_UAE
			, 3c01: "ar" ; Arabic_Bahrain
			, 042c: "az" ; Azeri_Latin
			, 082c: "az" ; Azeri_Cyrillic
			, 042d: "eu" ; Basque
			, 0423: "be" ; Belarusian
			, 0402: "bg" ; Bulgarian
			, 0403: "ca" ; Catalan
			, 0404: "zh-CN" ; Chinese_Taiwan
			, 0804: "zh-CN" ; Chinese_PRC
			, 0c04: "zh-CN" ; Chinese_Hong_Kong
			, 1004: "zh-CN" ; Chinese_Singapore
			, 1404: "zh-CN" ; Chinese_Macau
			, 041a: "hr" ; Croatian
			, 0405: "cs" ; Czech
			, 0406: "da" ; Danish
			, 0413: "nl" ; Dutch_Standard
			, 0813: "nl" ; Dutch_Belgian
			, 0409: "en" ; English_United_States
			, 0809: "en" ; English_United_Kingdom
			, 0c09: "en" ; English_Australian
			, 1009: "en" ; English_Canadian
			, 1409: "en" ; English_New_Zealand
			, 1809: "en" ; English_Irish
			, 1c09: "en" ; English_South_Africa
			, 2009: "en" ; English_Jamaica
			, 2409: "en" ; English_Caribbean
			, 2809: "en" ; English_Belize
			, 2c09: "en" ; English_Trinidad
			, 3009: "en" ; English_Zimbabwe
			, 3409: "en" ; English_Philippines
			, 0425: "et" ; Estonian
			, 040b: "fi" ; Finnish
			, 040c: "fr" ; French_Standard
			, 080c: "fr" ; French_Belgian
			, 0c0c: "fr" ; French_Canadian
			, 100c: "fr" ; French_Swiss
			, 140c: "fr" ; French_Luxembourg
			, 180c: "fr" ; French_Monaco
			, 0437: "ka" ; Georgian
			, 0407: "de" ; German_Standard
			, 0807: "de" ; German_Swiss
			, 0c07: "de" ; German_Austrian
			, 1007: "de" ; German_Luxembourg
			, 1407: "de" ; German_Liechtenstein
			, 0408: "el" ; Greek
			, 040d: "iw" ; Hebrew
			, 0439: "hi" ; Hindi
			, 040e: "hu" ; Hungarian
			, 040f: "is" ; Icelandic
			, 0421: "id" ; Indonesian
			, 0410: "it" ; Italian_Standard
			, 0810: "it" ; Italian_Swiss
			, 0411: "ja" ; Japanese
			, 0412: "ko" ; Korean
			, 0426: "lv" ; Latvian
			, 0427: "lt" ; Lithuanian
			, 042f: "mk" ; Macedonian
			, 043e: "ms" ; Malay_Malaysia
			, 083e: "ms" ; Malay_Brunei_Darussalam
			, 0414: "no" ; Norwegian_Bokmal
			, 0814: "no" ; Norwegian_Nynorsk
			, 0415: "pl" ; Polish
			, 0416: "pt" ; Portuguese_Brazilian
			, 0816: "pt" ; Portuguese_Standard
			, 0418: "ro" ; Romanian
			, 0419: "ru" ; Russian
			, 081a: "sr" ; Serbian_Latin
			, 0c1a: "sr" ; Serbian_Cyrillic
			, 041b: "sk" ; Slovak
			, 0424: "sl" ; Slovenian
			, 040a: "es" ; Spanish_Traditional_Sort
			, 080a: "es" ; Spanish_Mexican
			, 0c0a: "es" ; Spanish_Modern_Sort
			, 100a: "es" ; Spanish_Guatemala
			, 140a: "es" ; Spanish_Costa_Rica
			, 180a: "es" ; Spanish_Panama
			, 1c0a: "es" ; Spanish_Dominican_Republic
			, 200a: "es" ; Spanish_Venezuela
			, 240a: "es" ; Spanish_Colombia
			, 280a: "es" ; Spanish_Peru
			, 2c0a: "es" ; Spanish_Argentina
			, 300a: "es" ; Spanish_Ecuador
			, 340a: "es" ; Spanish_Chile
			, 380a: "es" ; Spanish_Uruguay
			, 3c0a: "es" ; Spanish_Paraguay
			, 400a: "es" ; Spanish_Bolivia
			, 440a: "es" ; Spanish_El_Salvador
			, 480a: "es" ; Spanish_Honduras
			, 4c0a: "es" ; Spanish_Nicaragua
			, 500a: "es" ; Spanish_Puerto_Rico
			, 0441: "sw" ; Swahili
			, 041d: "sv" ; Swedish
			, 081d: "sv" ; Swedish_Finland
			, 0449: "ta" ; Tamil
			, 041e: "th" ; Thai
			, 041f: "tr" ; Turkish
			, 0422: "uk" ; Ukrainian
			, 0420: "ur" ; Urdu
			, 042a: "vi"} ; Vietnamese
   If(lang)
     Return LanguageCodeArray[lang]
   Else Return LanguageCodeArray[A_Language]
}

SendRequest(JS, str, tl, sl, proxy) {
   ComObjError(false)
   http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   ( proxy && http.SetProxy(2, proxy) )
   http.open( "POST", "https://translate.google.com/translate_a/single?client=t&sl="
      . sl . "&tl=" . tl . "&hl=" . tl
      . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=1&ssel=3&tsel=3&pc=1&kc=2"
      . "&tk=" . JS.("tk").(str), 1 )

   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . URIEncode(str))
   http.WaitForResponse(-1)
   Return http.responsetext
}

URIEncode(str, encoding := "UTF-8")  {
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)

   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}

GetJScript()
{
   script =
   (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());

      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }

      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
   )
   Return script
}

GetJScripObject()  {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
}
Last edited by Osprey on 23 Apr 2019, 03:37, edited 1 time in total.
garry
Posts: 3740
Joined: 22 Dec 2013, 12:50

Re: Using Google Translate to automate text translation

21 Apr 2019, 13:21

thank you , teadrinker , Osprey
I tried to add a GUI to teadrinker's script / select language with DropDownList , copy text ( ctrl+c ) > see translation or also direct input in GUI

EDIT : 20210411 Example-4 select SOURCE-language also
EDIT : 20210212 Example-3 input (Edit-2) or CTRL+c ( translate marked text ( total 109 languages to select ) )
EDIT : 20210123 added all languages https://cloud.google.com/translate/docs/languages
EDIT : 20200726 Example-2 added AUDIO button


Image

Example-4 20210411 ( same as Example-1 but select also SOURCE-language )

Code: Select all

;-------- saved at 星期日 四月 2021-04-11  17:44 UTC -----------------------------
;- Using Google Translate to automate text translation 
;- https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63835
;- function from user 'teadrinker'  GoogleTranslate.ahk in folder %a_programfiles%\Autohotkey\LIB  or in script
;--------------------------
;- MODIFIED = 20210411  select also source language
;- CREATED  = 20190419
;-------------------------------------------------------------------------------
#NoEnv
;#Warn
setworkingdir,%a_scriptdir%
Gui,1:default
Gui,1: +AlwaysOnTop  
Gui,1: -DPIScale
SS_REALSIZECONTROL := 0x40
wa:=a_screenwidth,ha:=a_screenheight,xx:=100
clipboard=
cl=
transform,s,chr,32
gosub,language
Gui,1:Color,Black,Black
Gui, Font,s14 cYellow ,Lucida Console 
rssini=%a_scriptdir%\translate_20210411.ini
ifnotexist,%rssini%    ;- first run
    {
    from=auto
    to=pt      
    IniWrite,%from%, %rssini% ,FROM  ,key1
    IniWrite,%to%  , %rssini% ,TO    ,key1
    }
IniRead, sl, %rssini%,FROM ,key1
IniRead, tl, %rssini%,TO   ,key1
global sl,tl,JS
;-------------------------------
x:=(wa*.5)/xx,W :=(wa*9)/xx,H :=(ha*10)/xx,y:=(ha*.5)/xx
Gui,add,dropdownlist, x%x% y%y% w%w% vDDL1 gddl1 ,%e5x%
;-------------------------------
x:=(wa*12)/xx,W :=(wa*9)/xx,H :=(ha*10)/xx,y:=(ha*.5)/xx
Gui,add,dropdownlist, x%x% y%y% w%w% vDDL2 gddl2 ,%e5x%
;-------------------------------
x:=(wa*.5)/xx,W :=(wa*29)/xx , H :=(ha*88)/xx , y:=(ha*3.5)/xx
Gui,add,edit,x%x% y%y%  w%w% h%h% vED1  -border -E0x200,
;-------------------------------
y:=(ha*3)/xx,W :=(wa*30)/xx , H :=(ha*92)/xx,x:=(wa-w)
Gui, Show,x%x% y%y% w%w% h%h% ,TRANSLATE
;-------------------------------
GuiControl,1:Choose,ddl1,%sl%
GuiControl,1:Choose,ddl2,%tl%
GuiControl, Focus,ED1
WinID := WinExist("A")
WinSetTitle, ahk_id %WinID%,, TRANSLATE : %sl% >> %tl%
E0x200 = WS_EX_CLIENTEDGE
RETURN
;--------------------------
esc::exitapp
;--------------------------
Guiclose:
exitapp
;------- translate changed language -----
translateddlchange:
Guicontrolget,ed1
if ed1<>
{
aa:=GoogleTranslate(cl,sl,tl)      ;- translate clipboard again in other language
ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
aa=
}
return
;---------------------------------------

;---------------------------------------
ddl1:
Gui,1:submit,nohide
h1:=""
h2:=""
if DDL1<>
{
StringSplit,h,ddl1,`_
if h1<>
  {
  IniRead, tl  , %rssini% ,TO    ,key1
  IniWrite,%h1%, %rssini% ,FROM  ,key1
  sl:=h1
  WinSetTitle, ahk_id %WinID%,, TRANSLATE_FROM : %h2% >> %tl%
  gosub,translateddlchange
  }
}
return
;----------------------------------------
;----------------------------------------
ddl2:
Gui,1:submit,nohide
q1:=""
q2:=""
if DDL2<>
{
StringSplit,q,ddl2,`_
if q1<>
  {
  IniRead, sl  , %rssini% ,FROM ,key1
  IniWrite,%q1%, %rssini% ,TO   ,key1
  tl:=q1
  WinSetTitle, ahk_id %WinID%,, TRANSLATE_FROM : %sl% >> %q2%
  gosub,translateddlchange
  }
}
return
;------------------------------------------------------------
;----- ( Hotkey) CTRL+C Clipboardchange ---------------------
OnClipboardChange:
If (A_EventInfo=1)
 {
 Gui, Show,
 GuiControl, Focus,ED1
 ClipWait,
 if (!ErrorLevel)
  {
  cl:=clipboard
  aa:=GoogleTranslate(cl,sl,tl)
  ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
  aa=
  ;cl=
  ;clipboard=
  GuiControl, Focus,ED1
  }
 }
return
;-----------------------------------------
;- OR 
;------- Hotkey alt+F7 -------------------
!F7::
  send, ^c
  sleep,500
  clipwait,
  Gui, Show,
  GuiControl, Focus,ED1
 if (!ErrorLevel)
  {
  cl:=clipboard
  aa:=GoogleTranslate(cl,sl,tl)
  ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
  aa=
  GuiControl, Focus,ED1
  }
return
;--------------------------

;-----------------------------------------------------------------
;-- some examples to select 
;-https://cloud.google.com/translate/docs/languages
language:
e5x=
(Ltrim join|
auto_SOURCE
af_Afrikaans
zh-CN_China or zh (BCP-47)
zh-TW_China trad (BCP-47)
da_Danmark
nl_Nederland
en_English
fi_Finland Suomi
fr_France
fy_Fryslan
de_German
pt_Portuguese
%s%
%s%
)
return
;====================== END SCRIPT ==================================================

Example-3 / ( without Audio ) input (Edit-2) or CTRL+c ( translate marked text )

Code: Select all

;- https://www.autohotkey.com/boards/viewtopic.php?p=273621#p273621  ;- user teadrinker
;- https://www.autohotkey.com/boards/viewtopic.php?p=273678#p273678
;- translator from user teadrinker / with GUI 
;- DropDownList to select 109 languages / save in ini-file / write to logfile
;- mark text then CTRL+c  / or direct input in Edit-2
/*
modified=20210210  added Edit-2 for direct input 
modified=20200130  translate clipboard again in other language with dropdownlist (ddl1)
modified=20200129  translate when language change (ddl1) 
modified=20191019  ( teadrinker ) edited 1 time in total. 
modified=20190422  EDIT CreateScriptObj() ( teadrinker )
created =20190419  
https://cloud.google.com/translate/docs/languages
*/
;-------------------------------------------------------------------------------
#NoEnv
setworkingdir,%a_scriptdir%
tl1:=""
transform,s,chr,32
Gui,1:default
Gui,1: +AlwaysOnTop  
Gui,1: -DPIScale
SS_REALSIZECONTROL := 0x40
wa:=a_screenwidth,ha:=a_screenheight,xx:=100
clipboard=
cl=
ex:=""
transform,s,chr,32
gosub,language
F1=%a_scriptdir%\myGoogleTranslate_Logfile.txt
rssini=%a_scriptdir%\translate.ini
ifnotexist,%rssini%    ;- first run
    {
    translateto=pt     ;- portuguese predefined
    IniWrite,%translateto%, %rssini% ,Lang1  ,key1
    }
Gui,1:Color,Black,Black
Gui, Font,s14 cYellow ,Lucida Console 
IniRead, tl1, %rssini%,Lang1 ,key1
global tl1,JS

x:=(wa*.5)/xx,W :=(wa*28)/xx,H :=(ha*10)/xx,y:=(ha*.5)/xx
Gui,add,dropdownlist, x%x% y%y% w%w% vDDL1 gddl2 ,%e5x%
;-------------------------------------------------------
W :=(wa*29)/xx , H :=(ha*78)/xx , y:=(ha*3.5)/xx
Gui,add,Edit,x%x% y%y%  w%w% h%h% vED1  -border -E0x200,
;-------------------------------------------------------
W :=(wa*29)/xx , H :=(ha*8)/xx , y:=(ha*81.6)/xx
Gui,add,Edit,x%x% y%y%  w%w% h%h% vED2 ,
;-------------------------------------------------------

W :=(wa*30)/xx , H :=(ha*92)/xx  , x:=(wa-w),y:=(ha*1)/xx
Gui, Show,x%x% y%y% w%w% h%h% ,TRANSLATE
;-------------------------------------------------------
GuiControl,1:Choose,ddl1,%tl1%
GuiControl, Focus,ED2
WinID := WinExist("A")
WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%tl1%
E0x200 = WS_EX_CLIENTEDGE
gosub,ddl2
RETURN
;--------------------------
esc::exitapp
;--------------------------
Guiclose:
cl=
clipboard=
exitapp
;------------------------------------------------------
~$enter::
Gui,submit,nohide
i++
aa:=GoogleTranslate(ed2)
if (i=1)
xc:=tl1x . "`n" . ed2 . "=" . aa
else 
xc:=ed1 . "`n" . ed2 . "=" . aa
GuiControl,1:,ED1,%xc%
fileappend,%ed2%=%aa%`r`n,%f1%,utf-8
aa=
GuiControl,1:,ED2,
GuiControl, Focus,ED2
return
;------------------------------------------------------------
;----- ( Hotkey) CTRL+C Clipboardchange ---------------------
OnClipboardChange:
If (A_EventInfo=1)
 {
 Gui, Show,
 GuiControl, Focus,ED1
 ClipWait,
 if (!ErrorLevel)
  {
  cl:=clipboard
  aa:=GoogleTranslate(cl)
  GuiControl,1:,ED1,%aa%
  txnew:= RegExReplace(aa, "([.!?¿:-=] )", "$1`r`n")
  fileappend,------------------`r`n%txnew%`r`n,%f1%,utf-8
  aa=
  GuiControl, Focus,ED2
  }
 }
return
;--------------------------
;--------------------------
ddl2:
Gui,1:submit,nohide
h1:=""
h2:=""
if DDL1<>
{
StringSplit,h,ddl1,`_
if h1<>
  {
  IniWrite,%h1%, %rssini% ,Lang1  ,key1
  tl1:=h1
  WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%h2%
  gosub,translateddlchange
  tl1x:=h2
  }
}
return
;----------------------------------------
;------- translate changed language -----
translateddlchange:
Guicontrolget,ed1
if ed1<>
{
aa:=GoogleTranslate(cl)      ;- translate clipboard again in other language
GuiControl,1:Text,ED1,%aa%
aa=
}
return
;---------------------------------------
;;-------- https://www.autohotkey.com/boards/viewtopic.php?p=273621#p273621 ---
;- Last edited by teadrinker on Sat Oct 19, 2019 9:58 pm, edited 1 time in total. 
;MsgBox, % GoogleTranslate("今日の天気はとても良いです")
;MsgBox, % GoogleTranslate("Hello, World!", "en", "ru")
GoogleTranslate(str, from := "auto", to := "en")  {
   trans:=""
   static JS := CreateScriptObj(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject;delete GetObject;")
   json := SendRequest(JS, str, to, from, proxy := "")
   oJSON := JS.("(" . json . ")")
   if !IsObject(oJSON[1])  {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
   }
   else  {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length  {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length  {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
   }
   if !IsObject(oJSON[1])
      MainTransText := trans := Trim(trans, ",+`n ")
   else
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")
   from := oJSON[2]
   trans := Trim(trans, ",+`n ")
   Return trans
}
SendRequest(JS, str, tl, sl, proxy) {
   ComObjError(false)
   http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   ( proxy && http.SetProxy(2, proxy) )
   tl1=%tl1%
   ;http.open( "POST", "https://translate.google.com/translate_a/single?client=t&sl="
   ;                   "https://translate.google.com/#view=home&op=translate&client=t&sl="  ;- usual in web
   http.open( "POST", "https://translate.google.com/translate_a/single?client=webapp&sl="
      . sl . "&tl=" . tl1 . "&hl=" . tl1
      . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1"
      . "&tk=" . JS.("tk").(str), 1 )
   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . URIEncode(str))
   http.WaitForResponse(-1)
   Return http.responsetext
}
URIEncode(str, encoding := "UTF-8")  {
   urlstr:=""-
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)
   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}
GetJScript()
{
   script =
   (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());
      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }
      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
   )
   Return script
}
CreateScriptObj() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
}
;-----------------------------------------------------------------
;-- some examples to select 
;-https://cloud.google.com/translate/docs/languages
language:
e5x:=""
e5x=
(Ltrim join|
af_Afrikaans
sq_Albania
am_Amharisch
ar_Arab
hy_Armenia
az_Aserbaijan
eu_Baskisch
be_Belarus
bn_Bengal
bs_Bosnia
bg_Bulgaria
ca_Catalan
ceb_Cebuano (ISO-639-2)
zh-CN_China or zh (BCP-47)
zh-TW_China trad (BCP-47)
co_Corsica
hr_Croatia
cs_Cesko
da_Danmark
nl_Nederland
en_English
eo_Esperanto
et_Estonia
fi_Finland Suomi
fr_France
fy_Fryslan
gl_Galicia
ka_Georgia
de_German
el_Greece Elliniki
gu_Gujarati
ht_Creol Haiti
ha_Haussa
haw_Hawaii(ISO-639-2)
he_Hebräisch
iw_Hebräisch
hi_Hindi
hmn_Hmong (ISO-639-2)
hu_Hungarian Magyar
is_Iceland
ig_Igbo
id_Indonesia
ga_Irland Eire
it_Italia
ja_Japan Nippon
jv_Java
kn_Kannada
kk_Kasach
km_Khmer
rw_Kinyarwanda
ko_Korea
ku_Kurdistan
ky_Kirgisian
lo_Lao
la_Latin
lv_Lettland Latvija
lt_Litvanija Lietuva
lb_Luxemburg
mk_Mazedonia
mg_Madagascar
ms_Malaia
ml_Malayalam
mt_Malta
mi_Maori
mr_Marathi
mn_Mongolia
my_Myanmar
ne_Nepal
no_Norge
ny_Nyanja (Chichewa)
or_Odia (Oriya)
ps_Pashtun
fa_Persia
pl_Poland
pt_Portugal Brasilia
pa_Pandschabi
ro_Romania
ru_Rossija
sm_Samoa
gd_Scotia gael
sr_Serbia
st_Sesotho
sn_Shona
sd_Sindhi
si_Singhal
sk_Slovakia
sl_Slovenia
so_Somalia
es_Espana
su_Sundanesisch
sw_Swahili
sv_Sverige
tl_Tagalog (Philippines)
tg_Tadschikistan
ta_Tamil
tt_Tatar
te_Telugu
th_Thai
tr_Turkiye
tk_Turkmenistan
uk_Ukraina
ur_Urdu
ug_Uigur
uz_Uzbekistan
vi_Vietnam
cy_Wales GB
xh_Xhosa
yi_Jiddisch
yo_Yoruba
zu_Zulu
%s%
%s%
)
return
;====================== END SCRIPT ==================================================

2nd- example 20200726 ( with Audio )

Code: Select all

;-------- saved at 星期一 七月 2020-07-27  11:55 UTC --------------
;- Using Google Translate to automate text translation 
;- https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63835

;- https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63835
;- https://www.autohotkey.com/boards/viewtopic.php?f=76&t=71993 ---
;- translator from user teadrinker / with GUI 
/*
modified=20210123  modified language https://cloud.google.com/translate/docs/languages
modified=20200726  added AUDIO
modified=20200329  ( teadrinker ) edited 2 times in total.
modified=20200130  translate clipboard again in other language with dropdownlist (ddl1)
modified=20191019  ( teadrinker ) edited 1 time in total. 
modified=20190422  EDIT CreateScriptObj() ( teadrinker )
created =20190419
-select language , copy marked text ctrl+c > see translation in selected language
-click AUDIO button to hear the text
*/
;-------------------------------------------------------------------------------
#NoEnv
;#Warn
setworkingdir,%a_scriptdir%
tl1:=""
Gui,1:default
Gui,1: +AlwaysOnTop  
Gui,1: -DPIScale
SS_REALSIZECONTROL := 0x40
wa:=a_screenwidth,ha:=a_screenheight,xx:=100
clipboard=
cl=
transform,s,chr,32
gosub,language
rssini=%a_scriptdir%\translate.ini
ifnotexist,%rssini%    ;- first run
    {
    translateto=pt     ;- portuguese
    IniWrite,%translateto%, %rssini% ,Lang1  ,key1
    }
Gui,1:Color,Black,Black
Gui,1:Font,s14 cYellow ,Lucida Console 
IniRead, tl1, %rssini%,Lang1 ,key1
global tl1,JS,txt22,h1
x:=(wa*.5)/xx,W :=(wa*18)/xx,H :=(ha*10)/xx,y:=(ha*.5)/xx
Gui,add,dropdownlist, x%x% y%y% w%w% vDDL1 gddl2 ,%e5x%
x:=(wa*20)/xx,W :=(wa*8)/xx,H :=(ha*2.4)/xx,y:=(ha*.5)/xx
Gui,add,button,x%x% y%y%  w%w% h%h% gAudio,AUDIO
x:=(wa*.5)/xx,W :=(wa*29)/xx , H :=(ha*88)/xx , y:=(ha*3.5)/xx
Gui,add,edit,x%x% y%y%  w%w% h%h% vED1  -border -E0x200,
W :=(wa*30)/xx , H :=(ha*91)/xx  , x:=(wa-w),y:=(ha*2)/xx
Gui, Show,x%x% y%y% w%w% h%h% ,TRANSLATE
GuiControl,1:Choose,ddl1,%tl1%
GuiControl, Focus,ED1
WinID := WinExist("A")
WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%tl1%
E0x200 = WS_EX_CLIENTEDGE
RETURN
;--------------------------
esc::exitapp
;--------------------------
Guiclose:
cl=
clipboard=
exitapp
;-----  CTRL+C Clipboardchange ---------------------
OnClipboardChange:
If (A_EventInfo=1)
 {
 Gui, Show,
 GuiControl, Focus,ED1
 ClipWait,
 if (!ErrorLevel)
  {
  cl:=clipboard
  aa:=GoogleTranslate(cl)
  ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
  txt22:=aa
  aa=
  GuiControl, Focus,ED1
  }
 }
return
;--------------------------
;--------------------------
ddl2:
Gui,1:submit,nohide
h1:=""
h2:=""
if DDL1<>
{
StringSplit,h,ddl1,`_
if h1<>
  {
  IniWrite,%h1%, %rssini% ,Lang1  ,key1
  tl1:=h1
  WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%h2%
  gosub,translateddlchange
  }
}
return
;----------------------------------------
;------- translate changed language -----
translateddlchange:
Guicontrolget,ed1
if ed1<>
{
aa:=GoogleTranslate(cl)      ;- translate clipboard again in other language
ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
txt22:=aa
aa=
}
return
;---------------------------------------
;====================== TRANSLATE user teadrinker =============================
;-------- saved at 星期日 七月 2020-07-26  19:57 UTC --------------
;- Using Google Translate to automate text translation 
;- https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63835
;MsgBox, % GoogleTranslate("今日の天気はとても良いです")
;MsgBox, % GoogleTranslate("Hello, World!", "en", "ru")
GoogleTranslate(str, from := "auto", to := "en")  {
   trans:=""
   static JS := CreateScriptObj(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject; delete GetObject;")
   
   json := SendRequest(JS, str, to, from, proxy := "")
   oJSON := JS.("(" . json . ")")
   if !IsObject(oJSON[1])  {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
   }
   else  {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length  {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length  {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
   }
   if !IsObject(oJSON[1])
      MainTransText := trans := Trim(trans, ",+`n ")
   else
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")
   from := oJSON[2]
   trans := Trim(trans, ",+`n ")
   Return trans
}
SendRequest(JS, str, tl, sl, proxy) {
   static http
   ComObjError(false)
   if !http
   {
      http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
      ( proxy && http.SetProxy(2, proxy) )
      http.open( "get", "https://translate.google.com", 1 )
      http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
      http.send()
      http.WaitForResponse(-1)
   }
   http.open( "POST", "https://translate.google.com/translate_a/single?client=webapp&sl="
      . sl . "&tl=" . tl1 . "&hl=" . tl1
      . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1"
      . "&tk=" . JS.("tk").(str), 1 )
   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . URIEncode(str))
   http.WaitForResponse(-1)
   Return http.responsetext
}
URIEncode(str, encoding := "UTF-8")  {
   urlstr:=""
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)
   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}
GetJScript()
{
   script =
   (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());
      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }
      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
   )
   Return script
}
CreateScriptObj() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
}
;============================================================================
;=================================   AUDIO ==================================
AUDIO:
Gui,submit,nohide
global aa2,TL1,text
F1 := a_desktop . "\test.mp3"
tl1=%tl1%
;TL1:="de"
;text:="Good evening , how are you ?"
text:=txt22
;msgbox, 262208, ,LNG=`n%lng%`n---------------------`nTEXT=`n%text%
;return
aa2:= GetAudioFromGoogle(text, TL1, F1)
if (aa2<>1)
  {
  msgbox, 262208, ,AA2=%aa2%`nLanguage = "%Tl1%"
  return
  }
soundplay,%f1%
filedelete,%f1%
return
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
GetAudioFromGoogle(text,TL1, mp3filePath)  {
   url := CreateUrl(text,TL1)
   data := sendrequest2(url)
   if SubStr(data, 1, 6) = "Error!"
      Return data
   
   Return SaveDataToFile(data, mp3filePath)
}
CreateUrl(text, TL1)  {
   JS := CreateScriptObj2(), JS.( GetJscript2() )
   url := "https://translate.google.ru/translate_tts?ie=UTF-8&tl="
         . TL1 . "&total=1&idx=0&client=t&prev=input&textlen="
         . StrLen(text) . "&tk=" . JS.("tk").(text) . "&q=" . uriencode2(text)
   Return url
}
sendrequest2(url) {
   whr := ComObjCreate("Msxml2.XMLHTTP.6.0")
   whr.Open("GET", url, false)
   whr.Send()
   
   if (whr.Status != 200)
      Return "Error! Status: " . whr.Status . "`n`n" . whr.responseBody
   Return whr.responseBody
}
SaveDataToFile(data, filePath) {
   stream := ComObjCreate("ADODB.Stream")
   stream.type := 1  ; Binary data
   stream.Open
   stream.Write(data)
   stream.SaveToFile(filePath, 2)
   stream.Close
   Return true
}
;=====================================================================================
GetJscript2()
{
   script =
   (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());
      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }
      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
   )
   Return script
}
UriEncode2(str, encoding := "UTF-8")  {
   urlstr:=""
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)
   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}
CreateScriptObj2() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
}
;====================== END AUDIO ========================================
;====================== LANGUAGEs ========================================
;-- some examples to select 
;-https://cloud.google.com/translate/docs/languages
language:
e5x:=""
e5x=
(Ltrim join|
af_Afrikaans
sq_Albania
am_Amharisch
ar_Arab
hy_Armenia
az_Aserbaijan
eu_Baskisch
be_Belarus
bn_Bengal
bs_Bosnia
bg_Bulgaria
ca_Catalan
ceb_Cebuano (ISO-639-2)
zh-CN_China or zh (BCP-47)
zh-TW_China trad (BCP-47)
co_Corsica
hr_Croatia
cs_Cesko
da_Danmark
nl_Nederland
en_English
eo_Esperanto
et_Estonia
fi_Finland Suomi
fr_France
fy_Fryslan
gl_Galicia
ka_Georgia
de_German
el_Greece Elliniki
gu_Gujarati
ht_Creol Haiti
ha_Haussa
haw_Hawaii(ISO-639-2)
he_Hebräisch
iw_Hebräisch
hi_Hindi
hmn_Hmong (ISO-639-2)
hu_Hungarian Magyar
is_Iceland
ig_Igbo
id_Indonesia
ga_Irland Eire
it_Italia
ja_Japan Nippon
jv_Java
kn_Kannada
kk_Kasach
km_Khmer
rw_Kinyarwanda
ko_Korea
ku_Kurdistan
ky_Kirgisian
lo_Lao
la_Latin
lv_Lettland Latvija
lt_Litvanija Lietuva
lb_Luxemburg
mk_Mazedonia
mg_Madagascar
ms_Malaia
ml_Malayalam
mt_Malta
mi_Maori
mr_Marathi
mn_Mongolia
my_Myanmar
ne_Nepal
no_Norge
ny_Nyanja (Chichewa)
or_Odia (Oriya)
ps_Pashtun
fa_Persia
pl_Poland
pt_Portugal Brasilia
pa_Pandschabi
ro_Romania
ru_Rossija
sm_Samoa
gd_Scotia gael
sr_Serbia
st_Sesotho
sn_Shona
sd_Sindhi
si_Singhal
sk_Slovakia
sl_Slovenia
so_Somalia
es_Espana
su_Sundanesisch
sw_Swahili
sv_Sverige
tl_Tagalog (Philippines)
tg_Tadschikistan
ta_Tamil
tt_Tatar
te_Telugu
th_Thai
tr_Turkiye
tk_Turkmenistan
uk_Ukraina
ur_Urdu
ug_Uigur
uz_Uzbekistan
vi_Vietnam
cy_Wales GB
xh_Xhosa
yi_Jiddisch
yo_Yoruba
zu_Zulu
%s%
%s%
)
return
;====================== END SCRIPT ==================================================

First example :

Code: Select all

;;-------- https://www.autohotkey.com/boards/viewtopic.php?f=76&t=71993 ---
;- translator from user teadrinker / with GUI 
/*
modified=20200130  translate clipboard again in other language with dropdownlist (ddl1)
modified=20200129  warn / translate when language change (ddl1) 
modified=20191019  ( teadrinker ) edited 1 time in total. 
modified=20190422  EDIT CreateScriptObj() ( teadrinker )
created =20190419
select language , copy marked text ctrl+c > see translation in selected language
*/
;-------------------------------------------------------------------------------
#NoEnv
;#Warn
setworkingdir,%a_scriptdir%
tl1:=""
Gui,1:default
Gui,1: +AlwaysOnTop  
Gui,1: -DPIScale
SS_REALSIZECONTROL := 0x40
wa:=a_screenwidth
ha:=a_screenheight
xx:=100
clipboard=
cl=
ex:=""
transform,s,chr,32
gosub,language
rssini=%a_scriptdir%\translate.ini
ifnotexist,%rssini%    ;- first run
    {
    translateto=pt     ;- portuguese
    IniWrite,%translateto%, %rssini% ,Lang1  ,key1
    }
Gui,1:Color,Black,Black
Gui, Font,s14 cYellow ,Lucida Console 
IniRead, tl1, %rssini%,Lang1 ,key1
global tl1,JS

x:=(wa*.5)/xx,W :=(wa*28)/xx,H :=(ha*10)/xx,y:=(ha*.5)/xx
Gui,add,dropdownlist, x%x% y%y% w%w% vDDL1 gddl2 ,%e5x%
W :=(wa*29)/xx , H :=(ha*88)/xx , y:=(ha*3.5)/xx
Gui,add,edit,x%x% y%y%  w%w% h%h% vED1  -border -E0x200,
W :=(wa*30)/xx , H :=(ha*92)/xx  , x:=(wa-w),y:=(ha*1)/xx
Gui, Show,x%x% y%y% w%w% h%h% ,TRANSLATE
GuiControl,1:Choose,ddl1,%tl1%
GuiControl, Focus,ED1
WinID := WinExist("A")
WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%tl1%
E0x200 = WS_EX_CLIENTEDGE
RETURN
;--------------------------
esc::exitapp
;--------------------------
Guiclose:
cl=
clipboard=
exitapp
/*
;------- Hotkey alt+F7 -------------------
!F7::
  send, ^c
  sleep,500
  clipwait,
  Gui, Show,
  GuiControl, Focus,ED1
 if (!ErrorLevel)
  {
  cl:=clipboard
  aa:=GoogleTranslate(cl)
  ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
  aa=
  ;cl=
  ;clipboard=
  GuiControl, Focus,ED1
  }
return
;--------------------------
*/
;-------------- OR : ------
;/*
;----- ( Hotkey) CTRL+C Clipboardchange ---------------------
OnClipboardChange:
If (A_EventInfo=1)
 {
 Gui, Show,
 GuiControl, Focus,ED1
 ClipWait,
 if (!ErrorLevel)
  {
  cl:=clipboard
  aa:=GoogleTranslate(cl)
  ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
  aa=
  ;cl=
  ;clipboard=
  GuiControl, Focus,ED1
  }
 }
return
;--------------------------
;*/
;--------------------------
ddl2:
Gui,1:submit,nohide
h1:=""
h2:=""
if DDL1<>
{
StringSplit,h,ddl1,`_
if h1<>
  {
  IniWrite,%h1%, %rssini% ,Lang1  ,key1
  tl1:=h1
  WinSetTitle, ahk_id %WinID%,, TRANSLATE_to_%h2%
  gosub,translateddlchange
  }
}
return
;----------------------------------------
;------- translate changed language -----
translateddlchange:
Guicontrolget,ed1
;stringreplace,ed1,ed1,`n,`r`n,all
if ed1<>
{
aa:=GoogleTranslate(cl)      ;- translate clipboard again in other language
;aa:=GoogleTranslate(ed1)     ;- translate EDIT            in other language
;ControlSetText,edit1,%aa%`r`n--------------------------`r`n%a2%, ahk_class AutoHotkeyGUI
ControlSetText,edit1,%aa%, ahk_class AutoHotkeyGUI
aa=
;a2=
}
return
;---------------------------------------
;;-------- https://www.autohotkey.com/boards/viewtopic.php?p=273621#p273621 ---
;- Last edited by teadrinker on Sat Oct 19, 2019 9:58 pm, edited 1 time in total. 
;MsgBox, % GoogleTranslate("今日の天気はとても良いです")
;MsgBox, % GoogleTranslate("Hello, World!", "en", "ru")
GoogleTranslate(str, from := "auto", to := "en")  {
   trans:=""
   static JS := CreateScriptObj(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject;delete GetObject;")
   json := SendRequest(JS, str, to, from, proxy := "")
   oJSON := JS.("(" . json . ")")
   if !IsObject(oJSON[1])  {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
   }
   else  {
      MainTransText := oJSON[0][0][0]
      Loop % oJSON[1].length  {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length  {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
   }
   if !IsObject(oJSON[1])
      MainTransText := trans := Trim(trans, ",+`n ")
   else
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")
   from := oJSON[2]
   trans := Trim(trans, ",+`n ")
   Return trans
}
SendRequest(JS, str, tl, sl, proxy) {
   ComObjError(false)
   http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   ( proxy && http.SetProxy(2, proxy) )
   tl1=%tl1%
   ;http.open( "POST", "https://translate.google.com/translate_a/single?client=t&sl="
   ;                   "https://translate.google.com/#view=home&op=translate&client=t&sl="  ;- usual in web
   http.open( "POST", "https://translate.google.com/translate_a/single?client=webapp&sl="
      . sl . "&tl=" . tl1 . "&hl=" . tl1
      . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1"
      . "&tk=" . JS.("tk").(str), 1 )
   http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
   http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
   http.send("q=" . URIEncode(str))
   http.WaitForResponse(-1)
   Return http.responsetext
}
URIEncode(str, encoding := "UTF-8")  {
   urlstr:=""-
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)
   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}
GetJScript()
{
   script =
   (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());
      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }
      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
   )
   Return script
}
CreateScriptObj() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
}
;-----------------------------------------------------------------
;-- some examples to select 
;-https://cloud.google.com/translate/docs/languages
language:
e5x:=""
e5x=
(Ltrim join|
af_Afrikaans
sq_Albania
am_Amharisch
ar_Arab
hy_Armenia
az_Aserbaijan
eu_Baskisch
be_Belarus
bn_Bengal
bs_Bosnia
bg_Bulgaria
ca_Catalan
ceb_Cebuano (ISO-639-2)
zh-CN_China or zh (BCP-47)
zh-TW_China trad (BCP-47)
co_Corsica
hr_Croatia
cs_Cesko
da_Danmark
nl_Nederland
en_English
eo_Esperanto
et_Estonia
fi_Finland Suomi
fr_France
fy_Fryslan
gl_Galicia
ka_Georgia
de_German
el_Greece Elliniki
gu_Gujarati
ht_Creol Haiti
ha_Haussa
haw_Hawaii(ISO-639-2)
he_Hebräisch
iw_Hebräisch
hi_Hindi
hmn_Hmong (ISO-639-2)
hu_Hungarian Magyar
is_Iceland
ig_Igbo
id_Indonesia
ga_Irland Eire
it_Italia
ja_Japan Nippon
jv_Java
kn_Kannada
kk_Kasach
km_Khmer
rw_Kinyarwanda
ko_Korea
ku_Kurdistan
ky_Kirgisian
lo_Lao
la_Latin
lv_Lettland Latvija
lt_Litvanija Lietuva
lb_Luxemburg
mk_Mazedonia
mg_Madagascar
ms_Malaia
ml_Malayalam
mt_Malta
mi_Maori
mr_Marathi
mn_Mongolia
my_Myanmar
ne_Nepal
no_Norge
ny_Nyanja (Chichewa)
or_Odia (Oriya)
ps_Pashtun
fa_Persia
pl_Poland
pt_Portugal Brasilia
pa_Pandschabi
ro_Romania
ru_Rossija
sm_Samoa
gd_Scotia gael
sr_Serbia
st_Sesotho
sn_Shona
sd_Sindhi
si_Singhal
sk_Slovakia
sl_Slovenia
so_Somalia
es_Espana
su_Sundanesisch
sw_Swahili
sv_Sverige
tl_Tagalog (Philippines)
tg_Tadschikistan
ta_Tamil
tt_Tatar
te_Telugu
th_Thai
tr_Turkiye
tk_Turkmenistan
uk_Ukraina
ur_Urdu
ug_Uigur
uz_Uzbekistan
vi_Vietnam
cy_Wales GB
xh_Xhosa
yi_Jiddisch
yo_Yoruba
zu_Zulu
%s%
%s%
)
return

;====================== END SCRIPT ==================================================


Last edited by garry on 11 Apr 2021, 16:04, edited 12 times in total.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: Using Google Translate to automate text translation

21 Apr 2019, 16:22

Isn't Google going to block the app if one uses it often?

It's a very nice script and idea, but I'm worried that it will get blocked.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
User avatar
DuyMinh
Posts: 40
Joined: 05 May 2017, 08:34

Re: Using Google Translate to automate text translation

22 Apr 2019, 02:46

robodesign wrote:
21 Apr 2019, 16:22
Isn't Google going to block the app if one uses it often?

It's a very nice script and idea, but I'm worried that it will get blocked.
No, it just a function get tk param when request unless google change their code.
But JScript can run corretly in some computer...
Use htmlfile object will run as well.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Using Google Translate to automate text translation

22 Apr 2019, 05:29

Osprey, garry, I need to make some clarifications. In this version of the script I changed CreateScriptObj() function from

Code: Select all

GetJScripObject()  {
   VarSetCapacity(tmpFile, (MAX_PATH := 260) << !!A_IsUnicode, 0)
   DllCall("GetTempFileName", Str, A_Temp, Str, "AHK", UInt, 0, Str, tmpFile)
   
   FileAppend,
   (
   <component>
   <public><method name='eval'/></public>
   <script language='JScript'></script>
   </component>
   ), % tmpFile
   
   JS := ObjBindMethod( ComObjGet("script:" . tmpFile), "eval" )
   FileDelete, % tmpFile
   Return JS
}
to

Code: Select all

CreateScriptObj() {
   static doc
   doc := ComObjCreate("htmlfile")
   doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
   Return ObjBindMethod(doc.parentWindow, "eval")
}
since first one needs a temp file. However, last one is more "heavy" since com-object "htmlfile" is created there. You could use what you prefer. Also lexikos'th ActiveScript could be used here instead.
garry
Posts: 3740
Joined: 22 Dec 2013, 12:50

Re: Using Google Translate to automate text translation

22 Apr 2019, 06:52

@teadrinker, thank you , modified script above ( maybe check it )
Osprey
Posts: 453
Joined: 18 Nov 2017, 05:50

Re: Using Google Translate to automate text translation

23 Apr 2019, 03:48

robodesign wrote:
21 Apr 2019, 16:22
Isn't Google going to block the app if one uses it often?

It's a very nice script and idea, but I'm worried that it will get blocked.
Yes, I've already had this happen. That's why, in my version above, I added a simple condition to detect when the script was getting blocked and, in those cases, return the untranslated string (because, otherwise, a blank string was being returned). The block is only a temporary one on your IP, but it's a good reason to not over-use the function in your scripts so that you don't trigger it. By my estimation, it took sending hundreds or even thousands of translation requests in the span of just a few minutes for me to trigger the block, so more reasonable usage in scripts may be perfectly safe.
teadrinker wrote:
22 Apr 2019, 05:29
Osprey, garry, I need to make some clarifications. In this version of the script I changed CreateScriptObj() function from
I've updated my post above. Thanks.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: Using Google Translate to automate text translation

23 Apr 2019, 08:38

Thank you very much for your detailed response.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
garry
Posts: 3740
Joined: 22 Dec 2013, 12:50

Re: Using Google Translate to automate text translation

23 Apr 2019, 14:07

I tried to make a newsreader using translate script
Image
User avatar
Klark92
Posts: 161
Joined: 18 Jan 2015, 19:33

Re: Using Google Translate to automate text translation

23 Apr 2019, 15:47

Thanks! Very handy script. I did it with browser automation before. It was fast too. What do you think about the "tk" token system. Can you guess how long they dont change it :) ?
Smart Kombo 1.0 | One of the best Knight Online's key combo program...
Bluscream
Posts: 15
Joined: 10 Jan 2017, 23:12
Contact:

Re: Using Google Translate to automate text translation

19 Sep 2019, 21:46

I made yet another version of it:
Translate.ahk:

Code: Select all

;;-------- https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63835 ---
;- from user teadrinker
/*
modified=20190422  EDIT CreateScriptObj() ( teadrinker )
created =20190419
select language , copy marked text ctrl+c > see translation in selected language
*/
;-------------------------------------------------------------------------------

#Include <translate>

#SingleInstance, Force

setworkingdir,%a_scriptdir%
; SS_REALSIZECONTROL := 0x40
; Gui,1:Color,Black,Black
; Gui, Font,s12 cYellow ,Lucida Console 
cl=
ex:=""
transform,s,chr,32
global lang_list
gosub,language

global ui_from_lang := "auto_Automatic"
global ui_to_lang := "en_English"
global WinID
CreateUI()
;Gui, Show,x10 y10 w1150 h600 minimize,TRANSLATE
RefreshTitle()
RETURN

RefreshTitle() {
    langs := GetLanguages()
    ; MsgBox, % langs
    WinSetTitle, ahk_id %WinID%,, % "Translate from " . langs[2] . " to " . langs[4]
}

GetLanguages() {
    arr := StrSplit(ui_from_lang, "_")
    arr2 := StrSplit(ui_to_lang, "_")
    arr.push(arr2*)
    return arr
}

CreateUI() {
; Gui,1: +AlwaysOnTop  
Gui,1: -DPIScale

global ui_textbox
global OnFromLanguageChanged
global OnToLanguageChanged
global ui_text_url

Gui Add, Edit,          x0      y0  w647    h21 vui_text_url -vscroll +Border +ReadOnly
Gui Add, Text,          x8      y32 w30     h23 +0x200, From:
Gui Add, DropDownList,  x48     y32 w120        vui_from_lang gOnFromLanguageChanged,%lang_list%
Gui Add, Text,          x176    y32 w23     h23 +0x200, To:
Gui Add, DropDownList,  x208    y32 w120        vui_to_lang gOnToLanguageChanged,%lang_list%
Gui Add, Button,        x338    y32 w50     h20 gOnButtonTranslateClicked, Translate

Gui Add, Edit, x8 y72 w628 h419 vui_textbox +Border

Gui Show, x10 y10 w646 h502, Translate Text
GuiControl,ChooseString,ui_to_lang,%ui_to_lang%
GuiControl,ChooseString,ui_from_lang,%ui_from_lang%


ControlSetText, %ui_textbox%, "vui_textbox"

ControlSetText, %ui_text_url%, "vui_text_url"

GuiControl, Focus,ui_textbox

WinID := WinExist("A")
}
;--------------------------


OnButtonTranslateClicked:
 Gui, Show,
 guiControlGet, cl,, ui_textbox
 langs := GetLanguages()
 aa := GoogleTranslate(cl, langs[1], langs[3])
 ControlSetText,edit1, % aa[3], ahk_class AutoHotkeyGUI
 ControlSetText,edit2, % aa[1], ahk_class AutoHotkeyGUI
 aa=
 cl=
return
;--------------------------
OnToLanguageChanged:
Gui,1:submit,nohide
RefreshTitle()
return
;----------------------------------------
;--------------------------
OnFromLanguageChanged:
Gui,1:submit,nohide
RefreshTitle()
return
;----------------------------------------

language:
lang_list:=""
lang_list=
(Ltrim join|
auto_Automatic
nl_Nederlands
af_Suid-Afrika
fy_Fryslân
eu_Basque
ca_Catalan
de_Deutsch
da_Dansk
sv_Sverige
no_Norge
is_Iceland
fi_Suomen
en_English
pt_Portugues
es_Español
it_Italia
fr_Français
ru_Rossija
zh-CN_Chinese
ja_Nippon
ko_Korea
ro_Romania
bg_Bulgaria
mc_Macedonia
el_Greek
tr_Turkiye
sq_Albania
hr_Croatia
sr_Serbia
sl_Slovenia
hu_Hungary
cs_Czech
sk_Slovakia
pl_Poland
be_Belarus
uk_Ukraina
et_Estonia
lv_Latvija
lt_Lituania
az_Azerbaijan 
ka_Georgian
ar_Arabic
iw_Hebrew
hi_Hindi
id_Indonesia
ms_Malaysia
vi_Vietnam
th_Thai
ta_Tamil
ur_Urdu
sw_Swahili
%s%
)
return
;====================== END SCRIPT ==================================================
translate.ahk

Code: Select all

GoogleTranslate(str, from := "auto", to := 0) {
    ret := Array(str, "Unknown Error", "")
    static JS := GetJScripObject(), _ := JS.( GetJScript() ) := JS.("delete ActiveXObject; delete GetObject;")
    if(!to){
        to := GetISOLanguageCode()	; Assign the system (OS) language to "to"
    }

    if(from = to) {
        ret.InsertAt(2, "Target language matches source language")
        Return ret
    }

    request := SendRequest(JS, str, from, to, proxy := "")
    response := request[1]
    url := request[2]
    json := response.responsetext
    if(!json) {
        ret.InsertAt(2, response.status . ": " . response.statustext)
        ret.InsertAt(3, url)
        Return ret				; Return the original, untranslated string
    }
    if(InStr(json, "document.getElementById('captcha-form')")){
        ret.InsertAt(2, "Spam detected")
        ret.InsertAt(3, url)
        Return ret
    }
    oJSON := JS.("(" . json . ")")
    trans:=""
    if !IsObject(oJSON[1])  {
      Loop % oJSON[0].length
         trans .= oJSON[0][A_Index - 1][0]
    }
    else  {
      MainTransText := oJSON[0][0][0]
      trans:=""
      Loop % oJSON[1].length  {
         trans .= "`n+"
         obj := oJSON[1][A_Index-1][1]
         Loop % obj.length  {
            txt := obj[A_Index - 1]
            trans .= (MainTransText = txt ? "" : "`n" txt)
         }
      }
    }
    if(!IsObject(oJSON[1])){
      MainTransText := trans := Trim(trans, ",+`n ")
    } else {
      trans := MainTransText . "`n+`n" . Trim(trans, ",+`n ")
    }
    ; from := oJSON[2]
    trans := Trim(trans, ",+`n ")
   
    ret.InsertAt(1, trans)
    ret.InsertAt(2, "Success")
    ret.InsertAt(3, url)
    Return ret
}

SendRequest(JS, str, from_lang, to_lang, proxy) {
    url := "https translate.google.com /translate_a/single?client=webapp"  Broken Link for safety
      . "&sl=" . from_lang . "&tl=" . to_lang . "&hl=" . to_lang . "&tk=" . JS.("tk").(str) . "&q=" . URIEncode(str)
      . "&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=gt&ie=UTF-8&oe=UTF-8&otf=1&ssel=0&tsel=0&kc=1"
    ComObjError(false)
    http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
    ; http.SetProxy(2, proxy)
    http.open( "GET", url, 1 )
    ; http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
    http.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0")
    http.SetRequestHeader("Host", "translate.google.com")
    http.SetRequestHeader("Referer", "https translate.google.com /")  Broken Link for safety
    http.send() ; "q=" . URIEncode(str))
    http.WaitForResponse(-1)
    Return Array(http,url)
}

URIEncode(str, encoding := "UTF-8") {
    VarSetCapacity(var, StrPut(str, encoding))
    StrPut(str, &var, encoding)
    urlstr:=""
    While code := NumGet(Var, A_Index - 1, "UChar")  {
        bool := (code > 0x7F || code < 0x30 || code = 0x3D)
        UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
    }
    Return UrlStr
}

GetJScript() {
    script =
    (
      var TKK = ((function() {
        var a = 561666268;
        var b = 1526272306;
        return 406398 + '.' + (a + b);
      })());
      function b(a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
      }
      function tk(a) {
          for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
              var c = a.charCodeAt(f);
              128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
              (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240,
              g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
          }
          a = h;
          for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
          a = b(a, "+-3^+b+-f");
          a ^= Number(e[1]) || 0;
          0 > a && (a = (a & 2147483647) + 2147483648);
          a `%= 1E6;
          return a.toString() + "." + (a ^ h)
      }
    )
    Return script
}

GetJScripObject()  {
    static doc
    doc := ComObjCreate("htmlfile")
    doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'>")
    Return ObjBindMethod(doc.parentWindow, "eval")
}

GetISOLanguageCode(lang := 0) {
   LanguageCodeArray := { 0436: "af", 041c: "sq", 0401: "ar", 0801: "ar", 0c01: "ar", 1001: "ar", 1401: "ar", 1801: "ar", 1c01: "ar", 2001: "ar", 2401: "ar", 2801: "ar", 2c01: "ar", 3001: "ar", 3401: "ar", 3801: "ar", 3c01: "ar", 042c: "az", 082c: "az", 042d: "eu", 0423: "be", 0402: "bg", 0403: "ca", 0404: "zh-CN", 0804: "zh-CN", 0c04: "zh-CN", 1004: "zh-CN", 1404: "zh-CN", 041a: "hr", 0405: "cs", 0406: "da", 0413: "nl", 0813: "nl", 0409: "en", 0809: "en", 0c09: "en", 1009: "en", 1409: "en", 1809: "en", 1c09: "en", 2009: "en", 2409: "en", 2809: "en", 2c09: "en", 3009: "en", 3409: "en", 0425: "et", 040b: "fi", 040c: "fr", 080c: "fr", 0c0c: "fr", 100c: "fr", 140c: "fr", 180c: "fr", 0437: "ka", 0407: "de", 0807: "de", 0c07: "de", 1007: "de", 1407: "de", 0408: "el", 040d: "iw", 0439: "hi", 040e: "hu", 040f: "is", 0421: "id", 0410: "it", 0810: "it", 0411: "ja", 0412: "ko", 0426: "lv", 0427: "lt", 042f: "mk", 043e: "ms", 083e: "ms", 0414: "no", 0814: "no", 0415: "pl", 0416: "pt", 0816: "pt", 0418: "ro", 0419: "ru", 081a: "sr", 0c1a: "sr", 041b: "sk", 0424: "sl", 040a: "es", 080a: "es", 0c0a: "es", 100a: "es", 140a: "es", 180a: "es", 1c0a: "es", 200a: "es", 240a: "es", 280a: "es", 2c0a: "es", 300a: "es", 340a: "es", 380a: "es", 3c0a: "es", 400a: "es", 440a: "es", 480a: "es", 4c0a: "es", 500a: "es", 0441: "sw", 041d: "sv", 081d: "sv", 0449: "ta", 041e: "th", 041f: "tr", 0422: "uk", 0420: "ur", 042a: "vi" }
   if(lang) {
       return LanguageCodeArray[lang]
   } else {
    return LanguageCodeArray[A_Language]
   }
}
Bluscream
Posts: 15
Joined: 10 Jan 2017, 23:12
Contact:

Re: Using Google Translate to automate text translation

20 Sep 2019, 00:00

Code: Select all

#SingleInstance Force

#Include <translate>
#Include <obj2str>
#Include <bluscream>

#t::
    translateActiveWindow()
    Return

translateActiveWindow(){
    WinGetActiveTitle, win_title
    ; WinGetClass, win_class, win_title
    WinGet, win_id, ID, A
    ; title := win_title . " ahk_class " . win_class . " ahk_id " . win_id
    title := "ahk_id " . win_id
    ; MsgBox, % title
    WinGet, win_cntrls, ControlList, A
    cntrl_texts := Object()
    msg := "Active Window: " . win_title . "`n" ; todo: remove
    Loop,Parse,win_cntrls,`n
    {
        txt := getText(title, A_LoopField)
        msg .= "Index: " . A_Index . " Field: " . A_LoopField . " Text: " . txt . "`n" ; todo: remove
        txt := Trim(txt)
        if (txt) {
            cntrl_texts[A_LoopField] := txt
        }
    }
    ; MsgBox % msg ; todo: remove
    cntrl_texts_len := cntrl_texts.GetCapacity()
    if (!cntrl_texts_len){
        MsgBox,, % win_title, % "Found nothing to translate"
        return
    }
    totranslate := ""
    trseperator := " ``´`` "
    For cntrl, value in cntrl_texts
        totranslate .= value . trseperator
    if (!totranslate){
        MsgBox,, % win_title, % "No Text to translate"
        return
    }
    MsgBox % totranslate
    trresult := GoogleTranslate(totranslate)
    if (!trresult){
        MsgBox,, % win_title, % "Error while translating!"
        return
    }
    ; MsgBox % trresult
    cntrl_translated := StrSplit(trresult[1], trseperator)
    cntrl_texts_translated := ObjFullyClone(cntrl_texts)
    For cntrl, value in cntrl_texts
        cntrl_texts_translated[cntrl] = cntrl_translated[A_Index]
    MsgBox % obj2str(cntrl_texts) . "`n`n" . obj2str(cntrl_texts_translated) . "`n`n" . trresult[4]
    For cntrl, value in cntrl_texts_translated
        setText(title, cntrl, value)
}

getText(window, cntrl) {
    static WM_GETTEXTLENGTH := 0xE , WM_GETTEXT := 0xD
    SendMessage, WM_GETTEXTLENGTH, 0, 0,, % window
    len := ErrorLevel
    VarSetCapacity(txt, len*(A_IsUnicode ? 2 : 1)+1, 0)
    SendMessage, WM_GETTEXT, len+1, &txt, % cntrl, % window
    return txt
}
setText(window, cntrl, txt) {
    ; static WM_SETTEXT := 0x0C 
    ; SendMessage, WM_SETTEXT, 0, % txt, % cntrl, % window
    ControlSetText, % cntrl, % txt, % window
    ; MsgBox, % "Set " . cntrl . " to " . txt
}

ObjFullyClone(obj) {
	nobj := obj.Clone()
	for k,v in nobj
		if IsObject(v)
			nobj[k] := A_ThisFunc.(v)
	return nobj
}
debug stuff
User avatar
kunkel321
Posts: 974
Joined: 30 Nov 2015, 21:19

Re: Using Google Translate to automate text translation

20 Sep 2019, 14:02

Hi, I just wanted to comment. This code looks similar to teadrinker's code here: https://www.autohotkey.com/boards/viewtopic.php?f=5&t=40876
The little tool I made from it has worked FLAWLESSLY. Over the last two years I've translated dozens of things and there has never been a problem.
Good stuff !!! :ugeek:
ste(phen|ve) kunkel
Bullex
Posts: 11
Joined: 25 Dec 2015, 09:23

Re: Using Google Translate to automate text translation

16 Oct 2019, 12:15

The Script provided by teadrinker is working nicely to collect the Google translation. The only problem is, the collected translation is NOT same as the translation provided by the Google translate webpage (https translate.google.com /#view=home&op=translate&sl=en&tl=bn&text=Hello%20world) which is of much higher quality than the translation collected by this script. Is there any way to modify this script so that it collects the same translation provided by the Google translate webpage?
Last edited by Bullex on 17 Oct 2019, 08:09, edited 2 times in total.
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Using Google Translate to automate text translation

16 Oct 2019, 13:53

Interesting, this topic remind me of this Proof of concept script I wrote a long time ago:
https://www.autohotkey.com/boards/viewtopic.php?p=20609#p20609

But it doesn't work anymore... :p
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Using Google Translate to automate text translation

19 Oct 2019, 16:59

I fixed the obsolete parameters in the http request, the script is edited.
Bullex
Posts: 11
Joined: 25 Dec 2015, 09:23

Re: Using Google Translate to automate text translation

21 Oct 2019, 09:00

teadrinker wrote:
19 Oct 2019, 16:59
I fixed the obsolete parameters in the http request, the script is edited.
Hi teadrinker,

You are my hero, Man! You did it perfectly. Thanks a Million for all your help! I really appreciate it.

THANK YOU!
r2997790
Posts: 71
Joined: 02 Feb 2017, 02:46

Re: Using Google Translate to automate text translation

27 Feb 2020, 07:04

I'm loving the speed of this rountine. I had one question and one suggestion related to the script.

Is it possible to set 'detect language' for the input language?
and
I think it would be great to add a feature to the function to toggle on or off the 'extended' translation, ie. where a prefered translation is given with alternates.

This is such an improvement on the Tesseract library. Thank you!

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: gwarble, JoeWinograd and 126 guests