Ułatwianie obsługi poczty e-mail dzięki dodatkom do Google Workspace

1. Przegląd

W tym samouczku użyjesz Google Apps Script, aby napisać dodatek do Google Workspace do Gmaila, który umożliwi użytkownikom dodawanie danych z paragonu z e-maila do arkusza kalkulacyjnego bezpośrednio w Gmailu. Gdy użytkownik otrzyma e-maila z rachunkiem, otworzy dodatek, który automatycznie pobierze z e-maila odpowiednie informacje o wydatkach. Użytkownik może edytować informacje o wydatkach, a następnie przesłać je, aby zarejestrować wydatki w arkuszu kalkulacyjnym Arkuszy Google.

Czego się nauczysz

  • Tworzenie dodatku do Google Workspace dla Gmaila za pomocą Google Apps Script
  • Analizowanie e-maili za pomocą Google Apps Script
  • Praca z Arkuszami Google za pomocą Google Apps Script
  • Przechowywanie wartości użytkownika za pomocą usługi Properties w Google Apps Script

Czego potrzebujesz

  • dostęp do internetu i przeglądarki;
  • konto Google,
  • niektóre wiadomości, najlepiej potwierdzenia e-maili, w Gmailu;

2. Pobieranie przykładowego kodu

Podczas wykonywania tego ćwiczenia z kodowania może Ci się przydać działająca wersja kodu, który będziesz pisać. Repozytorium GitHub zawiera przykładowy kod, którego możesz użyć jako odniesienia.

Aby pobrać przykładowy kod, w wierszu polecenia wpisz i uruchom:

git clone https://github.com/googleworkspace/gmail-add-on-codelab.git

3. Tworzenie podstawowego dodatku

Zacznij od napisania kodu prostej wersji dodatku, która wyświetla formularz wydatków obok e-maila.

Najpierw utwórz nowy projekt Apps Script i otwórz jego plik manifestu.

  1. Otwórz stronę script.google.com. Możesz na niej tworzyć projekty Apps Script, zarządzać nimi i je monitorować.
  2. Aby utworzyć nowy projekt, w lewym górnym rogu kliknij Nowy projekt. Nowy projekt otworzy się z domyślnym plikiem o nazwie Code.gs. Na razie zostaw Code.gs w spokoju. Zajmiesz się nim później.
  3. Kliknij Projekt bez tytułu, nazwij projekt Expense It! i kliknij Zmień nazwę.
  4. Po lewej stronie kliknij Ustawienia projektu Ustawienia projektu.
  5. Zaznacz pole wyboru Wyświetlaj plik manifestu „appscript.json” w edytorze.
  6. Kliknij Edytujący Edytor.
  7. Aby otworzyć plik manifestu, po lewej stronie kliknij appscript.json.

W pliku appscript.json podaj metadane powiązane z dodatkiem, takie jak jego nazwa i wymagane uprawnienia. Zastąp zawartość pliku appsscript.json tymi ustawieniami konfiguracji:

{
  "timeZone": "GMT",
  "oauthScopes": [
    "https://www.googleapis.com/auth/gmail.addons.execute"
  ],
  "gmail": {
    "name": "Expense It!",
    "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/receipt_black_24dp.png",
    "contextualTriggers": [{
      "unconditional": {
      },
      "onTriggerFunction": "getContextualAddOn"
    }],
    "primaryColor": "#41f470",
    "secondaryColor": "#94f441"
  }
}

Zwróć szczególną uwagę na część pliku manifestu o nazwie contextualTriggers. Ta część pliku manifestu identyfikuje funkcję zdefiniowaną przez użytkownika, która ma być wywoływana przy pierwszym włączeniu dodatku. W tym przypadku wywołuje funkcję getContextualAddOn, która pobiera szczegóły otwartego e-maila i zwraca zestaw kart do wyświetlenia użytkownikowi.

Aby utworzyć funkcję getContextualAddOn, wykonaj te czynności:

  1. Po lewej stronie najedź wskaźnikiem na Code.gs, a następnie kliknij Menu Menu Więcej > Zmień nazwę.
  2. Wpisz GetContextualAddOn i naciśnij klawisz Enter. Apps Script automatycznie dodaje do nazwy pliku znak .gs, więc nie musisz wpisywać rozszerzenia pliku. Jeśli wpiszesz GetContextualAddOn.gs, Apps Script nada plikowi nazwę GetContextualAddOn.gs.gs.
  3. W pliku GetContextualAddOn.gs zastąp domyślny kod funkcją getContextualAddOn:
/**
 * Returns the contextual add-on data that should be rendered for
 * the current e-mail thread. This function satisfies the requirements of
 * an 'onTriggerFunction' and is specified in the add-on's manifest.
 *
 * @param {Object} event Event containing the message ID and other context.
 * @returns {Card[]}
 */
function getContextualAddOn(event) {
  var card = CardService.newCardBuilder();
  card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));

  var section = CardService.newCardSection();
  section.addWidget(CardService.newTextInput()
    .setFieldName('Date')
    .setTitle('Date'));
  section.addWidget(CardService.newTextInput()
    .setFieldName('Amount')
    .setTitle('Amount'));
  section.addWidget(CardService.newTextInput()
    .setFieldName('Description')
    .setTitle('Description'));
  section.addWidget(CardService.newTextInput()
    .setFieldName('Spreadsheet URL')
    .setTitle('Spreadsheet URL'));

  card.addSection(section);

  return [card.build()];
}

Interfejs każdego dodatku do Google Workspace składa się z kart podzielonych na co najmniej 1 sekcję, z których każda zawiera widżety, które mogą wyświetlać informacje i pobierać je od użytkownika. Funkcja getContextualAddOn tworzy pojedynczą kartę, która zawiera szczegóły wydatku znalezionego w e-mailu. Karta ma jedną sekcję zawierającą pola wprowadzania tekstu, w których można podać odpowiednie dane. Funkcja zwraca tablicę kart dodatku. W takim przypadku zwrócona tablica zawiera tylko 1 kartę.

Przed wdrożeniem dodatku Expense It! musisz mieć projekt Google Cloud Platform (GCP), którego projekty Apps Script używają do zarządzania autoryzacjami, zaawansowanymi usługami i innymi informacjami. Więcej informacji znajdziesz na stronie Projekty Google Cloud Platform.

Aby wdrożyć i uruchomić dodatek, wykonaj te czynności:

  1. Otwórz projekt GCP i skopiuj jego numer.
  2. W projekcie Apps Script po lewej stronie kliknij Ustawienia projektu Ustawienia projektu.
  3. W sekcji „Projekt Google Cloud Platform (GCP)” kliknij Zmień projekt.
  4. Wpisz numer projektu GCP, a następnie kliknij Ustaw projekt.
  5. Kliknij Wdróż> Testowe wdrożenia.
  6. Sprawdź, czy typ wdrożenia to Dodatek do Google Workspace. W razie potrzeby u góry okna kliknij Włącz typy wdrożenia Włącz typy wdrożenia i jako typ wdrożenia wybierz Dodatek do Google Workspace.
  7. Obok pozycji Aplikacje: Gmail kliknij Zainstaluj.
  8. Kliknij Gotowe.

Dodatek będzie teraz widoczny w skrzynce odbiorczej Gmaila.

  1. Otwórz Gmaila na komputerze.
  2. W panelu bocznym po prawej stronie pojawi się Expense It! Pojawi się dodatek Ikona rachunku Expense It!. Aby ją znaleźć, może być konieczne kliknięcie Więcej dodatków Więcej dodatków.
  3. Otwórz e-maila, najlepiej paragon z wydatkami.
  4. Aby otworzyć dodatek, w panelu bocznym po prawej stronie kliknij Expense It!. Ikona rachunku Expense It!.
  5. Przyznaj aplikacji Expense It! dostęp do swojego konta Google, klikając Authorize Access (Autoryzuj dostęp) i postępując zgodnie z wyświetlanymi instrukcjami.

Dodatek wyświetla prosty formularz obok otwartej wiadomości w Gmailu. Na razie nie robi nic więcej, ale w następnej sekcji rozbudujesz jego funkcjonalność.

Aby zobaczyć aktualizacje dodatku w trakcie wykonywania tego modułu, wystarczy zapisać kod i odświeżyć Gmaila. Nie musisz niczego dodatkowo wdrażać.

4. Dostęp do e-maili

Dodaj kod, który pobiera treść e-maila, i podziel go na moduły, aby był bardziej uporządkowany.

Obok opcji Pliki kliknij Dodaj Dodaj plik > Skrypt i utwórz plik o nazwie Cards. Utwórz drugi plik skryptu o nazwie Helpers. Cards.gs tworzy kartę i używa funkcji z Helpers.gs, aby wypełnić pola w formularzu na podstawie treści e-maila.

Zastąp domyślny kod w Cards.gs tym kodem:

var FIELDNAMES = ['Date', 'Amount', 'Description', 'Spreadsheet URL'];

/**
 * Creates the main card users see with form inputs to log expenses.
 * Form can be prefilled with values.
 *
 * @param {String[]} opt_prefills Default values for each input field.
 * @param {String} opt_status Optional status displayed at top of card.
 * @returns {Card}
 */
function createExpensesCard(opt_prefills, opt_status) {
  var card = CardService.newCardBuilder();
  card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
  
  if (opt_status) {
    if (opt_status.indexOf('Error: ') == 0) {
      opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
    } else {
      opt_status = '<font color=\'#228B22\'>' + opt_status + '</font>';
    }
    var statusSection = CardService.newCardSection();
    statusSection.addWidget(CardService.newTextParagraph()
      .setText('<b>' + opt_status + '</b>'));
    card.addSection(statusSection);
  }
  
  var formSection = createFormSection(CardService.newCardSection(),
                                      FIELDNAMES, opt_prefills);
  card.addSection(formSection);
  
  return card;
}

/**
 * Creates form section to be displayed on card.
 *
 * @param {CardSection} section The card section to which form items are added.
 * @param {String[]} inputNames Names of titles for each input field.
 * @param {String[]} opt_prefills Default values for each input field.
 * @returns {CardSection}
 */
function createFormSection(section, inputNames, opt_prefills) {
  for (var i = 0; i < inputNames.length; i++) {
    var widget = CardService.newTextInput()
      .setFieldName(inputNames[i])
      .setTitle(inputNames[i]);
    if (opt_prefills && opt_prefills[i]) {
      widget.setValue(opt_prefills[i]);
    }
    section.addWidget(widget);
  }
  return section;
}

Funkcja createExpensesCard przyjmuje jako argument opcjonalny tablicę wartości, które mają zostać wstępnie wypełnione w formularzu. Funkcja może wyświetlać opcjonalny komunikat o stanie, który jest wyświetlany na czerwono, jeśli stan zaczyna się od „Error:”, a w pozostałych przypadkach na zielono. Zamiast dodawać każde pole do formularza ręcznie, funkcja pomocnicza o nazwie createFormSection wykonuje pętlę procesu tworzenia widżetów wprowadzania tekstu, ustawia każdą wartość domyślną za pomocą setValue, a następnie dodaje widżety do odpowiednich sekcji na karcie.

Teraz zastąp domyślny kod w pliku Helpers.gs tym kodem:

/**
 * Finds largest dollar amount from email body.
 * Returns null if no dollar amount is found.
 *
 * @param {Message} message An email message.
 * @returns {String}
 */
function getLargestAmount(message) {
  return 'TODO';
}

/**
 * Determines date the email was received.
 *
 * @param {Message} message An email message.
 * @returns {String}
 */
function getReceivedDate(message) {
  return 'TODO';
}

/**
 * Determines expense description by joining sender name and message subject.
 *
 * @param {Message} message An email message.
 * @returns {String}
 */
function getExpenseDescription(message) {
  return 'TODO';
}

/**
 * Determines most recent spreadsheet URL.
 * Returns null if no URL was previously submitted.
 *
 * @returns {String}
 */
function getSheetUrl() {
  return 'TODO';
}

Funkcje w Helpers.gs są wywoływane przez getContextualAddon, aby określić wstępnie wypełnione wartości w formularzu. Na razie te funkcje będą zwracać tylko ciąg „TODO”, ponieważ logikę wstępnego wypełniania zaimplementujesz w późniejszym kroku.

Następnie zaktualizuj kod w pliku GetContextualAddon.gs, aby korzystał z kodu w plikach Cards.gsHelpers.gs. Zastąp kod w GetContextualAddon.gs tym kodem:

/**
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Returns the contextual add-on data that should be rendered for
 * the current e-mail thread. This function satisfies the requirements of
 * an 'onTriggerFunction' and is specified in the add-on's manifest.
 *
 * @param {Object} event Event containing the message ID and other context.
 * @returns {Card[]}
 */
function getContextualAddOn(event) {
  var message = getCurrentMessage(event);
  var prefills = [getReceivedDate(message),
                  getLargestAmount(message),
                  getExpenseDescription(message),
                  getSheetUrl()];
  var card = createExpensesCard(prefills);

  return [card.build()];
}

/**
 * Retrieves the current message given an action event object.
 * @param {Event} event Action event object
 * @return {Message}
 */
function getCurrentMessage(event) {
  var accessToken = event.messageMetadata.accessToken;
  var messageId = event.messageMetadata.messageId;
  GmailApp.setCurrentMessageAccessToken(accessToken);
  return GmailApp.getMessageById(messageId);
}

Zwróć uwagę na nową funkcję getCurrentMessage, która używa zdarzenia dostarczonego przez Gmaila do odczytania aktualnie otwartej wiadomości użytkownika. Aby ta funkcja działała, dodaj do pliku manifestu skryptu dodatkowy zakres, który umożliwia dostęp do wiadomości w Gmailu tylko do odczytu.

appscript.json zaktualizuj oauthScopes, aby żądał też zakresu https://www.googleapis.com/auth/gmail.addons.current.message.readonly.

"oauthScopes": [
  "https://www.googleapis.com/auth/gmail.addons.execute",
   "https://www.googleapis.com/auth/gmail.addons.current.message.readonly"
],

Uruchom dodatek w Gmailu i przyznaj mu uprawnienia do wyświetlania e-maili. Pola formularza są teraz wstępnie wypełnione tekstem „TODO”.

5. Praca z Arkuszami Google

Dodatek Expense It! ma formularz, w którym użytkownik może wpisać szczegóły wydatku, ale te szczegóły nie mają gdzie trafić. Dodajmy przycisk, który wysyła dane z formularza do Arkusza Google.

Aby dodać przycisk, użyjemy klasy ButtonSet. Do komunikacji z Arkuszami Google użyjemy usługi Arkuszy Google.

Zmodyfikuj createFormSection, aby w sekcji formularza na karcie pojawił się przycisk „Prześlij”. Wykonaj te czynności:

  1. Utwórz przycisk tekstowy za pomocą CardService.newTextButton() i oznacz go jako „Prześlij” za pomocą CardService.TextButton.setText().
  2. Zaprojektuj przycisk tak, aby po jego kliknięciu wywoływane było to działanie submitForm za pomocą CardService.TextButton.setOnClickAction():
/**
 * Logs form inputs into a spreadsheet given by URL from form.
 * Then displays edit card.
 *
 * @param {Event} e An event object containing form inputs and parameters.
 * @returns {Card}
 */
function submitForm(e) {
  var res = e['formInput'];
  try {
    FIELDNAMES.forEach(function(fieldName) {
      if (! res[fieldName]) {
        throw 'incomplete form';
      }
    });
    var sheet = SpreadsheetApp
      .openByUrl((res['Spreadsheet URL']))
      .getActiveSheet();
    sheet.appendRow(objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1)));
    return createExpensesCard(null, 'Logged expense successfully!').build();
  }
  catch (err) {
    if (err == 'Exception: Invalid argument: url') {
      err = 'Invalid URL';
      res['Spreadsheet URL'] = null;
    }
    return createExpensesCard(objToArray(res, FIELDNAMES), 'Error: ' + err).build();
  }
}

/**
 * Returns an array corresponding to the given object and desired ordering of keys.
 *
 * @param {Object} obj Object whose values will be returned as an array.
 * @param {String[]} keys An array of key names in the desired order.
 * @returns {Object[]}
 */
function objToArray(obj, keys) {
  return keys.map(function(key) {
    return obj[key];
  });
}
  1. Utwórz widżet zestawu przycisków za pomocą CardService.newButtonSet() i dodaj do niego przycisk tekstowy za pomocą CardService.ButtonSet.addButton().
  2. Dodaj widżet zestawu przycisków do sekcji formularza karty za pomocą CardService.CardSection.addWidget().

Wystarczy kilka wierszy kodu, aby otworzyć arkusz kalkulacyjny za pomocą adresu URL, a następnie dodać do niego wiersz danych. Pamiętaj, że dane wejściowe formularza są przekazywane do funkcji w ramach zdarzenia e, a my sprawdzamy, czy użytkownik podał wszystkie pola. Jeśli nie wystąpią żadne błędy, utworzymy pustą kartę wydatków ze stanem „korzystny”. Jeśli wykryjemy błąd, zwrócimy wypełnioną kartę wraz z komunikatem o błędzie. Funkcja pomocnicza objToArray ułatwia przekształcanie odpowiedzi z formularza w tablicę, którą można następnie dołączyć do arkusza kalkulacyjnego.

Na koniec ponownie zaktualizuj sekcję oauthScopesappsscript.json i poproś o zakres https://www.googleapis.com/auth/spreadsheets. Po autoryzacji ten zakres umożliwia dodatkowi odczytywanie i modyfikowanie Arkuszy Google użytkownika.

"oauthScopes": [
  "https://www.googleapis.com/auth/gmail.addons.execute",
  "https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
  "https://www.googleapis.com/auth/spreadsheets"
],

Jeśli nie masz jeszcze nowego arkusza kalkulacyjnego, utwórz go na stronie https://docs.google.com/spreadsheets/.

Uruchom ponownie dodatek i spróbuj przesłać formularz. W polu formularza URL arkusza kalkulacyjnego wpisz pełny adres URL docelowego adresu URL.

6. Przechowywanie wartości za pomocą usługi Properties Service

Użytkownicy często rejestrują wiele wydatków w tym samym arkuszu kalkulacyjnym, więc warto zaoferować najnowszy adres URL arkusza kalkulacyjnego jako wartość domyślną na karcie. Aby poznać najnowszy adres URL arkusza kalkulacyjnego, musimy zapisywać te informacje za każdym razem, gdy używasz dodatku.

Usługa Properties umożliwia przechowywanie par klucz-wartość. W naszym przypadku odpowiednim kluczem będzie „SPREADSHEET_URL”, a wartością – sam adres URL. Aby zapisać taką wartość, musisz zmodyfikować submitFormCards.gs w taki sposób, aby adres URL arkusza był zapisywany jako właściwość po dodaniu do niego nowego wiersza.

Pamiętaj, że właściwości mogą mieć jeden z 3 zakresów: skrypt, użytkownik lub dokument. Zakres dokumentu nie ma zastosowania do dodatków w Gmailu, ale jest istotny w przypadku innego typu dodatków, gdy przechowują one informacje dotyczące konkretnego dokumentu Google lub arkusza. W przypadku naszego dodatku oczekiwane działanie polega na tym, że użytkownik widzi swój najnowszy arkusz kalkulacyjny (a nie arkusz innej osoby) jako opcję domyślną w formularzu. Dlatego wybieramy zakres użytkownik zamiast zakresu skrypt.

Użyj PropertiesService.getUserProperties().setProperty(), aby zapisać adres URL arkusza kalkulacyjnego. Dodaj do pliku submitForm w Cards.gs te informacje:

PropertiesService.getUserProperties().setProperty('SPREADSHEET_URL', 
    res['Spreadsheet URL']);

Następnie zmień funkcję getSheetUrlHelpers.gs, aby zwracała zapisaną usługę, dzięki czemu użytkownik będzie widzieć najnowszy adres URL za każdym razem, gdy użyje dodatku. Aby uzyskać wartość właściwości, użyj PropertiesService.getUserProperties().getProperty().

/**
 * Determines most recent spreadsheet URL.
 * Returns null if no URL was previously submitted.
 *
 * @returns {String}
 */
function getSheetUrl() {
  return PropertiesService.getUserProperties().getProperty('SPREADSHEET_URL');
}

Aby uzyskać dostęp do usługi Property, skrypt musi też mieć autoryzację. Dodaj zakres https://www.googleapis.com/auth/script.storage do pliku manifestu, aby dodatek mógł odczytywać i zapisywać informacje o usłudze.

7. Analizowanie wiadomości w Gmailu

Aby zaoszczędzić czas użytkowników, wstępnie wypełnijmy formularz odpowiednimi informacjami o wydatkach z e-maila. W Helpers.gs mamy już funkcje, które odgrywają tę rolę, ale do tej pory zwracały one tylko „TODO” w przypadku daty, kwoty i opisu wydatku.

Możemy na przykład uzyskać datę otrzymania e-maila i użyć jej jako domyślnej wartości daty wydatku.

/**
 * Determines date the email was received.
 *
 * @param {Message} message - The message currently open.
 * @returns {String}
 */
function getReceivedDate(message) {
  return message.getDate().toLocaleDateString();
}

Zaimplementuj pozostałe 2 funkcje:

  1. getExpenseDescription może obejmować połączenie nazwy nadawcy i tematu wiadomości, ale istnieją bardziej zaawansowane sposoby analizowania treści wiadomości i dostarczania jeszcze dokładniejszego opisu.
  2. W przypadku getLargestAmount warto poszukać konkretnych symboli związanych z pieniędzmi. Na paragonach często podane są różne wartości, np. podatki i inne opłaty. Zastanów się, jak możesz określić prawidłową kwotę. Wyrażenia regularne też mogą być przydatne.

Jeśli potrzebujesz dodatkowej inspiracji, zapoznaj się z dokumentacją referencyjną dotyczącą GmailMessage lub sprawdź kod rozwiązania pobrany na początku ćwiczeń z programowania. Gdy opracujesz własne implementacje wszystkich funkcji w Helpers.gs, wypróbuj dodatek. Otwórz rachunki i zacznij je rejestrować w arkuszu kalkulacyjnym.

8. Wyczyść formularz za pomocą działań na karcie

Co się stanie, jeśli funkcja Expense It! błędnie zidentyfikuje wydatek w otwartym e-mailu i wstępnie wypełni formularz nieprawidłowymi informacjami? Użytkownik czyści formularz. Klasa CardAction umożliwia określenie funkcji, która jest wywoływana po kliknięciu działania. Użyjmy go, aby umożliwić użytkownikowi szybkie wyczyszczenie formularza.

Zmodyfikuj funkcję createExpensesCard tak, aby zwracana przez nią karta zawierała działanie karty o nazwie „Wyczyść formularz”, a po kliknięciu wywoływała tę funkcję clearForm, którą możesz wkleić do Cards.gs. Aby po wyczyszczeniu formularza komunikat o stanie pozostał widoczny, musisz przekazać do działania parametr o nazwie „Status” z wartością opt_status. Pamiętaj, że parametry opcjonalne działań muszą być typu Object.<string, string>, więc jeśli opt_status jest niedostępny, przekaż {'Status' : ''}.

/**
 * Recreates the main card without prefilled data.
 *
 * @param {Event} e An event object containing form inputs and parameters.
 * @returns {Card}
 */
function clearForm(e) {
  return createExpensesCard(null, e['parameters']['Status']).build();
}

9. Utwórz arkusz kalkulacyjny

Oprócz edytowania istniejącego arkusza kalkulacyjnego za pomocą Google Apps Script możesz też tworzyć zupełnie nowe arkusze kalkulacyjne. W przypadku naszego dodatku zezwólmy użytkownikowi na utworzenie arkusza kalkulacyjnego dotyczącego wydatków. Aby rozpocząć, dodaj do karty, którą zwraca createExpensesCard, tę sekcję karty:

var newSheetSection = CardService.newCardSection();
var sheetName = CardService.newTextInput()
  .setFieldName('Sheet Name')
  .setTitle('Sheet Name');
var createExpensesSheet = CardService.newAction()
  .setFunctionName('createExpensesSheet');
var newSheetButton = CardService.newTextButton()
  .setText('New Sheet')
  .setOnClickAction(createExpensesSheet);
newSheetSection.addWidget(sheetName);
newSheetSection.addWidget(CardService.newButtonSet().addButton(newSheetButton));
card.addSection(newSheetSection);

Gdy użytkownik kliknie przycisk „Nowy arkusz”, dodatek wygeneruje nowy arkusz kalkulacyjny sformatowany z zamrożonym wierszem nagłówka, który jest zawsze widoczny. Użytkownik określa tytuł nowego arkusza kalkulacyjnego w formularzu, chociaż dobrym rozwiązaniem może być uwzględnienie wartości domyślnej na wypadek, gdyby formularz był pusty. W implementacji createExpensesSheet zwróć kartę niemal identyczną z dotychczasową, ale z odpowiednim komunikatem o stanie oraz wstępnie wypełnionym polem adresu URL adresem URL nowego arkusza kalkulacyjnego.

10. Gratulacje!

Udało Ci się zaprojektować i wdrożyć dodatek w Gmailu, który znajduje w e-mailu informacje o wydatkach i pomaga użytkownikom w ciągu kilku sekund zapisywać je w arkuszu kalkulacyjnym. Używasz Google Apps Script do komunikacji z wieloma interfejsami API Google i przechowujesz dane między wieloma wykonaniami dodatku.

Możliwe ulepszenia

Ulepszając aplikację Expense It!, kieruj się wyobraźnią. Oto kilka pomysłów na to, jak zwiększyć jej użyteczność:

  • Link do arkusza kalkulacyjnego po zarejestrowaniu wydatku przez użytkownika
  • Dodanie możliwości edytowania lub cofania rejestrowania wydatków
  • Zintegruj zewnętrzne interfejsy API, aby umożliwić użytkownikom dokonywanie płatności i wysyłanie próśb o pieniądze.

Więcej informacji