Zbieranie kontaktów w Google Chat i zarządzanie nimi

W tym samouczku pokazujemy, jak utworzyć aplikację Google Chat, która pomaga użytkownikom Google Chat zarządzać kontaktami osobistymi i biznesowymi. Aby zbierać informacje, aplikacja Chat prosi użytkowników o wypełnienie formularza kontaktowego w wiadomościach w postaci kart i oknach.

Zobacz, jak działa aplikacja Google Chat:

  • Formularz kontaktowy z polecenia po ukośniku.
    Rysunek 1. Aplikacja do czatu odpowiada na polecenie /about wiadomością tekstową i przyciskiem, który otwiera formularz kontaktowy.
  • Formularz kontaktowy w oknie.
    Rysunek 2. Aplikacja do czatu otwiera okno, w którym użytkownicy mogą wpisać informacje o kontakcie.
  • Okno potwierdzenia i sprawdzania.
    Rysunek 3. Aplikacja do czatu wyświetla okno potwierdzenia, aby użytkownicy mogli przejrzeć i potwierdzić informacje przed przesłaniem.
  • Wiadomość tekstowa potwierdzająca dodanie nowego kontaktu.
    Rysunek 4. Po przesłaniu formularza przez użytkownika aplikacja Chat wysyła prywatną wiadomość tekstową z potwierdzeniem przesłania.
  • formularz kontaktowy z wiadomości na karcie,
    Rysunek 5. Aplikacja Google Chat wyświetla też użytkownikom prośbę o dodanie kontaktu z karty w wiadomości.

Wymagania wstępne

Cele

Architektura

Aplikacja do obsługi czatu jest zbudowana w Google Apps Script i używa zdarzeń interakcji do przetwarzania i odpowiadania na wiadomości użytkowników Google Chat.

Poniżej pokazujemy, jak użytkownik może zwykle korzystać z aplikacji Chat:

  1. Użytkownik otwiera czat z aplikacją Google Chat lub dodaje aplikację Google Chat do istniejącego pokoju.

  2. Aplikacja Google Chat prosi użytkownika o dodanie kontaktu, tworząc i wyświetlając formularz kontaktowy jako obiekt card. Aby wyświetlić formularz kontaktowy, aplikacja Chat odpowiada użytkownikom w ten sposób:

    • Odpowiada na wzmianki i czaty za pomocą wiadomości z kartą zawierającą formularz kontaktowy.
    • Odpowiada na polecenie po ukośniku /addContact, otwierając okno z formularzem kontaktowym.
    • Odpowiada na polecenie z ukośnikiem /about wiadomością tekstową z przyciskiem Dodaj kontakt, który użytkownicy mogą kliknąć, aby otworzyć okno z formularzem kontaktowym.
  3. Gdy użytkownik zobaczy formularz kontaktowy, wpisuje dane kontaktowe w tych polach i widżetach:

  4. Aplikacja Google Chat obsługuje CARD_CLICKEDzdarzenie interakcjiCARD_CLICKED, aby przetwarzać wartości wprowadzane przez użytkownika, i wyświetla je na karcie potwierdzenia.

  5. Użytkownik sprawdza kartę potwierdzenia i klika przycisk Prześlij, aby sfinalizować podawanie danych kontaktowych.

  6. Aplikacja Google Chat wysyła prywatną wiadomość tekstową, która potwierdza przesłanie.

Przygotowywanie środowiska

W tej sekcji dowiesz się, jak utworzyć i skonfigurować projekt Google Cloud na potrzeby aplikacji do obsługi czatu.

Tworzenie projektu Google Cloud

Google Cloud Console

  1. W konsoli Google Cloud kliknij Menu  > Administracja > Utwórz projekt.

    Otwórz stronę Tworzenie projektu

  2. W polu Nazwa projektu wpisz opisową nazwę projektu.

    Opcjonalnie: aby edytować identyfikator projektu, kliknij Edytuj. Po utworzeniu projektu nie można zmienić jego identyfikatora, więc wybierz taki, który będzie Ci odpowiadać przez cały okres jego istnienia.

  3. W polu Lokalizacja kliknij Przeglądaj, aby wyświetlić potencjalne lokalizacje projektu. Następnie kliknij Wybierz.
  4. Kliknij Utwórz. W konsoli Google Cloud otworzy się strona Panel, a projekt zostanie utworzony w ciągu kilku minut.

interfejs wiersza poleceń gcloud

W jednym z tych środowisk programistycznych uzyskaj dostęp do interfejsu Google Cloud CLI (gcloud):

  • Cloud Shell: aby używać terminala online z już skonfigurowanym interfejsem gcloud CLI, aktywuj Cloud Shell.
    Aktywuj Cloud Shell
  • Lokalna powłoka: aby używać lokalnego środowiska programistycznego, zainstaluj i zainicjuj interfejs wiersza poleceń gcloud.
    Aby utworzyć projekt w Google Cloud, użyj polecenia gcloud projects create:
    gcloud projects create PROJECT_ID
    Zastąp PROJECT_ID identyfikatorem projektu, który chcesz utworzyć.

Konfigurowanie uwierzytelniania i autoryzacji

Aplikacje Google Chat wymagają skonfigurowania ekranu zgody OAuth, aby użytkownicy mogli autoryzować aplikację w usługach Google Workspace, w tym w Google Chat.

W tym samouczku wdrożysz aplikację do obsługi czatu, która jest przeznaczona tylko do testowania i użytku wewnętrznego, więc możesz użyć informacji zastępczych na ekranie zgody. Przed opublikowaniem aplikacji do czatu zastąp wszystkie informacje zastępcze prawdziwymi danymi.

  1. W konsoli Google Cloud otwórz Menu  > > Branding.

    Otwórz Promowanie marki

  2. Jeśli masz już skonfigurowany ekran akceptacji OAuth, możesz skonfigurować te ustawienia w sekcjach Branding, Odbiorcy i Dostęp do danych. Jeśli zobaczysz komunikat Jeszcze nie skonfigurowano, kliknij Rozpocznij:

    1. W sekcji Informacje o aplikacji w polu Nazwa aplikacji wpisz Contact Manager.
    2. W sekcji Adres e-mail pomocy dla użytkowników wybierz swój adres e-mail lub odpowiednią grupę dyskusyjną Google.
    3. Kliknij Dalej.
    4. W sekcji Odbiorcy wybierz Wewnętrzny. Jeśli nie możesz wybrać opcji Wewnętrzny, wybierz Zewnętrzny.
    5. Kliknij Dalej.
    6. W sekcji Dane kontaktowe wpisz adres e-mail, na który będziesz otrzymywać powiadomienia o wszelkich zmianach w projekcie.
    7. Kliknij Dalej.
    8. W sekcji Zakończ zapoznaj się z zasadami dotyczącymi danych użytkownika w usługach interfejsu API Google. Jeśli je akceptujesz, kliknij Akceptuję zasady dotyczące danych użytkownika w usługach interfejsu API Google.
    9. Kliknij Dalej.
    10. Kliknij Utwórz.
    11. Jeśli jako typ użytkownika wybierzesz Zewnętrzny, dodaj użytkowników testowych:
      1. Kliknij Odbiorcy.
      2. W sekcji Użytkownicy testowi kliknij Dodaj użytkowników.
      3. Wpisz swój adres e-mail i adresy e-mail innych autoryzowanych testerów, a następnie kliknij Zapisz.

Tworzenie i wdrażanie aplikacji Google Chat

W następnej sekcji skopiujesz i zaktualizujesz cały projekt Apps Script, który zawiera cały wymagany kod aplikacji do obsługi aplikacji do obsługi czatu. Nie musisz więc kopiować i wklejać każdego pliku.

Opcjonalnie możesz wyświetlić cały projekt na GitHubie.

Wyświetl w GitHubie

Oto omówienie poszczególnych plików:

main.gs

Obsługuje całą logikę aplikacji, w tym zdarzenia interakcji, takie jak wysyłanie wiadomości do aplikacji Google Chat, klikanie przycisków w wiadomościach aplikacji Google Chat oraz otwieranie i zamykanie okien.

Wyświetl main.gs kod

apps-script/contact-form-app/main.gs
/**
 * Copyright 2024 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
 *
 * http://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.
 */

/**
 * Responds to a MESSAGE interaction event in Google Chat.
 *
 * @param {Object} event the MESSAGE interaction event from Chat API.
 * @return {Object} message response that opens a dialog or sends private
 *                          message with text and card.
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {
      case 1:
        // If the slash command is "/about", responds with a text message and button
        // that opens a dialog.
        return {
          text: "Manage your personal and business contacts 📇. To add a " +
                  "contact, use the slash command `/addContact`.",
          accessoryWidgets: [{
            buttonList: { buttons: [{
              text: "Add Contact",
              onClick: { action: {
                function: "openInitialDialog",
                interaction: "OPEN_DIALOG"
              }}
            }]}
          }]
        }
      case 2:
        // If the slash command is "/addContact", opens a dialog.
        return openInitialDialog();
    }
  }

  // If user sends the Chat app a message without a slash command, the app responds
  // privately with a text and card to add a contact.
  return {
    privateMessageViewer: event.user,
    text: "To add a contact, try `/addContact` or complete the form below:",
    cardsV2: [{
      cardId: "addContactForm",
      card: {
        header: { title: "Add a contact" },
        sections:[{ widgets: CONTACT_FORM_WIDGETS.concat([{
          buttonList: { buttons: [{
            text: "Review and submit",
            onClick: { action: { function : "openConfirmation" }}
          }]}
        }])}]
      }
    }]
  };
}

/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

/**
  * Validates and submits information from a dialog or card message
  * and notifies status.
  *
  * @param {Object} event the interactive event with parameters.
  * @return {Object} a message response that opens a dialog or posts a private
  *                  message.
  */
function submitForm(event) {
  const contactName = event.common.parameters["contactName"];
  // Checks to make sure the user entered a contact name.
  // If no name value detected, returns an error message.
  const errorMessage = "Don't forget to name your new contact!";
  if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  }
  if (!contactName) {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }

  // The Chat app indicates that it received form data from the dialog or card.
  // Sends private text message that confirms submission.
  const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: { actionStatus: {
          statusCode: "OK",
          userFacingMessage: "Success " + contactName
        }}
      }
    };
  }
  return {
    actionResponse: { type: "NEW_MESSAGE" },
    privateMessageViewer: event.user,
    text: confirmationMessage
  };
}

/**
 * Extracts form input value for a given widget.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @param {String} widgetName a unique ID for the widget, specified in the widget's name field.
 * @returns the value inputted by the user, null if no value can be found.
 */
function fetchFormValue(event, widgetName) {
  const formItem = event.common.formInputs[widgetName][""];
  // For widgets that receive StringInputs data, the value input by the user.
  if (formItem.hasOwnProperty("stringInputs")) {
    const stringInput = event.common.formInputs[widgetName][""].stringInputs.value[0];
    if (stringInput != null) {
      return stringInput;
    }
  // For widgets that receive dateInput data, the value input by the user.
  } else if (formItem.hasOwnProperty("dateInput")) {
    const dateInput = event.common.formInputs[widgetName][""].dateInput.msSinceEpoch;
     if (dateInput != null) {
       return dateInput;
     }
  }

  return null;
}

/**
 * Converts date in milliseconds since epoch to user-friendly string.
 *
 * @param {Object} millis the milliseconds since epoch time.
 * @return {string} Display-friend date (English US).
 */
function convertMillisToDateString(millis) {
  const date = new Date(millis);
  const options = { year: 'numeric', month: 'long', day: 'numeric' };
  return date.toLocaleDateString('en-US', options);
}
contactForm.gs

Zawiera widżety, które otrzymują dane z formularza od użytkowników. Te widżety wprowadzania danych w formularzu są wyświetlane na kartach, które pojawiają się w wiadomościach i oknach.

Wyświetl contactForm.gs kod

apps-script/contact-form-app/contactForm.gs
/**
 * Copyright 2024 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
 *
 * http://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.
 */

/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];
appsscript.json

Plik manifestu Apps Script, który definiuje i konfiguruje projekt Apps Script na potrzeby aplikacji w Chat.

Wyświetl appsscript.json kod

apps-script/contact-form-app/appsscript.json
{
  "timeZone": "America/Los_Angeles",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "chat": {}
}

Znajdowanie numeru i identyfikatora projektu Cloud

  1. W konsoli Google Cloud otwórz projekt w Cloud.

    Otwórz konsolę Google Cloud

  2. Kliknij Ustawienia i narzędzia > Ustawienia projektu.

  3. Zapisz wartości w polach Numer projektuIdentyfikator projektu. Użyjesz ich w kolejnych sekcjach.

Tworzenie projektu Apps Script

Aby utworzyć projekt Apps Script i połączyć go z projektem Cloud:

  1. Kliknij ten przycisk, aby otworzyć projekt Zarządzanie kontaktami w Google Chat w Apps Script.
    Otwórz projekt
  2. Kliknij  Przegląd.
  3. Na stronie przeglądu kliknij Ikona tworzenia kopii Utwórz kopię.
  4. Nadaj nazwę kopii projektu Apps Script:

    1. Kliknij Kopia artykułu Zarządzanie kontaktami w Google Chat.

    2. W polu Tytuł projektu wpisz Contact Manager - Google Chat app.

    3. Kliknij Zmień nazwę.

Ustawianie projektu Cloud w projekcie Apps Script

  1. W projekcie Apps Script kliknij Ikona ustawień projektu Ustawienia projektu.
  2. W sekcji Projekt Google Cloud Platform (GCP) kliknij Zmień projekt.
  3. W sekcji Numer projektu GCP wklej numer projektu Cloud.
  4. Kliknij Ustaw projekt. Projekt w chmurze i projekt Apps Script zostały połączone.

Tworzenie wdrożenia Apps Script

Gdy cały kod będzie już gotowy, wdróż projekt Apps Script. Identyfikator wdrożenia jest używany podczas konfigurowania aplikacji do obsługi czatu w Google Cloud.

  1. W Apps Script otwórz projekt aplikacji Google Chat.

    Otwórz Apps Script

  2. Kliknij Wdróż > Nowe wdrożenie.

  3. Jeśli Dodatek nie jest jeszcze wybrany, obok Wybierz typ kliknij typy wdrożenia Ikona ustawień projektu i wybierz Dodatek.

  4. W polu Opis wpisz opis tej wersji, np. Test of Contact Manager.

  5. Kliknij Wdróż. Apps Script zgłasza udane wdrożenie i podaje identyfikator wdrożenia.

  6. Kliknij  Kopiuj, aby skopiować identyfikator wdrożenia, a następnie kliknij Gotowe.

Konfigurowanie aplikacji Chat w konsoli Google Cloud

W tej sekcji dowiesz się, jak skonfigurować interfejs Google Chat API w konsoli Google Cloud, podając informacje o aplikacji do obsługi czatu, w tym identyfikator wdrożenia, które zostało utworzone w projekcie Apps Script.

  1. W konsoli Google Cloud kliknij Menu > Więcej usług > Google Workspace > Biblioteka usług > Google Chat API > Zarządzaj > Konfiguracja.

    Otwórz konfigurację interfejsu Chat API

  2. W polu Nazwa aplikacji wpisz Contact Manager.

  3. W polu URL awatara wpisz https://developers.google.com/chat/images/contact-icon.png.

  4. W polu Opis wpisz Manage your personal and business contacts.

  5. Ustaw przełącznik Włącz funkcje interaktywne w pozycji włączonej.

  6. W sekcji Funkcje wybierz Dołączanie do pokoi i rozmów grupowych.

  7. W sekcji Ustawienia połączenia wybierz Apps Script.

  8. W polu Identyfikator wdrożenia wklej identyfikator wdrożenia Apps Script skopiowany w poprzedniej sekcji podczas tworzenia wdrożenia Apps Script.

  9. W sekcji Commands (Polecenia) skonfiguruj polecenia rozpoczynające się ukośnikiem /about i /addContact:

    1. Aby skonfigurować pierwsze polecenie po ukośniku, kliknij Dodaj polecenie po ukośniku.
    2. W polu Nazwa wpisz About.
    3. W polu Identyfikator polecenia wpisz 1.
    4. W polu Opis wpisz Learn how to use this Chat app to manage your contacts.
    5. W sekcji Typ polecenia kliknij Slash command.
    6. W polu Nazwa polecenia po ukośniku wpisz /about.
    7. Kliknij Otwiera okno.
    8. Kliknij Gotowe.
    9. Aby skonfigurować kolejne polecenie po ukośniku, kliknij Dodaj polecenie.
    10. W polu Nazwa wpisz Add a contact.
    11. W polu Identyfikator polecenia wpisz 2.
    12. W polu Opis wpisz Submit information about a contact.
    13. W sekcji Typ polecenia kliknij Slash command.
    14. W polu Nazwa polecenia po ukośniku wpisz /addContact.
    15. Kliknij Otwiera okno.
    16. Kliknij Gotowe.
  10. W sekcji Widoczność zaznacz pole wyboru Udostępnij tę aplikację do obsługi czatu konkretnym osobom i grupom w domenie YOUR DOMAIN i wpisz swój adres e-mail.

  11. W sekcji Logi wybierz Loguj błędy w usłudze Logging.

  12. Kliknij Zapisz. Pojawi się komunikat o zapisaniu konfiguracji.

Aplikacja Chat jest gotowa do zainstalowania i przetestowania w Chat.

Testowanie aplikacji Google Chat

Aby przetestować aplikację do obsługi czatu, otwórz pokój czatu z aplikacją i wyślij wiadomość:

  1. Otwórz Google Chat, korzystając z konta Google Workspace, które zostało podane podczas dodawania siebie jako zaufanego testera.

    Otwórz Google Chat

  2. Kliknij  Nowy czat.
  3. W polu Dodaj co najmniej 1 osobę wpisz nazwę aplikacji Chat.
  4. Wybierz aplikację Chat z wyników. Otworzy się czat.

  1. Na nowym czacie z aplikacją Google Chat wpisz /addContact i naciśnij Enter.

  2. W wyświetlonym oknie podaj dane kontaktowe:

    1. W polu tekstowym Imię i nazwisko wpisz nazwę.
    2. W selektorze daty Data urodzenia wybierz datę.
    3. W sekcji Typ kontaktu kliknij Służbowy lub Prywatny.
  3. Kliknij Sprawdź i prześlij.

  4. W oknie potwierdzenia sprawdź przesłane informacje i kliknij Prześlij. Aplikacja Chat odpowie SMS-em z tekstem CONTACT NAME has been added to your contacts..

  5. Opcjonalnie możesz też przetestować i przesłać formularz kontaktowy w jeden z tych sposobów:

    • Użyj polecenia po ukośniku /about. Aplikacja do obsługi czatu odpowiada wiadomością tekstową i przyciskiem widżetu akcesoriów z tekstem Add a contact. Możesz kliknąć ten przycisk, aby otworzyć okno z formularzem kontaktowym.
    • Wyślij do aplikacji Google Chat wiadomość na czacie bez polecenia po ukośniku, np. Hello. Aplikacja Chat odpowie tekstem i kartą zawierającą formularz kontaktowy.

Czyszczenie danych

Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby zużyte w tym samouczku, zalecamy usunięcie projektu w Cloud.

  1. W konsoli Google Cloud otwórz stronę Zarządzanie zasobami. Kliknij Menu > Administracja > Zarządzaj zasobami.

    Otwórz Menedżera zasobów

  2. Na liście projektów wybierz projekt, który chcesz usunąć, a potem kliknij Usuń .
  3. W oknie wpisz identyfikator projektu i kliknij Wyłącz, aby usunąć projekt.