Smart Translate with DeepL API

Translate selected text into another language using the DeepL API.

  1. // ==UserScript==
  2. // @license MIT
  3. // @name Smart Translate with DeepL API
  4. // @namespace http://tampermonkey.net/
  5. // @version 1.3.0
  6. // @description Translate selected text into another language using the DeepL API.
  7. // @author Twil3akine
  8. // @match *://*/*
  9. // @match file:///*
  10. // @match ftp://*/*
  11. // @include myapp://*
  12. // @connect *
  13. // @grant GM_xmlhttpRequest
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // ==/UserScript==
  17.  
  18. (function () {
  19. 'use strict';
  20.  
  21. // APIキーを取得または保存
  22. const getApiKey = async () => {
  23. let apiKey = await GM_getValue('DEEPL_API_KEY', null);
  24. if (!apiKey) {
  25. apiKey = prompt('Enter your DeepL API key:');
  26. if (apiKey) {
  27. await GM_setValue('DEEPL_API_KEY', apiKey);
  28. } else {
  29. alert('API key is required to use this script.');
  30. }
  31. }
  32. return apiKey;
  33. };
  34.  
  35. const requestLanguage = async () => {
  36. const normalize = (str) => {
  37. return str.replace(/[A-Za-z]/g, (match) => {
  38. return String.fromCharCode(match.charCodeAt(0) - 0xFEE0);
  39. });
  40. }
  41.  
  42. const langMap = {
  43. "arabic": "AR",
  44. "bulgarian": "BG",
  45. "czech": "CS",
  46. "danish": "DA",
  47. "german": "DE",
  48. "greek": "EL",
  49. "english": "EN",
  50. "english-british": "EN-GB",
  51. "english-american": "EN-US",
  52. "spanish": "ES",
  53. "estonian": "ET",
  54. "finnish": "FI",
  55. "french": "FR",
  56. "hungarian": "HU",
  57. "indonesian": "ID",
  58. "italian": "IT",
  59. "japanese": "JA",
  60. "korean": "KO",
  61. "lithuanian": "LT",
  62. "latvian": "LV",
  63. "norwegian-bokmaal": "NB",
  64. "dutch": "NL",
  65. "polish": "PL",
  66. "portuguese": "PT",
  67. "portuguese-brazilian": "PT-BR",
  68. "portuguese-european": "PT-PT",
  69. "romanian": "RO",
  70. "russian": "RU",
  71. "slovak": "SK",
  72. "slovenian": "SL",
  73. "swedish": "SV",
  74. "turkish": "TR",
  75. "ukrainian": "UK",
  76. "chinese": "ZH",
  77. "chinese-simplified": "ZH-HANS",
  78. "chinese-traditional": "ZH-HANT"
  79. };
  80.  
  81. const input = await new Promise((resolve) => {
  82. const userInput = prompt('Please enter the target language for translation (e.g., English, Japanese)');
  83. resolve(userInput);
  84. });
  85.  
  86. const formatText = normalize(input);
  87.  
  88. // 入力があれば、対応する言語コードを返す
  89. const langCode = langMap[formatText.toLowerCase()];
  90. if (langCode) {
  91. return langCode;
  92. } else {
  93. alert('Invalid language entered. Defaulting to Japanese.');
  94. }
  95.  
  96. return 'JA';
  97. };
  98.  
  99. const translateText = async (text, lang) => {
  100. const apiKey = await getApiKey();
  101. if (!apiKey) return;
  102.  
  103. const url = 'https://api-free.deepl.com/v2/translate';
  104.  
  105. const params = {
  106. auth_key: apiKey,
  107. text: text,
  108. target_lang: lang,
  109. };
  110.  
  111. GM_xmlhttpRequest({
  112. method: 'POST',
  113. url: url,
  114. headers: {
  115. 'Content-Type': 'application/x-www-form-urlencoded',
  116. },
  117. data: new URLSearchParams(params).toString(),
  118. onload: (response) => {
  119. try {
  120. const result = JSON.parse(response.responseText);
  121. const translatedText = result.translations[0].text;
  122. alert(`${text}\n\n->\n\n${translatedText}`);
  123. console.log(`${text}\n\n->\n\n${translatedText}`);
  124. } catch (e) {
  125. console.error('Error parsing the response from DeepL:', e);
  126. alert('An error occurred while processing the translation.');
  127. }
  128. },
  129. onerror: (error) => {
  130. console.error('Error with DeepL API request:', error);
  131. alert('Error occurred while translating. Please try again later.');
  132. },
  133. });
  134. };
  135.  
  136. console.log('Smart-Translate is started!');
  137. document.addEventListener('keydown', async (event) => {
  138. if (event.altKey && event.key === 't') {
  139. const selectedText = window.getSelection().toString().trim();
  140. if (selectedText) {
  141. await translateText(selectedText, 'JA');
  142. } else {
  143. alert('Please select text!');
  144. }
  145. }
  146.  
  147. if (event.altKey && event.key === 'T') {
  148. const selectedText = window.getSelection().toString().trim();
  149. if (selectedText) {
  150. const selectLanguage = await requestLanguage();
  151. await translateText(selectedText, selectLanguage);
  152. } else {
  153. alert('Please select text!');
  154. }
  155. }
  156.  
  157. if (event.altKey && event.key === 'r') {
  158. const apiKey = await getApiKey();
  159. const newKey = prompt(`Please input your new API key\nNow API key: ${apiKey}`);
  160. if (newKey) {
  161. await GM_setValue('DEEPL_API_KEY', newKey);
  162. alert('API key updated successfully.');
  163. }
  164. }
  165. });
  166. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址