Prześlij załączniki

Interfejs Gmail API umożliwia przesyłanie danych pliku podczas tworzenia lub aktualizowania wersji roboczej albo podczas wstawiania lub wysyłania wiadomości.

Opcje przesyłania

Interfejs Gmail API umożliwia przesyłanie określonych typów danych binarnych lub multimediów. Szczegółowe informacje o danych, które można przesyłać, znajdziesz na stronie referencyjnej każdej metody obsługującej przesyłanie multimediów:

  • Maksymalny rozmiar przesyłanego pliku: maksymalna ilość danych, które można przechowywać przy użyciu tej metody.
  • Accepted media MIME types (Akceptowane typy MIME multimediów): typy danych binarnych, które możesz przechowywać za pomocą tej metody.

Żądania przesłania możesz wysyłać na dowolny z tych sposobów. Określ metodę, której używasz, za pomocą parametru żądania uploadType.

  • Proste przesyłanie: uploadType=media. Do szybkiego przesyłania mniejszych plików, np. o rozmiarze do 5 MB.
  • Przesyłanie wieloczęściowe: uploadType=multipart. Do szybkiego przesyłania mniejszych plików i metadanych. Przesyła plik wraz z metadanymi, które go opisują, w ramach jednego żądania.
  • Przesyłanie z możliwością wznowienia: uploadType=resumable. Zapewnia niezawodny transfer, co jest szczególnie ważne w przypadku większych plików. W tej metodzie używasz żądania inicjującego sesję, które może opcjonalnie zawierać metadane. Jest to dobra strategia w przypadku większości aplikacji, ponieważ działa również w przypadku mniejszych plików kosztem jednego dodatkowego żądania HTTP na przesłanie.

Do przesyłania multimediów używasz specjalnego identyfikatora URI. Metody obsługujące przesyłanie multimediów mają 2 punkty końcowe URI:

  • Identyfikator URI /upload dla multimediów. Format punktu końcowego przesyłania to standardowy identyfikator URI zasobu z prefiksem „/upload”. Użyj tego identyfikatora URI podczas przesyłania danych multimedialnych.

    Przykład: POST /upload/gmail/v1/users/userId/messages/send

  • Standardowy identyfikator URI zasobu dla metadanych. Jeśli zasób zawiera pola danych, są one używane do przechowywania metadanych opisujących przesłany plik. Możesz użyć tego identyfikatora URI podczas tworzenia lub aktualizowania wartości metadanych.

    Przykład: POST /gmail/v1/users/userId/messages/send

Proste przesyłanie

Najprostszym sposobem przesłania pliku jest wysłanie prostego żądania przesyłania. Ta opcja jest dobrym wyborem, gdy:

  • Plik jest na tyle mały, że w razie niepowodzenia połączenia można go przesłać ponownie w całości.
  • Brak metadanych do wysłania. Może tak być, jeśli planujesz wysłać metadane tego zasobu w osobnym żądaniu lub jeśli metadane nie są obsługiwane lub dostępne.

Aby użyć prostego przesyłania, wyślij żądanie POST lub PUT do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=media. Na przykład:

POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=media

Nagłówki HTTP, których należy użyć podczas wysyłania prostego żądania przesłania, to m.in.:

  • Content-Type. Ustaw jeden z akceptowanych przez metodę typów danych multimedialnych do przesłania, które są określone w dokumentacji API.
  • Content-Length. Ustaw liczbę bajtów, które przesyłasz. Nie jest wymagany, jeśli używasz kodowania fragmentowanego.

Przykład: proste przesyłanie

Ten przykład przedstawia sposób użycia prostego żądania przesyłania w interfejsie Gmail API.

POST /upload/gmail/v1/users/userId/messages/send?uploadType=media HTTP/1.1
Host: www.googleapis.com
Content-Type: message/rfc822
Content-Length: number_of_bytes_in_file
Authorization: Bearer your_auth_token

Email Message data

Jeśli żądanie się powiedzie, serwer zwróci kod stanu HTTP 200 OK wraz z metadanymi:

HTTP/1.1 200
Content-Type: application/json

{
 
"id": string,
 
"threadId": string,
 
"labelIds": [
   
string
 
],
 
"snippet": string,
 
"historyId": unsigned long,
 
"payload": {
   
"partId": string,
   
"mimeType": string,
   
"filename": string,
   
"headers": [
     
{
       
"name": string,
       
"value": string
     
}
   
],
   
"body": users.messages.attachments Resource,
   
"parts": [
     
(MessagePart)
   
]
 
},
 
"sizeEstimate": integer,
 
"raw": bytes
}

Operacja przesyłania podzielona na części

Jeśli masz metadane, które chcesz wysłać razem z danymi do przesłania, możesz wysłać pojedyncze żądanie multipart/related. To dobry wybór, jeśli wysyłane dane są na tyle małe, że w razie niepowodzenia połączenia można je przesłać ponownie w całości.

Aby użyć operacji przesyłania podzielonej na części, wyślij żądanie POST lub PUT do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=multipart, na przykład:

POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=multipart

Nagłówki HTTP najwyższego poziomu, których należy używać podczas wysyłania żądania przesyłania wieloczęściowego, to m.in.:

  • Content-Type. Ustaw wartość multipart/related i uwzględnij ciąg graniczny, którego używasz do identyfikowania części żądania.
  • Content-Length. Ustaw na łączną liczbę bajtów w treści żądania. Część żądania dotycząca multimediów musi być mniejsza niż maksymalny rozmiar pliku określony dla tej metody.

Treść żądania jest sformatowana jako typ treści multipart/related [RFC2387] i składa się dokładnie z 2 części. Części są identyfikowane przez ciąg graniczny, a po ostatnim ciągu granicznym następują 2 łączniki.

Każda część żądania wieloczęściowego wymaga dodatkowego nagłówka Content-Type:

  1. Część z metadanymi: musi znajdować się na początku, a Content-Type musi być zgodny z jednym z akceptowanych formatów metadanych.
  2. Treść nagrana: musi być na drugim miejscu, a Content-Type musi odpowiadać jednemu z akceptowanych przez metodę typów MIME treści nagranej.

Listę akceptowanych typów MIME multimediów i limity rozmiaru przesyłanych plików dla każdej metody znajdziesz w dokumentacji interfejsu API.

Uwaga: aby utworzyć lub zaktualizować tylko część metadanych bez przesyłania powiązanych danych, wystarczy wysłać żądanie POST lub PUT do standardowego punktu końcowego zasobu: https://www.googleapis.com/gmail/v1/users/userId/messages/send

Przykład: operacja przesyłania podzielona na części

Poniższy przykład pokazuje żądanie wieloczęściowego przesyłania dla interfejsu Gmail API.

POST /upload/gmail/v1/users/userId/messages/send?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=foo_bar_baz
Content-Length: number_of_bytes_in_entire_request_body

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
 
"id": string,
 
"threadId": string,
 
"labelIds": [
   
string
 
],
 
"snippet": string,
 
"historyId": unsigned long,
 
"payload": {
   
"partId": string,
   
"mimeType": string,
   
"filename": string,
   
"headers": [
     
{
       
"name": string,
       
"value": string
     
}
   
],
   
"body": users.messages.attachments Resource,
   
"parts": [
     
(MessagePart)
   
]
 
},
 
"sizeEstimate": integer,
 
"raw": bytes
} --foo_bar_baz Content-Type: message/rfc822 Email Message data --foo_bar_baz--

Jeśli żądanie się powiedzie, serwer zwróci kod stanu HTTP  200 OK wraz z metadanymi:

HTTP/1.1 200
Content-Type: application/json

{
 
"id": string,
 
"threadId": string,
 
"labelIds": [
   
string
 
],
 
"snippet": string,
 
"historyId": unsigned long,
 
"payload": {
   
"partId": string,
   
"mimeType": string,
   
"filename": string,
   
"headers": [
     
{
       
"name": string,
       
"value": string
     
}
   
],
   
"body": users.messages.attachments Resource,
   
"parts": [
     
(MessagePart)
   
]
 
},
 
"sizeEstimate": integer,
 
"raw": bytes
}

Przesyłanie z możliwością wznowienia

Aby przesyłać pliki danych w bardziej niezawodny sposób, możesz użyć protokołu przesyłania z możliwością wznowienia. Ten protokół umożliwia wznowienie operacji przesyłania po tym, jak błąd komunikacji przerwał przepływ danych. Jest to szczególnie przydatne, gdy przesyłasz duże pliki i istnieje duże prawdopodobieństwo przerwania połączenia sieciowego lub innego błędu transmisji, na przykład podczas przesyłania z aplikacji klienta mobilnego. Może to również zmniejszyć wykorzystanie przepustowości w przypadku awarii sieci, ponieważ nie trzeba ponownie rozpoczynać przesyłania dużych plików od początku.

Aby skorzystać z przesyłania z możliwością wznowienia:

  1. Rozpocznij sesję z możliwością wznowienia. Wyślij początkowe żądanie do identyfikatora URI przesyłania, który zawiera metadane (jeśli są dostępne).
  2. Zapisz identyfikator URI sesji z możliwością wznowienia. Zapisz identyfikator URI sesji zwrócony w odpowiedzi na pierwsze żądanie. Będziesz go używać w pozostałych żądaniach w tej sesji.
  3. Prześlij plik. Wyślij plik multimedialny do identyfikatora URI sesji z możliwością wznowienia.

Dodatkowo aplikacje, które korzystają z przesyłania z możliwością wznowienia, muszą zawierać kod umożliwiający wznowienie przerwanego przesyłania. Jeśli przesyłanie zostanie przerwane, dowiedz się, ile danych zostało pomyślnie odebranych, a następnie wznów przesyłanie od tego momentu.

Uwaga: identyfikator URI przesyłania wygasa po tygodniu.

Krok 1. Rozpocznij sesję z możliwością wznowienia

Aby rozpocząć przesyłanie z możliwością wznowienia, wyślij żądanie POST lub PUT do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=resumable, na przykład:

POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable

W przypadku tego żądania inicjującego treść jest pusta lub zawiera tylko metadane. Rzeczywistą zawartość pliku, który chcesz przesłać, prześlesz w kolejnych żądaniach.

W początkowym żądaniu użyj tych nagłówków HTTP:

  • X-Upload-Content-Type. Ustaw typ MIME multimediów przesyłanych danych, które mają zostać przeniesione w kolejnych żądaniach.
  • X-Upload-Content-Length. Ustaw liczbę bajtów danych do przesłania w kolejnych żądaniach.  Jeśli długość jest nieznana w momencie wysyłania żądania, możesz pominąć ten nagłówek.
  • Jeśli podajesz metadane: Content-Type. Ustaw zgodnie z typem danych metadanych.
  • Content-Length. Ustaw liczbę bajtów podaną w treści tego początkowego żądania. Nie jest wymagany, jeśli używasz kodowania fragmentowanego.

Listę akceptowanych typów MIME multimediów i limity rozmiaru przesyłanych plików dla każdej metody znajdziesz w dokumentacji interfejsu API.

Przykład: żądanie rozpoczęcia sesji z możliwością wznowienia

Poniższy przykład pokazuje, jak zainicjować sesję możliwą do wznowienia w interfejsie Gmail API.

POST /upload/gmail/v1/users/userId/messages/send?uploadType=resumable HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: message/rfc822
X-Upload-Content-Length: 2000000

{
 
"id": string,
 
"threadId": string,
 
"labelIds": [
   
string
 
],
 
"snippet": string,
 
"historyId": unsigned long,
 
"payload": {
   
"partId": string,
   
"mimeType": string,
   
"filename": string,
   
"headers": [
     
{
       
"name": string,
       
"value": string
     
}
   
],
   
"body": users.messages.attachments Resource,
   
"parts": [
     
(MessagePart)
   
]
 
},
 
"sizeEstimate": integer,
 
"raw": bytes
}

Uwaga: w przypadku początkowego żądania aktualizacji z możliwością wznowienia bez metadanych pozostaw treść żądania pustą i ustaw nagłówek Content-Length na 0.

W następnej sekcji opisano, jak postępować z odpowiedzią.

Krok 2. Zapisz identyfikator URI sesji z możliwością wznowienia

Jeśli żądanie rozpoczęcia sesji się powiedzie, serwer interfejsu API odpowie kodem stanu HTTP 200 OK. Dodatkowo zawiera nagłówek Location, który określa identyfikator URI sesji możliwej do wznowienia. Nagłówek Location, pokazany w przykładzie poniżej, zawiera część parametru zapytania upload_id, która podaje unikalny identyfikator przesyłania do użycia w tej sesji.

Przykład: odpowiedź na żądanie rozpoczęcia sesji z możliwością wznowienia

Oto odpowiedź na żądanie z kroku 1:

HTTP/1.1 200 OK
Location: https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable&upload_id=xa298sd_sdlkj2
Content-Length: 0

Wartość nagłówka Location, jak pokazano w powyższym przykładzie odpowiedzi, to identyfikator URI sesji, którego użyjesz jako punktu końcowego HTTP do przesłania pliku lub sprawdzenia stanu przesyłania.

Skopiuj i zapisz identyfikator URI sesji, aby móc go używać w kolejnych żądaniach.

Krok 3: prześlij plik

Aby przesłać plik, wyślij żądanie PUT do identyfikatora URI przesyłania uzyskanego w poprzednim kroku. Format żądania przesłania:

PUT session_uri

Nagłówki HTTP, których należy używać podczas wysyłania żądań przesyłania plików z możliwością wznowienia, obejmują Content-Length. Ustaw tę wartość na liczbę bajtów, które przesyłasz w tym żądaniu. Zwykle jest to rozmiar przesyłanego pliku.

Przykład: żądanie przesyłania pliku z możliwością wznowienia

Oto żądanie z możliwością wznowienia, które służy do przesłania całego pliku wiadomości e-mail o rozmiarze 2 000 000 bajtów w bieżącym przykładzie.

PUT https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 2000000
Content-Type: message/rfc822

bytes 0-1999999

Jeśli żądanie się powiedzie, serwer odpowie HTTP 201 Created wraz z metadanymi powiązanymi z tym zasobem. Jeśli początkowe żądanie sesji z możliwością wznowienia było żądaniem PUT, aby zaktualizować istniejący zasób, odpowiedź o powodzeniu będzie miała postać 200 OK wraz z wszelkimi metadanymi powiązanymi z tym zasobem.

Jeśli żądanie przesyłania zostanie przerwane lub otrzymasz z serwera odpowiedź HTTP 503 Service Unavailable lub inną odpowiedź 5xx, postępuj zgodnie z procedurą opisaną w sekcji Wznawianie przerwanego przesyłania.  


Przesyłanie pliku we fragmentach

W przypadku przesyłania z możliwością wznowienia możesz podzielić plik na fragmenty i wysłać serię żądań, aby przesłać każdy fragment po kolei. Nie jest to preferowane podejście, ponieważ dodatkowe żądania wiążą się z kosztami związanymi z wydajnością i zwykle nie są potrzebne. Może być jednak konieczne użycie fragmentacji, aby zmniejszyć ilość danych przesyłanych w jednym żądaniu. Jest to przydatne, gdy obowiązuje stały limit czasu dla poszczególnych żądań, jak w przypadku niektórych klas żądań Google App Engine. Umożliwia też m.in. wyświetlanie wskaźników postępu przesyłania w starszych przeglądarkach, które domyślnie nie obsługują tej funkcji.


Wznawianie przerwanego przesyłania

Jeśli żądanie przesyłania zostanie przerwane przed otrzymaniem odpowiedzi lub jeśli otrzymasz z serwera odpowiedź HTTP 503 Service Unavailable, musisz wznowić przerwane przesyłanie. Aby to zrobić:

  1. Stan prośby. Sprawdź bieżący stan przesyłania, wysyłając puste żądanie PUT do identyfikatora URI przesyłania. W przypadku tego żądania nagłówki HTTP powinny zawierać nagłówek Content-Range wskazujący, że bieżąca pozycja w pliku jest nieznana.  Jeśli na przykład łączna długość pliku wynosi 2 000 000, ustaw parametr Content-Range na */2000000. Jeśli nie znasz pełnego rozmiaru pliku, ustaw Content-Range na */*.

    Uwaga: stan możesz sprawdzać między fragmentami, a nie tylko wtedy, gdy przesyłanie zostanie przerwane. Jest to przydatne, jeśli chcesz na przykład wyświetlać wskaźniki postępu przesyłania w starszych przeglądarkach.

  2. Pobieranie liczby przesłanych bajtów Przetwórz odpowiedź na zapytanie o stan. Serwer używa nagłówka Range w odpowiedzi, aby określić, które bajty zostały już odebrane.  Na przykład nagłówek Range o wartości 0-299999 wskazuje, że odebrano pierwsze 300 000 bajtów pliku.
  3. Prześlij pozostałe dane. Gdy już wiesz, gdzie wznowić żądanie, wyślij pozostałe dane lub bieżący fragment. Pamiętaj, że w obu przypadkach pozostałe dane musisz potraktować jako osobny fragment, więc przy wznawianiu przesyłania musisz wysłać nagłówek Content-Range.
Przykład: wznawianie przerwanego przesyłania

1) Poproś o stan przesyłania.

To żądanie używa nagłówka Content-Range, aby wskazać,że bieżąca pozycja w pliku o rozmiarze 2 000 000 bajtów jest nieznana.

PUT {session_uri} HTTP/1.1
Content-Length: 0
Content-Range: bytes */2000000

2) Wyodrębnij z odpowiedzi liczbę przesłanych do tej pory bajtów.

Odpowiedź serwera zawiera nagłówek Range, który wskazuje, że serwer otrzymał do tej pory pierwsze 43 bajty pliku. Użyj górnej wartości nagłówka Range, aby określić, gdzie rozpocząć wznowione przesyłanie.

HTTP/1.1 308 Resume Incomplete
Content-Length: 0
Range: 0-42

Uwaga: jeśli przesyłanie zostało zakończone, odpowiedź dotycząca stanu może mieć wartość 201 Created lub 200 OK. Może się tak zdarzyć, jeśli połączenie zostało przerwane po przesłaniu wszystkich bajtów, ale zanim klient otrzymał odpowiedź z serwera.

3) Wznów przesyłanie od miejsca, w którym zostało przerwane.

To żądanie wznawia przesyłanie, wysyłając pozostałe bajty pliku, zaczynając od bajtu 43.

PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000

bytes 43-1999999

Sprawdzone metody

Podczas przesyłania multimediów warto pamiętać o kilku sprawdzonych metodach związanych z obsługą błędów.

  • Wznawiać lub ponawiać przesyłanie, które nie powiodło się z powodu przerw w połączeniu lub błędów 5xx, w tym:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Jeśli podczas wznawiania lub ponawiania próby przesłania wystąpi błąd serwera 5xx, zastosuj strategię wzrastającego czasu do ponowienia. Te błędy mogą wystąpić, jeśli serwer jest przeciążony. Wzrastający czas do ponowienia może pomóc w rozwiązaniu tego typu problemów w okresach dużej liczby żądań lub dużego ruchu w sieci.
  • Inne rodzaje żądań nie powinny być obsługiwane przez wzrastający czas do ponowienia, ale nadal możesz ponowić niektóre z nich. Podczas ponownego wysyłania tych żądań ogranicz liczbę prób. Na przykład kod może ograniczać liczbę ponownych prób do 10 lub mniej, zanim zgłosi błąd.
  • Obsługuj błędy 404 Not Found i 410 Gone podczas przesyłania z możliwością wznowienia, rozpoczynając całe przesyłanie od początku.

Wzrastający czas do ponowienia

Wzrastający czas do ponowienia to standardowa strategia obsługi błędów w aplikacjach sieciowych, w której klient okresowo ponawia nieudane żądanie, zwiększając czas między próbami. Jeśli duża liczba żądań lub duży ruch w sieci powodują, że serwer zwraca błędy, wzrastający czas do ponowienia może być dobrą strategią ich obsługi. Nie jest to jednak odpowiednia strategia w przypadku błędów niezwiązanych z natężeniem ruchu w sieci ani czasem odpowiedzi, takich jak nieprawidłowe dane uwierzytelniające lub błędy braku pliku.

Prawidłowo stosowany wzrastający czas do ponowienia zwiększa efektywność wykorzystania przepustowości, zmniejsza liczbę żądań wymaganych do uzyskania odpowiedzi i maksymalizuje przepustowość żądań w środowiskach równoległych.

Proces implementacji prostego wzrastającego czasu do ponowienia wygląda następująco:

  1. wysłać żądanie do interfejsu API,
  2. Otrzymasz odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  3. Odczekaj 1 sekundę + losowa_liczba_milisekund i spróbuj jeszcze raz.
  4. Otrzymasz odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  5. Zaczekaj 2 sekundy + losowa_liczba_milisekund i spróbuj jeszcze raz.
  6. Otrzymasz odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  7. Zaczekaj 4 sekundy + losowa_liczba_milisekund i spróbuj jeszcze raz.
  8. Otrzymasz odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  9. Zaczekaj 8 sekund + losowa_liczba_milisekund i spróbuj jeszcze raz.
  10. Otrzymasz odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  11. Odczekaj 16 sekund + losowa_liczba_milisekund i spróbuj jeszcze raz.
  12. Zatrzymaj. Zgłoś lub zarejestruj błąd.

W powyższym procesie random_number_milliseconds to losowa liczba milisekund mniejsza lub równa 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego losowego opóźnienia pomaga bardziej równomiernie rozłożyć obciążenie i uniknąć przeciążenia serwera. Wartość random_number_milliseconds musi być ponownie definiowana po każdym oczekiwaniu.

Uwaga: czas oczekiwania zawsze wynosi (2 ^ n) + losowa_liczba_milisekund, gdzie n to monotonicznie rosnąca liczba całkowita, która początkowo jest zdefiniowana jako 0. Liczba całkowita n jest zwiększana o 1 przy każdej iteracji (każdym żądaniu).

Algorytm jest ustawiony tak, aby kończył działanie, gdy n = 5. Ten limit zapobiega nieskończonemu ponawianiu prób przez klientów i powoduje, że łączny czas oczekiwania, zanim żądanie zostanie uznane za „nieodwracalny błąd”, wynosi około 32 sekund. Większa maksymalna liczba ponownych prób jest w porządku, zwłaszcza jeśli trwa długie przesyłanie. Pamiętaj tylko, aby opóźnienie ponownej próby było rozsądne, np. krótsze niż minuta.

Przewodniki po bibliotekach klienta interfejsu API