unity wiedza

Czas czytania: 13 minut

Jak przeprowadzić integrację Google z API?

Z poniższego artykułu dowiesz się:

  • Jak praktycznie podejść do tematu integracji?
  • Jak skonfigurować swoje środowisko pracy?
  • Jak zintegrować się z wybranymi usługami Google?

Tworzenie nowego projektu 

W dzisiejszych czasach ciężko spotkać ludzi, którzy nie korzystają z Internetu. Wiele osób nie potrafi sobie wyobrazić codziennej pracy bez użycia takich narzędzi jak: Google Mail, Google Drive, Google Docs. W poniższym artykule przedstawię, w jaki sposób możemy zintegrować się z API wybranych usług Google. 

Od czego należy zacząć? Pierwszym etapem jest zainstalowanie kilku narzędzi: 

  • JDK 1.8 
  • IDE IntelliJ IDEA 
  • Maven 3.5.x 

Następnie należy założyć konto Google – poniższa integracja z usługami Google została wykonana w oparciu o konto: unitysatest@gmail.com 

Na początku otwieramy stronę https://console.developers.google.com i tworzymy projekt np. testAPI.

Kolejnym działaniem jest znalezienie i dodanie API usług Google, z którymi chcemy się zintegrować. Na zakładce „Dashboard” klikamy „ENABLE APIS AND SERVICES”, wyszukujemy następujące pakiety usług: Google Drive API, Gmail API, Google Sheets API. Każdy z nich aktywujemy poprzez kliknięcie przycisku „ENABLE”.

Udzielanie uprawnień i tokeny dostępu 

Usługi Google np. Gmail posiadają dostęp do poufnych danych użytkownika, dlatego niektóre żądania wymagają kroku uwierzytelnienia, w którym użytkownik loguje się przy pomocy swojego konta Google. Po zalogowaniu użytkownik jest pytany, czy chce udzielić uprawień, o które prosi aplikacja. Ten typ autoryzacji jest realizowany poprzez protokół OAuth. 

Jeśli użytkownik wyrazi zgodę, serwer autoryzacji Google prześle aplikacji token dostępu (ang. access token) lub kod autoryzacji (ang. authorization code), za pomocą którego aplikacja może uzyskać token dostępu. Jeśli użytkownik nie zgodzi się na uprawnienia, serwer zwróci błąd. 

Tokeny dostępu są ważne tylko dla zestawów operacji podanych w zakresie żądania. Jeśli na przykład zostanie wydany token dostępu do interfejsu Gmail API, nie uzyska on dostępu do interfejsu Google Calendar API. Token dostępu może być używany wiele razy. 

Tokeny dostępu mają ograniczony czas życia. Jeśli aplikacja wymaga dostępu do interfejsu API Google, którego token dostępu wygasł, może uzyskać token odnawiający (ang. refresh token). Token odnawiający umożliwia aplikacji uzyskanie nowych tokenów dostępu. Tokeny należy przechowywać w bezpiecznym miejscu. Warto pamiętać, że mogą one przestać działać z następujących powodów: 

  • Użytkownik odwołał dostęp do aplikacji. 
  • Odnawiający token nie był używany przez sześć miesięcy. 
  • Konto użytkownika przekroczyło maksymalną liczbę przyznanych tokenów odnawiających. Aktualny limit wynosi 50 tokentów na konto użytkownika na klienta. Jeśli limit zostanie osiągnięty, utworzenie nowego tokena odnawiającego automatycznie unieważnia najstarszy token odnawiający bez ostrzeżenia. 

Więcej o implementacji OAuth można przeczytać TUTAJ.

Utworzenie identyfikatora klienta  

W kolejnym kroku klikamy zakładkę „Credentials” na stronie Google APIs, a następnie „OAuth consent screen”. W otwartym oknie podajemy nazwę naszej aplikacji np. testAPI. Dla sekcji „Scopes for Google APIs” klikamy „Add scope” i zaznaczamy wszystkie pozycje dla: Google Drive API, Gmail API i Google Sheets API, następnie klikamy „Add”. Scope to inaczej uprawnienie, które jest potrzebne do wykonania określonych operacji z API. Różne operacje mogą wymagać wielu uprawnień. Dostęp do wybranych uprawnień zdobędziemy po pomyślnej autoryzacji. Na koniec konfiguracji ekranu OAuth klikamy „Save”.  

Przechodzimy do zakładki „Credentials”, klikamy „Create credentials” a następnie „OAuth client ID”.

W otwartym oknie wybierany „Other” i jako nazwę podajemy „Terminal”. Klikamy „Create”. W kolejnym oknie wyświetlone zostaną nam dane potrzebne do autoryzacji OAuth: „Client ID” oraz „Client secret”. Ściągamy utworzoną konfigurację w formacie JSON. Zapisujemy ją do pliku o nazwie „credentials.json”. Wykorzystamy go później w naszej aplikacji.

Właśnie udało nam się dodać biblioteki API oraz skonfigurować potrzebne dane do autoryzacji OAuth! 

Otwieramy https://drive.google.com/drive/my-drive i tworzymy pusty plik Google Sheet o nazwie np. „test”.

Warto przeglądnąć, jakie metody oferuje API. W tym celu otwieramy linki: 

W tym poradniku skorzystamy z następujących metod: 

  • Users.messages: list – wyświetla listę emaili z poczty Gmail 
  • Users.messages: get – pobiera szczegóły dot. Wiadomości email 
  • Files: list – wyświetla listę plików z Dysku Google 
  • spreadsheets.values.update – aktualizuje wartości w arkuszu 

Dla powyższych metod sumarycznie będą potrzebne następujące uprawnienia:  

Przygotowanie requestów 

Kolejnym krokiem jest przygotowanie odpowiednich requestów, które wykonają autentykację, autoryzację oraz wywołają określoną metodę z API. Możemy te requesty przygotować ręcznie, ale z racji tego, że są one dość skomplikowane, warto użyć bibliotek klienckich przygotowanych przez Google. Biblioteki te tworzą odpowiednie zapytania do usług API, dodatkowo dbają o bezpieczne przetwarzanie danych. 

Jeśli chcielibyśmy zobaczyć, jak wyglądają przykładowe requesty, warto skorzystać z narzędzia OAuth 2.0 Playground.

W 1 kroku zaznaczamy potrzebne uprawnienia i wykonujemy autentykacje. 

W 2 kroku po uzyskaniu zezwoleń do określonych uprawnień oraz kodu autoryzacyjnego, wykonujemy operację, w efekcie której uzyskujemy token dostępowy oraz odnawiający

W 3 kroku możemy przetestować dowolną metodę z API Google. Zadziałają tylko te, które dodaliśmy do skonfigurowanej aplikacji „testAPI”, oraz dla których w 1 kroku zaznaczyliśmy wymagane uprawnienia.

Przykładowa aplikacja w Javie 

Poniżej przedstawiono prostą aplikację napisaną w języku Java, która: 

  • Pobiera z konta unitysatest@gmail.com emaile, wyświetla najnowsze. 
  • Łączy się z dyskiem Google, otwiera przygotowany wcześniej arkusz „test”, dodaje do komórki A1 aktualną datę i czas. 

Otwieramy IntelliJ IDEA i tworzymy nowy projekt typu maven. 

W pom.xml dodajemy odpowiednie zależności: 

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
    <modelVersion>4.0.0</modelVersion> 
 
    <groupId>pl.unity</groupId> 
    <artifactId>testAPI</artifactId> 
    <version>1.0-SNAPSHOT</version> 
 
    <properties> 
        <maven.compiler.source>1.8</maven.compiler.source> 
        <maven.compiler.target>1.8</maven.compiler.target> 
    </properties> 
 
    <dependencies> 
        <dependency> 
            <groupId>com.google.oauth-client</groupId> 
            <artifactId>google-oauth-client-jetty</artifactId> 
            <version>1.28.0</version> 
        </dependency> 
        <dependency> 
            <groupId>com.google.api-client</groupId> 
            <artifactId>google-api-client</artifactId> 
            <version>1.28.0</version> 
        </dependency> 
        <dependency> 
            <groupId>com.google.apis</groupId> 
            <artifactId>google-api-services-drive</artifactId> 
            <version>v3-rev136-1.25.0</version> 
        </dependency> 
        <dependency> 
            <groupId>com.google.apis</groupId> 
            <artifactId>google-api-services-gmail</artifactId> 
            <version>v1-rev98-1.25.0</version> 
        </dependency> 
        <dependency> 
            <groupId>com.google.apis</groupId> 
            <artifactId>google-api-services-sheets</artifactId> 
            <version>v4-rev553-1.25.0</version> 
        </dependency> 
    </dependencies> 
</project>  

Do folderu src/main/resources przenosimy ściągnięty wcześniej przygotowany plik: credentials.json. 

W folderze scr/main/java tworzymy klasę o nazwie GoogleApiTestApp. 

Klasa zawiera: 

  • Listę SCOPES – zawiera uprawnienia do wykonywania operacji z API, 
  • Metodę getCredentials() – odpowiedzialna jest za utworzenie zapytań dot. autentykacji i autoryzacji. Zapytania są tworzone w oparciu o dane z pliku credentials.json. Po uzyskaniu zgodny od użytkownika konta, uprawnienia zostają zapisane do folderu tokens. Dzięki temu przy kolejnym uruchomieniu aplikacji nie trzeba pytać ponownie użytkownika o zgodę, 
  • Metodę findAndPrintMessages() – wyszukuje 5 najnowszych emaili z skrzynki pocztowej i wyświetla ich skróconą wersję, 
  • Metodę findAndUpdateSheet() – wyszukuje plik test na dysku Google i modyfikuję pole A1 ustawiając w nim aktualną datę i czas, 
  • Metodę main() – główna metoda, która jest uruchamiana jako pierwsza. 

Cały kod źródłowy klasy został zamieszczony poniżej:

import com.google.api.client.auth.oauth2.Credential; 
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; 
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; 
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; 
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; 
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; 
import com.google.api.client.http.javanet.NetHttpTransport; 
import com.google.api.client.json.JsonFactory; 
import com.google.api.client.json.jackson2.JacksonFactory; 
import com.google.api.client.util.store.FileDataStoreFactory; 
import com.google.api.services.drive.Drive; 
import com.google.api.services.drive.DriveScopes; 
import com.google.api.services.drive.model.FileList; 
import com.google.api.services.gmail.Gmail; 
import com.google.api.services.gmail.GmailScopes; 
import com.google.api.services.gmail.model.ListMessagesResponse; 
import com.google.api.services.gmail.model.Message; 
import com.google.api.services.sheets.v4.Sheets; 
import com.google.api.services.sheets.v4.SheetsScopes; 
import com.google.api.services.sheets.v4.model.UpdateValuesResponse; 
import com.google.api.services.sheets.v4.model.ValueRange; 
 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.security.GeneralSecurityException; 
import java.time.LocalDateTime; 
import java.util.Arrays; 
import java.util.List; 
 
public class GoogleApiTestApp { 
 
    private static final String APPLICATION_NAME "Google API Test App"; 
    private static final JsonFactory JSON_FACTORY JacksonFactory.getDefaultInstance(); 
    private static final String TOKENS_DIRECTORY_PATH "tokens"; 
 
    private static final List<String> SCOPES Arrays.asList( 
            GmailScopes.MAIL_GOOGLE_COM, 
            GmailScopes.GMAIL_MODIFY, 
            GmailScopes.GMAIL_READONLY, 
            DriveScopes.DRIVE, 
            DriveScopes.DRIVE_APPDATA, 
            DriveScopes.DRIVE_FILE, 
            DriveScopes.DRIVE_METADATA, 
            DriveScopes.DRIVE_METADATA_READONLY, 
            DriveScopes.DRIVE_PHOTOS_READONLY, 
            DriveScopes.DRIVE_READONLY, 
            SheetsScopes.SPREADSHEETS, 
            SheetsScopes.SPREADSHEETS_READONLY 
            ); 
 
    private static final String CREDENTIALS_FILE_PATH "/credentials.json"; 
 
    private static Credential getCredentials(final NetHttpTransport  HTTP_TRANSPORT) throws IOException { 
        // Load client secrets. 
        InputStream in =  GoogleApiTestApp.class.getResourceAsStream(CREDENTIALS_FILE_PATH); 
        GoogleClientSecrets clientSecrets =  GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in)); 
 
        // Build flow and trigger user authorization request. 
        GoogleAuthorizationCodeFlow flow = new  GoogleAuthorizationCodeFlow.Builder( 
                HTTP_TRANSPORTJSON_FACTORYclientSecretsSCOPES) 
                .setDataStoreFactory(new FileDataStoreFactory(new  java.io.File(TOKENS_DIRECTORY_PATH))) 
                .setAccessType("offline") 
                .build(); 
        LocalServerReceiver receiver = new  LocalServerReceiver.Builder().setPort(8888).build(); 
        return new AuthorizationCodeInstalledApp(flow,  receiver).authorize("user"); 
    } 
 
    public static void findAndPrintMessages(NetHttpTransport  HTTP_TRANSPORT) throws IOException { 
        Gmail gmailService = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORYgetCredentials(HTTP_TRANSPORT)) 
                .setApplicationName(APPLICATION_NAME) 
                .build(); 
 
        String user = "me"; 
        ListMessagesResponse listMessageResponse = gmailService 
                .users() 
                .messages() 
                .list(user) 
                .setMaxResults(5l) 
                .execute(); 
        List<Message> messages = listMessageResponse.getMessages(); 
        if (messages.isEmpty()) { 
            System.out.println("No message found."); 
        else { 
            System.out.println("Messages:"); 
            for (Message message : messages) { 
                Message fullMessage = gmailService 
                        .users() 
                        .messages() 
                        .get(user,message.getId()) 
                        .setFormat("full") 
                        .execute(); 
                System.out.println(fullMessage.getSnippet()); 
            } 
        } 
    } 
 
    public static void findAndUpdateSheet(NetHttpTransport HTTP_TRANSPORT)  throws IOException { 
        Drive driveService = new Drive.Builder(HTTP_TRANSPORTJSON_FACTORYgetCredentials(HTTP_TRANSPORT)) 
                .setApplicationName(APPLICATION_NAME) 
                .build(); 
 
        FileList result = driveService.files().list() 
                .setQ("name='test'") 
                .setFields("files(id, name)") 
                .execute(); 
 
        Sheets sheetsService = new Sheets.Builder(HTTP_TRANSPORTJSON_FACTORYgetCredentials(HTTP_TRANSPORT)) 
                .setApplicationName(APPLICATION_NAME) 
                .build(); 
 
        String spreadsheetId = null; 
        if(!result.getFiles().isEmpty()) { 
            System.out.printf("%s (%s)\n"result.getFiles().get(0).getName()result.getFiles().get(0).getId()); 
 
            spreadsheetId = result.getFiles().get(0).getId(); 
            String range = "A1"; 
            String valueInputOption = "RAW"; 
 
            List<List<Object>> values = Arrays.asList( 
                    Arrays.asList( 
                            LocalDateTime.now().toString() 
                    ) 
            ); 
            ValueRange requestBody = new ValueRange().setValues(values); 
 
            UpdateValuesResponse response = sheetsService 
                    .spreadsheets() 
                    .values() 
                    .update(spreadsheetIdrangerequestBody) 
                    .setValueInputOption(valueInputOption) 
                    .execute(); 
 
            System.out.println(response); 
        } 
    } 
 
    public static void main(String... argsthrows IOExceptionGeneralSecurityException { 
        final NetHttpTransport HTTP_TRANSPORT =  GoogleNetHttpTransport.newTrustedTransport(); 
        findAndPrintMessages(HTTP_TRANSPORT); 
        findAndUpdateSheet(HTTP_TRANSPORT); 
    } 
}  

 

Po uruchomieniu aplikacji, w logach pojawiają się fragmenty znalezionych emaili, a na dysku Google zostanie zmodyfikowany plik „test”.

Fragmenty kodu źródłowego zostały zaczerpnięte ze stron z dokumentacją API: 

Wyrażam zgodę na przetwarzanie danych osobowych na zasadach określonych w polityce prywatności. Jeśli nie wyrażasz zgody na wykorzystywanie cookies we wskazanych w niej celach, w tym do profilowania, prosimy o wyłącznie cookies w przeglądarce lub opuszczenie serwisu. więcej

Akceptuj