Prześlij załączniki

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

Opcje przesyłania

Gmail API umożliwia przesyłanie niektórych typów danych binarnych lub multimediów. Szczegółowe informacje o danych, które możesz przesłać, znajdziesz na stronie referencyjnej dowolnej metody obsługującej przesyłanie multimediów:

  • Maksymalny rozmiar przesyłanego pliku: maksymalna ilość danych, które możesz przechowywać za pomocą tej metody.
  • Akceptowane typy MIME multimediów: typy danych binarnych, które możesz przechowywać za pomocą tej metody.

Żądania przesyłania możesz wysyłać na jeden z tych sposobów. Metodę, której używasz, określ za pomocą parametru żądania uploadType.

  • Proste przesyłanie: uploadType=media. Do szybkiego przesyłania mniejszych plików, np. o rozmiarze nieprzekraczającym 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. Do niezawodnego przesyłania, szczególnie ważnego w przypadku większych plików. W tej metodzie używasz żądania inicjującego sesję, które opcjonalnie może zawierać metadane. Jest to dobra strategia w przypadku większości aplikacji, ponieważ działa też w przypadku mniejszych plików, ale wiąże się z dodatkowym żądaniem HTTP na przesyłanie.

Podczas 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 samych 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 przesyłania pliku jest wysłanie prostego żądania przesyłania. Ta opcja jest dobrym wyborem, gdy:

  • plik jest wystarczająco mały, aby w przypadku awarii połączenia można go było przesłać ponownie w całości;
  • nie ma metadanych do wysłania. Może to być prawdą, jeśli planujesz wysłać metadane tego zasobu w osobnym żądaniu lub jeśli metadane nie są obsługiwane ani 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 przesyłania:

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

Przykład: proste przesyłanie

Ten przykład pokazuje, jak użyć prostego żądania przesyłania w 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
}

Przesyłanie wieloczęściowe

Jeśli masz metadane, które chcesz wysłać wraz z danymi do przesłania, możesz wysłać jedno żądanie multipart/related. Jest to dobry wybór, jeśli wysyłane dane są wystarczająco małe, aby w przypadku awarii połączenia można je było przesłać ponownie w całości.

Aby użyć przesyłania wieloczęściowego, 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żyć podczas wysyłania żądania przesyłania wieloczęściowego:

  • Content-Type. Ustaw na multipart/related i dodaj 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ęść multimedialna żądania musi być mniejsza niż maksymalny rozmiar pliku określony dla tej metody.

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

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

  1. Część metadanych: musi być pierwsza, a Content-Type musi być zgodny z jednym z akceptowanych formatów metadanych.
  2. Część multimediów: musi być druga, a Content-Type musi być zgodny z jednym z akceptowanych przez metodę typów MIME multimediów.

Listę akceptowanych typów MIME multimediów i limity rozmiaru przesyłanych plików znajdziesz w dokumentacji interfejsu API reference.

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

Przykład: przesyłanie wieloczęściowe

Poniższy przykład pokazuje żądanie przesyłania wieloczęściowego w 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 bardziej niezawodnie, możesz użyć protokołu przesyłania z możliwością wznowienia. Ten protokół umożliwia wznowienie przesyłania po przerwaniu przepływu danych z powodu awarii komunikacji. Jest to szczególnie przydatne, jeśli przesyłasz duże pliki i istnieje duże prawdopodobieństwo przerwy w sieci lub innej awarii transmisji, np. podczas przesyłania z aplikacji klienckiej na urządzeniu mobilnym. Może też zmniejszyć zużycie przepustowości w przypadku awarii sieci, ponieważ nie musisz ponownie przesyłać dużych plików od początku.

Kroki korzystania z przesyłania z możliwością wznowienia:

  1. Rozpocznij sesję z możliwością wznowienia. Wyślij wstępne żądanie do identyfikatora URI przesyłania, które 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 wstępne żą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.

Aplikacje, które korzystają z przesyłania z możliwością wznowienia, muszą też mieć kod umożliwiający wznowienie przerwanego przesyłania. Jeśli przesyłanie zostanie przerwane, sprawdź, 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 przypadku żądania początkowego użyj tych nagłówków HTTP:

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

Listę akceptowanych typów MIME multimediów i limity rozmiaru przesyłanych plików znajdziesz w dokumentacji interfejsu API reference.

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

Ten przykład pokazuje, jak rozpocząć sesję z możliwością wznowienia w 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 wstępnego żądania aktualizacji z możliwością wznowienia bez metadanych pozostaw treść żądania pustą i ustaw nagłówek Content-Length na 0.

Następna sekcja zawiera informacje o tym, jak obsługiwać odpowiedź.

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

Jeśli żądanie rozpoczęcia sesji się powiedzie, serwer API odpowie kodem stanu HTTP 200 OK. Dodatkowo udostępni nagłówek Location, który określa identyfikator URI sesji z możliwością 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 będziesz używać jako punktu końcowego HTTP do przesyłania pliku lub sprawdzania 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, który został uzyskany w poprzednim kroku. Format żądania przesyłania:

PUT session_uri

Nagłówki HTTP, których należy użyć podczas wysyłania żądań przesyłania pliku z możliwością wznowienia, obejmują Content-Length. Ustaw go na liczbę bajtów przesyłanych w tym żądaniu, która jest zwykle rozmiarem przesyłanego pliku.

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

Oto żądanie z możliwością wznowienia, które przesyła cały plik 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 kodem HTTP 201 Created wraz z metadanymi powiązanymi z tym zasobem. Jeśli wstępne żą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 metadanymi powiązanymi z tym zasobem.

Jeśli żądanie przesyłania zostanie przerwane lub jeśli 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 w częściach

W przypadku przesyłania z możliwością wznowienia możesz podzielić plik na części i wysłać serię żądań, aby przesłać każdą część po kolei. Nie jest to preferowane podejście, ponieważ wiąże się z dodatkowymi żądaniami, które wpływają na wydajność, i zwykle nie jest potrzebne. Może się jednak zdarzyć, że będziesz musiał użyć podziału na części, 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ż wykonywanie takich czynności jak wyświetlanie informacji o postępie przesyłania w starszych przeglądarkach, które domyślnie nie obsługują postępu przesyłania.


Wznawianie przerwanego przesyłania

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

  1. Stan żądania. 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 np. łączna długość pliku wynosi 2 000 000, ustaw Content-Range na */2000000. Jeśli nie znasz pełnego rozmiaru pliku, ustaw Content-Range na */*.

    Uwaga: możesz sprawdzić stan między częściami, a nie tylko wtedy, gdy przesyłanie zostanie przerwane. Jest to przydatne np. wtedy, gdy chcesz wyświetlać informacje o postępie przesyłania w starszych przeglądarkach.

  2. Pobierz liczbę przesłanych bajtów. Przetwórz odpowiedź na zapytanie o stan. Serwer używa w odpowiedzi nagłówka Range, aby określić, które bajty zostały dotychczas odebrane. Na przykład nagłówek Range o wartości 0-299999 oznacza, że odebrano pierwsze 300 000 bajtów pliku.
  3. Prześlij pozostałe dane. Gdy wiesz już, od którego miejsca wznowić żądanie, wyślij pozostałe dane lub bieżącą część. Pamiętaj, że w obu przypadkach musisz traktować pozostałe dane jako oddzielną część, więc podczas wznawiania przesyłania musisz wysłać nagłówek Content-Range.
Przykład: wznawianie przerwanego przesyłania

1) Sprawdź 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ę dotychczas przesłanych bajtów.

Odpowiedź serwera używa nagłówka Range, aby wskazać, że dotychczas odebrano pierwsze 43 bajty pliku. Użyj górnej wartości nagłówka Range, aby określić, od którego miejsca 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ź o stanie może mieć postać 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 znać sprawdzone metody związane z obsługą błędów.

  • Wznów lub ponów 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 żądań przesyłania zostanie zwrócony błąd serwera 5xx, użyj strategii 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 złagodzić te problemy w okresach dużej liczby żądań lub dużego ruchu w sieci.
  • Innych rodzajów żądań nie należy obsługiwać za pomocą wzrastającego czasu do ponowienia, ale nadal możesz ponowić ich wysyłanie. Podczas ponawiania tych żądań ogranicz liczbę prób. Na przykład Twój kod może ograniczyć liczbę prób do 10 lub mniej przed zgłoszeniem błędu.
  • Podczas przesyłania z możliwością wznowienia obsługuj błędy 404 Not Found i 410 Gone, 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 w coraz dłuższych odstępach czasu. Jeśli duża liczba żądań lub duży ruch w sieci powoduje, że serwer zwraca błędy, wzrastający czas do ponowienia może być dobrą strategią obsługi tych błędów. Z drugiej strony nie jest to odpowiednia strategia w przypadku błędów niezwiązanych z ruchem w sieci ani czasem odpowiedzi, takich jak nieprawidłowe dane uwierzytelniające lub błędy związane z brakiem pliku.

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

Proces implementacji prostego wzrastającego czasu do ponowienia:

  1. Wyślij żądanie do interfejsu API.
  2. Otrzymaj odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  3. Odczekaj 1 sekundę + random_number_milliseconds i ponów żądanie.
  4. Otrzymaj odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  5. Odczekaj 2 sekundy + random_number_milliseconds i ponów żądanie.
  6. Otrzymaj odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  7. Odczekaj 4 sekundy + random_number_milliseconds i ponów żądanie.
  8. Otrzymaj odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  9. Odczekaj 8 sekund + random_number_milliseconds i ponów żądanie.
  10. Otrzymaj odpowiedź HTTP 503, która wskazuje, że należy ponowić żądanie.
  11. Odczekaj 16 sekund + random_number_milliseconds i ponów żądanie.
  12. Zatrzymaj. Zgłoś lub zapisz błąd.

W powyższym procesie random_number_milliseconds to losowa liczba milisekund nie większa niż 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego losowego opóźnienia pomaga równomiernie rozłożyć obciążenie i uniknąć przeciążenia serwera. Wartość random_number_milliseconds musi zostać ponownie zdefiniowana po każdym oczekiwaniu.

Uwaga: czas oczekiwania to zawsze (2 ^ n) + random_number_milliseconds, gdzie n jest monotonicznie rosnącą liczbą całkowitą, która początkowo wynosi 0. Liczba całkowita n jest zwiększana o 1 w każdej iteracji (każde żądanie).

Algorytm jest ustawiony tak, aby zakończyć działanie, gdy n wynosi 5. Ten limit uniemożliwia klientom ponawianie żądań w nieskończoność i powoduje, że łączne opóźnienie przed uznaniem żądania za „błąd nie do naprawienia” wynosi około 32 sekund. Większa maksymalna liczba ponowień jest w porządku, zwłaszcza jeśli trwa długie przesyłanie. Pamiętaj tylko, aby ograniczyć opóźnienie ponowienia do rozsądnej wartości, np. poniżej 1 minuty.

Przewodniki po bibliotekach klienta interfejsu API