Menerjemahkan teks dari Google Dokumen, Spreadsheet, dan Slide

Level coding: Menengah
Durasi: 30 menit
Jenis project: Add-on Google Workspace

Tujuan

  • Pahami fungsi solusi tersebut.
  • Pahami fungsi layanan Apps Script dalam solusi tersebut.
  • Menyiapkan lingkungan.
  • Siapkan skrip.
  • Jalankan skrip.

Tentang solusi ini

Dengan solusi ini, Anda dapat dengan mudah menerjemahkan teks dari dalam Google Dokumen, Spreadsheet, dan Slide.

Screenshot Add-on Google Workspace Terjemahan

Cara kerjanya

Saat Anda memilih teks di Dokumen, Spreadsheet, atau Slide, lalu mengklik Get Selection di add-on, skrip akan menyalin teks ke add-on, menerjemahkannya, dan menampilkan teks terjemahan.

Secara default, skrip akan mendeteksi bahasa sumber dan menerjemahkan teks ke dalam bahasa Inggris. Anda dapat mengedit bahasa sumber dan target.

Layanan Apps Script

Solusi ini menggunakan layanan berikut:

Prasyarat

Untuk menggunakan sampel ini, Anda memerlukan prasyarat berikut:

  • Akun Google (akun Google Workspace mungkin memerlukan persetujuan administrator).
  • Browser web dengan akses ke internet.

  • Project Google Cloud.

Menyiapkan lingkungan Anda

Buka project Cloud Anda di konsol Google Cloud

Jika belum terbuka, buka project Cloud yang ingin Anda gunakan untuk contoh ini:

  1. Di konsol Google Cloud, buka halaman Select a project.

    Memilih project Cloud

  2. Pilih project Google Cloud yang ingin Anda gunakan. Atau, klik Buat project dan ikuti petunjuk di layar. Jika membuat project Google Cloud, Anda mungkin perlu mengaktifkan penagihan untuk project tersebut.

Add-on Google Workspace memerlukan konfigurasi layar izin. Mengonfigurasi layar izin OAuth add-on Anda akan menentukan apa yang ditampilkan Google kepada pengguna.

  1. Di konsol Google Cloud, buka Menu > APIs & Services > OAuth consent screen.

    Buka layar izin OAuth

  2. Untuk Jenis pengguna, pilih Internal, lalu klik Buat.
  3. Lengkapi formulir pendaftaran aplikasi, lalu klik Simpan dan Lanjutkan.
  4. Untuk saat ini, Anda dapat melewati penambahan cakupan dan mengklik Simpan dan Lanjutkan. Pada masa mendatang, saat membuat aplikasi untuk digunakan di luar organisasi Google Workspace, Anda harus mengubah User type menjadi External, lalu tambahkan cakupan otorisasi yang diperlukan aplikasi Anda.

  5. Tinjau ringkasan pendaftaran aplikasi Anda. Untuk melakukan perubahan, klik Edit. Jika pendaftaran aplikasi terlihat baik-baik saja, klik Back to Dashboard.

Menyiapkan skrip

Membuat project Apps Script

  1. Klik tombol berikut untuk membuka project Apps Script Translate.
    Buka project

  2. Klik Ringkasan .

  3. Di halaman ringkasan, klik Buat salinan Ikon untuk membuat salinan.

Salin nomor project Cloud

  1. Di konsol Google Cloud, buka Menu > IAM & Admin > Settings.

    Buka IAM & Admin Settings

  2. Di kolom Project number, salin nilainya.

Menetapkan project Cloud project Apps Script

  1. Di salinan project Apps Script Anda, klik Project Settings Ikon untuk setelan project.
  2. Pada Google Cloud Platform (GCP) Project, klik Change project.
  3. Di GCP project number, tempel nomor project Google Cloud.
  4. Klik Set project.

Menginstal deployment pengujian

  1. Di salinan project Apps Script yang Anda salin, klik Editor .
  2. Buka file Code.gs, lalu klik Run. Jika diminta, izinkan skrip.
  3. Klik Deploy > Uji deployment.
  4. Klik Instal > Selesai.

Jalankan skrip:

  1. Buka file di Google Dokumen, Spreadsheet, atau Slide, atau buat yang baru.
  2. Di sidebar kanan, buka add-on Terjemahan .
  3. Jika diminta, izinkan add-on.
  4. Pilih teks dalam file Anda.
  5. Di add-on, klik Get Selection > Translate.

Meninjau kode

Untuk meninjau kode Apps Script untuk solusi ini, klik Lihat kode sumber di bawah:

Melihat kode sumber

Code.gs

const DEFAULT_INPUT_TEXT = '';
const DEFAULT_OUTPUT_TEXT = '';
const DEFAULT_ORIGIN_LAN = ''; // Empty string means detect langauge
const DEFAULT_DESTINATION_LAN = 'en' // English

const LANGUAGE_MAP =
  [
    { text: 'Detect Language', val: '' },
    { text: 'Afrikaans', val: 'af' },
    { text: 'Albanian', val: 'sq' },
    { text: 'Amharic', val: 'am' },
    { text: 'Arabic', val: 'ar' },
    { text: 'Armenian', val: 'hy' },
    { text: 'Azerbaijani', val: 'az' },
    { text: 'Basque', val: 'eu' },
    { text: 'Belarusian', val: 'be' },
    { text: 'Bengali', val: 'bn' },
    { text: 'Bosnian', val: 'bs' },
    { text: 'Bulgarian', val: 'bg' },
    { text: 'Catalan', val: 'ca' },
    { text: 'Cebuano', val: 'ceb' },
    { text: 'Chinese (Simplified)', val: 'zh-CN' },
    { text: 'Chinese (Traditional)', val: 'zh-TW' },
    { text: 'Corsican', val: 'co' },
    { text: 'Croatian', val: 'hr' },
    { text: 'Czech', val: 'cs' },
    { text: 'Danish', val: 'da' },
    { text: 'Dutch', val: 'nl' },
    { text: 'English', val: 'en' },
    { text: 'Esperanto', val: 'eo' },
    { text: 'Estonian', val: 'et' },
    { text: 'Finnish', val: 'fi' },
    { text: 'French', val: 'fr' },
    { text: 'Frisian', val: 'fy' },
    { text: 'Galician', val: 'gl' },
    { text: 'Georgian', val: 'ka' },
    { text: 'German', val: 'de' },
    { text: 'Greek', val: 'el' },
    { text: 'Gujarati', val: 'gu' },
    { text: 'Haitian Creole', val: 'ht' },
    { text: 'Hausa', val: 'ha' },
    { text: 'Hawaiian', val: 'haw' },
    { text: 'Hebrew', val: 'he' },
    { text: 'Hindi', val: 'hi' },
    { text: 'Hmong', val: 'hmn' },
    { text: 'Hungarian', val: 'hu' },
    { text: 'Icelandic', val: 'is' },
    { text: 'Igbo', val: 'ig' },
    { text: 'Indonesian', val: 'id' },
    { text: 'Irish', val: 'ga' },
    { text: 'Italian', val: 'it' },
    { text: 'Japanese', val: 'ja' },
    { text: 'Javanese', val: 'jv' },
    { text: 'Kannada', val: 'kn' },
    { text: 'Kazakh', val: 'kk' },
    { text: 'Khmer', val: 'km' },
    { text: 'Korean', val: 'ko' },
    { text: 'Kurdish', val: 'ku' },
    { text: 'Kyrgyz', val: 'ky' },
    { text: 'Lao', val: 'lo' },
    { text: 'Latin', val: 'la' },
    { text: 'Latvian', val: 'lv' },
    { text: 'Lithuanian', val: 'lt' },
    { text: 'Luxembourgish', val: 'lb' },
    { text: 'Macedonian', val: 'mk' },
    { text: 'Malagasy', val: 'mg' },
    { text: 'Malay', val: 'ms' },
    { text: 'Malayalam', val: 'ml' },
    { text: 'Maltese', val: 'mt' },
    { text: 'Maori', val: 'mi' },
    { text: 'Marathi', val: 'mr' },
    { text: 'Mongolian', val: 'mn' },
    { text: 'Myanmar (Burmese)', val: 'my' },
    { text: 'Nepali', val: 'ne' },
    { text: 'Norwegian', val: 'no' },
    { text: 'Nyanja (Chichewa)', val: 'ny' },
    { text: 'Pashto', val: 'ps' },
    { text: 'Persian', val: 'fa' },
    { text: 'Polish', val: 'pl' },
    { text: 'Portuguese (Portugal, Brazil)', val: 'pt' },
    { text: 'Punjabi', val: 'pa' },
    { text: 'Romanian', val: 'ro' },
    { text: 'Russian', val: 'ru' },
    { text: 'Samoan', val: 'sm' },
    { text: 'Scots Gaelic', val: 'gd' },
    { text: 'Serbian', val: 'sr' },
    { text: 'Sesotho', val: 'st' },
    { text: 'Shona', val: 'sn' },
    { text: 'Sindhi', val: 'sd' },
    { text: 'Sinhala (Sinhalese)', val: 'si' },
    { text: 'Slovak', val: 'sk' },
    { text: 'Slovenian', val: 'sl' },
    { text: 'Somali', val: 'so' },
    { text: 'Spanish', val: 'es' },
    { text: 'Sundanese', val: 'su' },
    { text: 'Swahili', val: 'sw' },
    { text: 'Swedish', val: 'sv' },
    { text: 'Tagalog (Filipino)', val: 'tl' },
    { text: 'Tajik', val: 'tg' },
    { text: 'Tamil', val: 'ta' },
    { text: 'Telugu', val: 'te' },
    { text: 'Thai', val: 'th' },
    { text: 'Turkish', val: 'tr' },
    { text: 'Ukrainian', val: 'uk' },
    { text: 'Urdu', val: 'ur' },
    { text: 'Uzbek', val: 'uz' },
    { text: 'Vietnamese', val: 'vi' },
    { text: 'Welsh', val: 'cy' },
    { text: 'Xhosa', val: 'xh' },
    { text: 'Yiddish', val: 'yi' },
    { text: 'Yoruba', val: 'yo' },
    { text: 'Zulu', val: 'zu' }
  ];


/**
 * Callback for rendering the main card.
 * @return {CardService.Card} The card to show the user.
 */
function onHomepage(e) {
  return createSelectionCard(e, DEFAULT_ORIGIN_LAN, DEFAULT_DESTINATION_LAN, DEFAULT_INPUT_TEXT, DEFAULT_OUTPUT_TEXT);
}

/**
 * Main function to generate the main card.
 * @param {String} originLanguage Language of the original text.
 * @param {String} destinationLanguage Language of the translation.
 * @param {String} inputText The text to be translated.
 * @param {String} outputText The text translated.
 * @return {CardService.Card} The card to show to the user.
 */
function createSelectionCard(e, originLanguage, destinationLanguage, inputText, outputText) {
  var hostApp = e['hostApp'];
  var builder = CardService.newCardBuilder();

  // "From" language selection & text input section
  var fromSection = CardService.newCardSection()
    .addWidget(generateLanguagesDropdown('origin', 'From: ', originLanguage))
    .addWidget(CardService.newTextInput()
      .setFieldName('input')
      .setValue(inputText)
      .setTitle('Enter text...')
      .setMultiline(true));

  if (hostApp === 'docs') {
    fromSection.addWidget(CardService.newButtonSet()
      .addButton(CardService.newTextButton()
        .setText('Get Selection')
        .setOnClickAction(CardService.newAction().setFunctionName('getDocsSelection'))
        .setDisabled(false)))
  } else if (hostApp === 'sheets') {
    fromSection.addWidget(CardService.newButtonSet()
      .addButton(CardService.newTextButton()
        .setText('Get Selection')
        .setOnClickAction(CardService.newAction().setFunctionName('getSheetsSelection'))
        .setDisabled(false)))
  } else if (hostApp === 'slides') {
    fromSection.addWidget(CardService.newButtonSet()
      .addButton(CardService.newTextButton()
        .setText('Get Selection')
        .setOnClickAction(CardService.newAction().setFunctionName('getSlidesSelection'))
        .setDisabled(false)))
  }


  builder.addSection(fromSection);

  // "Translation" language selection & text input section
  builder.addSection(CardService.newCardSection()
    .addWidget(generateLanguagesDropdown('destination', 'To: ', destinationLanguage))
    .addWidget(CardService.newTextInput()
      .setFieldName('output')
      .setValue(outputText)
      .setTitle('Translation...')
      .setMultiline(true)));

  //Buttons section
  builder.addSection(CardService.newCardSection()
    .addWidget(CardService.newButtonSet()
      .addButton(CardService.newTextButton()
        .setText('Translate')
        .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
        .setOnClickAction(CardService.newAction().setFunctionName('translateText'))
        .setDisabled(false))
      .addButton(CardService.newTextButton()
        .setText('Clear')
        .setOnClickAction(CardService.newAction().setFunctionName('clearText'))
        .setDisabled(false))));

  return builder.build();

}

/**
 * Helper function to generate the drop down language menu. It checks what language the user had selected.
 * @param {String} fieldName
 * @param {String} fieldTitle
 * @param {String} previousSelected The language the user previously had selected.
 * @return {CardService.SelectionInput} The card to show to the user.
 */
function generateLanguagesDropdown(fieldName, fieldTitle, previousSelected) {
  var selectionInput = CardService.newSelectionInput().setTitle(fieldTitle)
    .setFieldName(fieldName)
    .setType(CardService.SelectionInputType.DROPDOWN);

  LANGUAGE_MAP.forEach((language, index, array) => {
    selectionInput.addItem(language.text, language.val, language.val == previousSelected);
  })

  return selectionInput;
}

/**
 * Helper function to translate the text. If the originLanguage is an empty string, the API detects the language
 * @return {CardService.Card} The card to show to the user.
 */
function translateText(e) {
  var originLanguage = e.formInput.origin;
  var destinationLanguage = e.formInput.destination;
  var inputText = e.formInput.input;

  if (originLanguage !== destinationLanguage && inputText !== undefined) {
    var translation = LanguageApp.translate(e.formInput.input, e.formInput.origin, e.formInput.destination);
    return createSelectionCard(e, originLanguage, destinationLanguage, inputText, translation);
  }
}

/**
 * Helper function to clean the text.
 * @return {CardService.Card} The card to show to the user.
 */
function clearText(e) {
  var originLanguage = e.formInput.origin;
  var destinationLanguage = e.formInput.destination;
  return createSelectionCard(e, originLanguage, destinationLanguage, DEFAULT_INPUT_TEXT, DEFAULT_OUTPUT_TEXT);
}

/**
 * Helper function to get the text selected.
 * @return {CardService.Card} The selected text.
 */
function getDocsSelection(e) {
  var text = '';
  var selection = DocumentApp.getActiveDocument().getSelection();
  Logger.log(selection)
  if (selection) {
    var elements = selection.getRangeElements();
    for (var i = 0; i < elements.length; i++) {
      Logger.log(elements[i]);
      var element = elements[i];
      // Only modify elements that can be edited as text; skip images and other non-text elements.
      if (element.getElement().asText() && element.getElement().asText().getText() !== '') {
        text += element.getElement().asText().getText() + '\n';
      }
    }
  }

  if (text !== '') {
    var originLanguage = e.formInput.origin;
    var destinationLanguage = e.formInput.destination;
    var translation = LanguageApp.translate(text, e.formInput.origin, e.formInput.destination);
    return createSelectionCard(e, originLanguage, destinationLanguage, text, translation);
  }
}

/**
 * Helper function to get the text of the selected cells.
 * @return {CardService.Card} The selected text.
 */
function getSheetsSelection(e) {
  var text = '';
  var ranges = SpreadsheetApp.getActive().getSelection().getActiveRangeList().getRanges();
  for (var i = 0; i < ranges.length; i++) {
    const range = ranges[i];
    const numRows = range.getNumRows();
    const numCols = range.getNumColumns();
    for (let i = 1; i <= numCols; i++) {
      for (let j = 1; j <= numRows; j++) {
        const cell = range.getCell(j, i);
        if (cell.getValue()) {
          text += cell.getValue() + '\n';
        }
      }
    }
  }
  if (text !== '') {
    var originLanguage = e.formInput.origin;
    var destinationLanguage = e.formInput.destination;
    var translation = LanguageApp.translate(text, e.formInput.origin, e.formInput.destination);
    return createSelectionCard(e, originLanguage, destinationLanguage, text, translation);
  }
}

/**
 * Helper function to get the selected text of the active slide.
 * @return {CardService.Card} The selected text.
 */
function getSlidesSelection(e) {
  var text = '';
  var selection = SlidesApp.getActivePresentation().getSelection();
  var selectionType = selection.getSelectionType();
  if (selectionType === SlidesApp.SelectionType.TEXT) {
    var textRange = selection.getTextRange();
    if (textRange.asString() !== '') {
      text += textRange.asString() + '\n';
    }
  }
  if (text !== '') {
    var originLanguage = e.formInput.origin;
    var destinationLanguage = e.formInput.destination;
    var translation = LanguageApp.translate(text, e.formInput.origin, e.formInput.destination);
    return createSelectionCard(e, originLanguage, destinationLanguage, text, translation);
  }
}

appsscript.json

{
  "timeZone": "America/New_York",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "oauthScopes": [
    "https://www.googleapis.com/auth/documents.currentonly",
    "https://www.googleapis.com/auth/spreadsheets.currentonly",
    "https://www.googleapis.com/auth/presentations.currentonly"
  ],
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Translate",
      "logoUrl": "https://www.gstatic.com/images/branding/product/1x/translate_24dp.png",
      "layoutProperties": {
        "primaryColor": "#2772ed"
      },
      "homepageTrigger": {
        "runFunction": "onHomepage"
      }
    },
    "docs" : {},
    "slides" : {},
    "sheets" : {}
  }
}

Kontributor

Contoh ini dikelola oleh Google dengan bantuan Pakar Google Developers.

Langkah berikutnya