Membangun Langkah-Langkah Tindakan dan Alat Bantu Awal Workspace Studio Kustom

1. Pengantar

Dalam codelab ini, Anda akan membangun Support Quick Portal interaktif yang berinteraksi langsung dengan Google Workspace Studio. Anda akan mempelajari cara membuat langkah awal kustom dan langkah tindakan kustom yang dapat langsung diuji tanpa mengandalkan infrastruktur pihak ketiga.

Kita akan menggunakan Google Apps Script untuk membuat:

  • Aplikasi Web dengan formulir yang canggih bagi pengguna untuk mengirimkan tiket dukungan secara manual.
  • Custom Starter yang merekam pengiriman Aplikasi Web tersebut dan memicu alur Workspace Studio.
  • Langkah Kustom yang menganalisis deskripsi tiket masuk untuk mengidentifikasi tingkat urgensi ("Tinggi" atau "Normal").

Yang akan Anda pelajari

  • Cara mengonfigurasi pemicu dan langkah dalam manifes appsscript.json.
  • Cara membuat notifyUri selama siklus proses pendaftaran starter.
  • Cara memicu alur Workspace Studio secara terprogram dari kode eksternal menggunakan UrlFetchApp.
  • Cara membuat variabel output di langkah kustom untuk meneruskan data ke hilir.

Prasyarat

  • Akun Google Workspace dengan Google Workspace Studio diaktifkan.
  • Setelan Izinkan langkah kustom yang belum dipublikasikan (pengujian) diaktifkan di Konsol Admin domain Anda (di bagian Aplikasi > Google Workspace > Workspace Studio > setelan langkah kustom).
  • Pemahaman tentang Google Apps Script.

2. Menyiapkan Project Apps Script

Pertama, mari kita buat project Apps Script baru untuk menampung kode kita:

  1. Buka script.google.com, lalu klik Project baru.
  2. Beri nama project Support Quick Portal.
  3. Klik Setelan Project Project Settings di sidebar kiri.
  4. Centang kotak untuk Tampilkan file manifes appsscript.json dalam editor.
  5. Kembali ke tampilan Editor Editor.

Secara default, project Apps Script dikaitkan dengan project Google Cloud default yang tersembunyi. Untuk memanggil Google Workspace Studio API dan menghindari error PERMISSION_DENIED, Anda harus mengalihkan skrip ke project Cloud standar, mengaktifkan API, dan mengonfigurasi Platform Auth Google dengan benar.

  1. Pilih atau Buat Project: Buka Konsol Google Cloud dan gunakan menu dropdown project di bagian atas halaman untuk memilih project yang sudah ada atau membuat project baru.
  2. Aktifkan API: Setelah project yang Anda pilih aktif di panel atas, buka API Enablement Flow, lalu klik Next dan Enable untuk Workspace Studio API.
  3. Mengonfigurasi Branding OAuth: Buka halaman Branding Google Auth Platform.
    1. Jika diminta, klik Mulai. (Jika sudah dikonfigurasi, lanjutkan ke langkah 4).
    2. Di bagian Informasi Aplikasi, masukkan Nama aplikasi dan Email dukungan pengguna. Klik Next.
    3. Di bagian Audience, pilih Internal (atau External jika Internal tidak tersedia), lalu klik Next.
    4. Berikan Informasi Kontak, setujui Kebijakan Data, lalu klik Buat.
  4. Konfigurasi Akses Data: Buka halaman Akses Data, lalu klik Tambahkan atau Hapus Cakupan.
    1. Di bagian Tambahkan cakupan secara manual, tempelkan https://www.googleapis.com/auth/workspace.studio.trigger.
    2. Klik Tambahkan ke Tabel, lalu Perbarui, dan terakhir klik Simpan di bagian bawah halaman.
  5. Buka IAM & Admin > Settings (atau dasbor Konsol Cloud) dan salin Project number.
  6. Kembali ke project Apps Script Anda, lalu klik Setelan Project Project Settings di sidebar kiri.
  7. Di bagian Google Cloud Platform (GCP) Project, klik Change project.
  8. Masukkan GCP Project number yang Anda salin, lalu klik Set project.

Mengonfigurasi Manifes

Buka file appsscript.json yang baru terlihat. Ganti kontennya dengan kode di bawah. Manifes ini secara eksplisit mencantumkan cakupan OAuth yang diperlukan dan menentukan starter sebagai workflowTrigger dan tindakan sebagai workflowAction dalam blok studio.flows.workflowElements.

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "webapp": {
     "executeAs": "USER_ACCESSING",
     "access": "MYSELF"
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/workspace.studio.trigger",
    "https://www.googleapis.com/auth/script.storage",
    "https://www.googleapis.com/auth/script.locale"
  ],
  "urlFetchWhitelist": [
    "https://workspacestudio.googleapis.com/"
  ],
  "addOns": {
    "common": {
      "name": "Support Extension",
      "logoUrl": "https://www.gstatic.com/images/branding/productlogos/buganizer/v1/192px.svg",
      "useLocaleFromApp": true
    },
    "studio": {
      "flows": {
        "workflowElements": [
          {
            "id": "supportTicketTrigger",
            "state": "ACTIVE",
            "name": "New Support Ticket",
            "description": "Fires when someone submits a ticket via the Web App.",
            "workflowTrigger": {
              "inputs": [],
              "outputs": [
                {
                  "id": "ticketTitle",
                  "description": "The title of the ticket",
                  "cardinality": "SINGLE",
                  "dataType": { "basicType": "STRING" }
                },
                {
                  "id": "ticketDescription",
                  "description": "The full description of the issue",
                  "cardinality": "SINGLE",
                  "dataType": { "basicType": "STRING" }
                }
              ],
              "onConfigFunction": "onConfigTrigger",
              "onManageFunction": "onManageTrigger"
            }
          },
          {
            "id": "urgencyDetectorStep",
            "state": "ACTIVE",
            "name": "Detect Urgency",
            "description": "Scans the ticket description to detect High or Normal urgency.",
            "workflowAction": {
              "inputs": [
                {
                  "id": "ticketDescription",
                  "description": "The ticket description",
                  "cardinality": "SINGLE",
                  "dataType": { "basicType": "STRING" }
                }
              ],
              "outputs": [
                {
                  "id": "urgencyLevel",
                  "description": "The urgency High/Normal",
                  "cardinality": "SINGLE",
                  "dataType": { "basicType": "STRING" }
                }
              ],
              "onConfigFunction": "onConfigUrgency",
              "onExecuteFunction": "onExecuteUrgency"
            }
          }
        ]
      }
    }
  }
}

3. Membangun UI Aplikasi Web

Untuk menyediakan cara visual dan dapat diuji untuk memicu starter tanpa menggunakan alat terminal atau webhook pihak ketiga, kita akan membuat Aplikasi Web Apps Script.

Di editor Apps Script, di samping File, klik Tambahkan berkas Tambahkan file, lalu pilih HTML. Beri nama index.html (ekstensi .html akan ditambahkan secara otomatis).

Tempelkan kode UI sederhana berikut:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
      body { font-family: Arial, sans-serif; padding: 20px; max-width: 500px; margin: auto; }
      label { font-weight: bold; display: block; margin-top: 15px; }
      input, textarea { width: 100%; margin-top: 5px; padding: 10px; box-sizing: border-box; }
      button { background-color: #1a73e8; color: white; border: none; padding: 10px 15px; margin-top: 15px; font-weight: bold; cursor: pointer; border-radius: 4px; }
      button:hover { background-color: #1557b0; }
      #status { margin-top: 15px; color: green; font-weight: bold; }
    </style>
  </head>
  <body>
    <h2>Support Quick Portal</h2>
    <p>Submit your issue below to trigger the Workspace Studio flow.</p>

    <label for="title">Ticket Title</label>
    <input type="text" id="title" placeholder="e.g. Broken monitor">

    <label for="description">Issue Description</label>
    <textarea id="description" rows="4" placeholder="Explain your issue (use words like 'urgent' to test the step!)..."></textarea>

    <button onclick="submitTicket()">Submit Ticket</button>
    <div id="status"></div>

    <script>
      function submitTicket() {
        const title = document.getElementById('title').value;
        const description = document.getElementById('description').value;
        const statusEl = document.getElementById('status');

        if (!title || !description) {
           statusEl.style.color = "red";
           statusEl.innerText = "Please fill out both fields.";
           return;
        }

        statusEl.style.color = "green";
        statusEl.innerText = "Submitting ticket...";

        google.script.run
          .withSuccessHandler(function(response) {
            statusEl.innerText = response;
          })
          .withFailureHandler(function(error) {
            statusEl.style.color = 'red';
            statusEl.innerText = 'Error: ' + error.message;
          })
          .submitTicketToStudio(title, description);
      }
    </script>
  </body>
</html>

4. Membangun Skrip Backend

Sekarang mari kita hubungkan semuanya. Agar kode tetap mudah dibaca, kita akan memisahkan logika Aplikasi Web, Starter, dan Langkah Tindakan ke dalam tiga file skrip yang berbeda.

WebApp.gs

Ganti nama file Code.gs default di editor menjadi WebApp.gs, hapus myFunction boilerplate, lalu salin dan tempel blok di bawah ke dalamnya. File ini menangani hosting Aplikasi Web:

/** --- WEB APP HOSTING --- **/

/**
 * Serves the HTML UI when users visit the web app URL.
 */
function doGet() {
  return HtmlService.createHtmlOutputFromFile('index')
      .setTitle('Support Quick Portal')
      .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

/**
 * Called by the Web App form. It calls the Workspace Studio API.
 */
function submitTicketToStudio(title, description) {
  const props = PropertiesService.getUserProperties();
  const notifyUri = props.getProperty('notifyUri');
  const triggerId = props.getProperty('triggerId');

  if (!notifyUri || !triggerId) {
    throw new Error('Trigger URL missing! Make sure the flow is enabled in Workspace Studio.');
  }

  // Use ScriptApp.getOAuthToken() (requires the workspace.studio.trigger scope in manifest)
  const token = ScriptApp.getOAuthToken();
  const requestId = Utilities.getUuid();

  // Package our outputs mapped in appsscript.json
  const payload = {
    "name": "triggers/" + triggerId,
    "outputs": {
      "ticketTitle": { "stringValues": [title] },
      "ticketDescription": { "stringValues": [description] }
    },
    "requestId": requestId
  };

  const options = {
    "method": "POST",
    "contentType": "application/json",
    "headers": { "Authorization": "Bearer " + token },
    "payload": JSON.stringify(payload),
    "muteHttpExceptions": true
  };

  // Fire!
  const response = UrlFetchApp.fetch(notifyUri, options);
  if (response.getResponseCode() !== 200) {
    console.error(response.getContentText());
    throw new Error('Workspace Studio API Error: ' + response.getResponseCode());
  }
  return 'Ticket successfully routed to Workspace Studio!';
}

Starter.gs

Selanjutnya, arahkan kursor ke File, klik Tambahkan berkas Tambahkan file, pilih Skrip, dan beri nama Starter.gs. Salin dan tempel blok di bawah ke dalamnya. File ini menangani konfigurasi Starter dan pengelolaan siklus proses Workspace Studio:

/** --- STARTER LOGIC --- **/

/**
 * Workspace Studio calls this to display the config UI when the user adds the starter.
 * We just return a static message since there are no properties to configure.
 */
function onConfigTrigger() {
  const section = CardService.newCardSection()
      .setHeader("Configure Web App Starter")
      .addWidget(CardService.newTextParagraph().setText("Ready to go! Once you enable this flow, deploy your Apps Script project as a Web App to submit tickets."));

  return CardService.newCardBuilder().addSection(section).build();
}

/**
 * Workspace Studio posts data here to manage the lifecycle (enable/disable the trigger).
 * Critically, we must construct or save the `notifyUri` and `triggerId` to call it later.
 */
function onManageTrigger(event) {
  const triggerCreation = event.workflow.triggerCreation;
  const triggerDeletion = event.workflow.triggerDeletion;

  const props = PropertiesService.getUserProperties();

  if (triggerCreation) {
    // Save the unique URL and ID when the flow is enabled
    // Note: notifyUri might be omitted, so fallback to constructing it dynamically
    const notifyUri = triggerCreation.notifyUri || `https://workspacestudio.googleapis.com/v1/triggers/${triggerCreation.triggerId}:fire`;
    props.setProperty('notifyUri', notifyUri);
    props.setProperty('triggerId', triggerCreation.triggerId);
  } else if (triggerDeletion) {
    // Cleanup if the user deletes the flow
    props.deleteProperty('notifyUri');
    props.deleteProperty('triggerId');
  }
}

Action.gs

Selanjutnya, arahkan kursor ke File, klik Tambahkan berkas Tambahkan file, pilih Skrip, dan beri nama Action.gs. Salin dan tempel logika Urgency Step di bawah ke dalamnya:

/** --- ACTION STEP LOGIC --- **/

/**
 * Workspace Studio configuration card for the Step.
 * We prompt the user to bind a variable to our "ticketDescription" input.
 */
function onConfigUrgency() {
  const input = CardService.newTextInput()
      .setFieldName("ticketDescription")
      .setTitle("Source Description")
      .setHint('Select the description variable outputted by the starter')
      .setHostAppDataSource(
        CardService.newHostAppDataSource().setWorkflowDataSource(CardService.newWorkflowDataSource().setIncludeVariables(true))
      );

  const section = CardService.newCardSection()
      .setHeader("Urgency Detector Step")
      .addWidget(input);

  return CardService.newCardBuilder().addSection(section).build();
}

/**
 * The synchronous logic executed during the Step.
 */
function onExecuteUrgency(event) {
  // Read mapped inputs
  let description = event.workflow.actionInvocation.inputs["ticketDescription"].stringValues[0];
  if (!description) description = "";

  const urgentKeywords = ['urgent', 'crash', 'broken', 'down', 'fire'];
  let urgencyLevel = 'Normal';

  if (urgentKeywords.some(keyword => description.toLowerCase().includes(keyword))) {
    urgencyLevel = 'High';
  }

  // Package outputs correctly
  const variableDataMap = {
    "urgencyLevel": AddOnsResponseService.newVariableData().addStringValue(urgencyLevel)
  };

  return outputVariables(variableDataMap);
}

/**
 * Helper strictly enforcing the expected Step object return type.
 */
function outputVariables(variableDataMap) {
  const workflowAction = AddOnsResponseService.newReturnOutputVariablesAction()
      .setVariableDataMap(variableDataMap);
  const hostAppAction = AddOnsResponseService.newHostAppAction()
      .setWorkflowAction(workflowAction);
  return AddOnsResponseService.newRenderActionBuilder()
      .setHostAppAction(hostAppAction)
      .build();
}

5. Men-deploy dan Menguji

Setelah kode ditulis, mari kita deploy dan konfigurasi project.

Langkah 1: Beri ulang otorisasi Skrip

Karena Anda menautkan project Google Cloud standar baru, Anda harus memberikan otorisasi secara eksplisit untuk cakupan skrip (seperti script.external_request yang digunakan oleh UrlFetchApp) terhadap project baru.

  1. Di editor Apps Script, pilih WebApp.gs di bagian File, lalu pilih fungsi doGet dari dropdown toolbar atas.
  2. Klik Run.
  3. Dialog "Otorisasi diperlukan" akan muncul. Klik Tinjau izin.
  4. Pilih akun Anda dan izinkan skrip. Jika Anda melihat peringatan "Aplikasi tidak terverifikasi", klik Lanjutan -> Buka Portal Cepat Dukungan untuk melewati peringatan.
  5. Tunggu hingga Log eksekusi menampilkan Eksekusi selesai, yang mengonfirmasi bahwa skrip kini sepenuhnya diizinkan.

Langkah 2: Uji Ekstensi dan Aplikasi Web

Karena appsscript.json Anda menentukan Add-on dan Aplikasi Web, Anda dapat mengonfigurasi keduanya secara bersamaan.

  1. Klik Deploy > Test deployments di pojok kanan atas Apps Script.
  2. Di sebelah Pilih jenis, klik Mengaktifkan jenis deployment Aktifkan jenis deployment dan pastikan Add-on Google Workspace dicentang, lalu klik Instal.
  3. Klik Mengaktifkan jenis deployment Aktifkan jenis deployment lagi, pastikan Aplikasi web dicentang, lalu salin URL (akan diakhiri dengan /dev). Ini adalah URL untuk aplikasi web Support Quick Portal yang Anda buat.
  4. Klik Selesai. Anda mungkin perlu memuat ulang browser sebelum Workspace Studio mendaftarkan add-on.

Langkah 3: Konfigurasi Alur Studio

  1. Buka Google Workspace Studio di studio.workspace.google.com.
  2. Klik Tambahkan alat Tambahkan alat di sebelah kiri, lalu pilih Alur.
  3. Untuk mengonfigurasi Starter, klik Choose a starter, lalu pilih Support Extension yang telah diinstal > New Support Ticket. Jika diminta dengan pesan "Izin diperlukan", klik Beri izin untuk mengizinkan add-on mengakses data Anda.
  4. Selanjutnya, di bagian Actions, klik Choose a step, scroll ke "Support Extension", lalu pilih langkah Detect Urgency.
  5. Di Deskripsi Sumber, klik Tambahkan Variabel, lalu pilih Langkah 1: Tiket Dukungan Baru > Deskripsi lengkap masalah (ticketDescription).
  6. Klik Pilih langkah lagi, lalu pilih langkah bawaan seperti Gmail > Kirim email atau Chat > Beri tahu saya di Chat.
    • Jika Anda memilih Gmail:
      • Kepada: Masukkan email Anda sendiri.
      • Subjek: Prioritas tiket ticketTitle adalah urgencyLevel
      • Pesan: ticketDescription
    • Jika Anda memilih Chat:
      • Pesan: Prioritas tiket ticketTitle adalah urgencyLevel. ticketDescription
  7. Aktifkan alur kerja. Jika diminta untuk Mengganti nama alur, masukkan nama seperti Support Ticket Router, lalu simpan. Hal ini memicu siklus proses onManageTrigger, menyimpan notifyUri.

Langkah 4: Jalankan Simulasi

  1. Buka URL Aplikasi Web yang Anda salin sebelumnya di Langkah 2 halaman ini di tab browser baru (URL tersebut diakhiri dengan /dev).
  2. Isi formulirnya. Pastikan Anda menyertakan kata kunci pemicu (seperti "mendesak" atau "error") dalam deskripsi.
  3. Klik Kirim. Tunggu pesan "Ticket successfully routed".
  4. Periksa Log Aktivitas Workspace Studio, Kotak Masuk Gmail, atau Google Chat Anda (bergantung pada tindakan yang Anda pilih). Anda akan melihat pesan atau email yang diberi tag sebagai urgensi "Tinggi" yang terintegrasi secara native menggunakan elemen Apps Script kustom Anda.

6. Pembersihan

Agar tidak membuat ruang kerja dan akun Google Cloud Anda berantakan, Anda dapat membersihkan resource yang Anda buat selama codelab ini.

  1. Menghapus Alur Workspace Studio:
  2. Hapus Project Apps Script:
    • Buka script.google.com.
    • Temukan project Support Quick Portal.
    • Klik menu tiga titik, lalu pilih Hapus.
  3. Nonaktifkan Project Google Cloud:
    • Buka Konsol Google Cloud.
    • Pastikan project baru Anda dipilih di dropdown atas.
    • Buka IAM & Admin > Settings, lalu klik Shut Down.

7. Kesimpulan

Anda telah berhasil membangun ekosistem lengkap untuk ekstensi kustom Google Workspace Studio tanpa mengandalkan langganan pihak ketiga eksternal.

Yang telah kita bahas:

  • Menggunakan workflowTrigger bersama onManageFunction untuk merekam dan menangani peristiwa siklus proses Google dengan benar.
  • Mengautentikasi permintaan backend menggunakan ScriptApp.getOAuthToken() terhadap endpoint API workspacestudio.googleapis.com.
  • Menggunakan workflowAction untuk memproses variabel input secara serentak dan menghasilkan output hilir.

Sekarang Anda dapat menskalakan prinsip-prinsip ini untuk terhubung ke platform SaaS nyata seperti Jira, Salesforce, atau Zendesk dengan mengubah tempat pemicuan Aplikasi Web (atau webhook masuk) Anda.