Łączenie z Gmailem przez API
Biblioteka klienta Google API, zgoda OAuth2 i wybór zakresów uprawnień Gmaila.
Łączenie z Gmailem przez API to bezpłatna lekcja AI Agents na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Agents, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Agents zawiera 4 lekcji w sumie.
Dlaczego używać Gmail API zamiast SMTP?
Tradycyjna automatyzacja poczty e-mail korzysta z SMTP/IMAP, ale Gmail API oferuje znacznie więcej: odczytywanie wątków, wyszukiwanie za pomocą zapytań, zarządzanie etykietami i wysyłanie z pełnym uwierzytelnianiem. Obsługuje również OAuth 2.0, dzięki czemu agent nigdy nie przechowuje hasła — korzysta jedynie z tokena dostępu o ograniczonym zakresie uprawnień.
Gmail API należy do Google Workspace APIs i uzyskuje się do niego dostęp za pośrednictwem biblioteki google-api-python-client.
# Install required libraries:
# pip install google-api-python-client google-auth google-auth-oauthlib
# The Gmail API lets agents:
# - List and search messages (labels, queries)
# - Read full message content and attachments
# - Send messages via OAuth (no password needed)
# - Manage labels and threads
# - Watch for new messages via push notifications
print('Gmail API is part of Google Workspace APIs')Uwierzytelnianie: konto usługi a uwierzytelnianie użytkownika
W przypadku Gmail API istnieją dwa podejścia do uwierzytelniania:
- Konto usługi: najlepsze rozwiązanie do zastosowań w przestrzeni roboczej lub organizacji, z delegowaniem w całej domenie; nie wymaga interakcji z użytkownikiem
- OAuth użytkownika (OAuth2 z ekranem zgody): wymagane w przypadku osobistych kont Gmail; użytkownik jednorazowo przyznaje dostęp, a agent korzysta z tokena odświeżania
W większości przypadków automatyzacji agentów preferowane są konta usługi ze względu na niezawodność.
# Service Account approach:
# 1. Go to Google Cloud Console -> APIs & Services -> Credentials
# 2. Create a Service Account
# 3. Download the JSON key file
# 4. In Google Workspace Admin: enable domain-wide delegation
# 5. Grant required scopes to the service account
# User OAuth approach:
# 1. Create OAuth 2.0 Client ID (Desktop or Web App type)
# 2. Download credentials.json
# 3. First run: user sees consent screen and grants access
# 4. Agent stores token.json with refresh token for subsequent runs
print('Choose service account for org automation, OAuth for personal Gmail')Struktura pliku JSON danych uwierzytelniających OAuth2
Google udostępnia dane uwierzytelniające w pliku JSON, który agent wczytuje w celu uwierzytelnienia. W przypadku OAuth użytkownika jest to plik credentials.json pobrany z Google Cloud Console. Plik zawiera identyfikator klienta, klucz tajny i URI przekierowania — nigdy nie należy umieszczać go w systemie kontroli wersji.
# credentials.json structure (User OAuth — Desktop app type):
# {
# "installed": {
# "client_id": "123456789.apps.googleusercontent.com",
# "client_secret": "GOCSPX-abc123xyz",
# "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"],
# "auth_uri": "https://accounts.google.com/o/oauth2/auth",
# "token_uri": "https://oauth2.googleapis.com/token"
# }
# }
# service-account.json structure:
# {
# "type": "service_account",
# "project_id": "my-project",
# "private_key_id": "abc123",
# "private_key": "-----BEGIN PRIVATE KEY-----\n...",
# "client_email": "agent@my-project.iam.gserviceaccount.com",
# "client_id": "..."
# }
print('Store credential files outside your git repository')Zakresy Gmail API
Zakresy OAuth dokładnie określają, do czego agent ma dostęp. Należy żądać wyłącznie potrzebnych zakresów — jest to zasada najmniejszych uprawnień. Zakresy Gmail obejmują uprawnienia od dostępu tylko do odczytu po pełny dostęp.
gmail.readonly— odczytywanie całej pocztygmail.send— tylko wysyłanie, bez odczytugmail.modify— odczytywanie, wysyłanie i modyfikowanie etykietgmail.compose— tworzenie tylko wersji roboczych
# Gmail API scope constants
SCOPE_READONLY = 'https://www.googleapis.com/auth/gmail.readonly'
SCOPE_SEND = 'https://www.googleapis.com/auth/gmail.send'
SCOPE_MODIFY = 'https://www.googleapis.com/auth/gmail.modify'
SCOPE_COMPOSE = 'https://www.googleapis.com/auth/gmail.compose'
# Calendar scopes (often used alongside Gmail)
SCOPE_CALENDAR_READ = 'https://www.googleapis.com/auth/calendar.readonly'
SCOPE_CALENDAR_EVENTS = 'https://www.googleapis.com/auth/calendar.events'
# Combine scopes your agent actually needs
AGENT_SCOPES = [
SCOPE_READONLY,
SCOPE_SEND,
SCOPE_CALENDAR_EVENTS
]
print(f'Using {len(AGENT_SCOPES)} scopes')OAuth użytkownika: uwierzytelnianie przy pierwszym użyciu
Przy pierwszym uruchomieniu agenta przez użytkownika zostanie otwarta przeglądarka, aby użytkownik mógł przyznać uprawnienia. Agent zapisuje uzyskany token w pliku token.json. Przy kolejnych uruchomieniach wczytuje zapisany token i automatycznie go odświeża — nie jest wymagana interakcja z przeglądarką.
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
import os
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
def get_credentials(token_file='token.json', creds_file='credentials.json'):
creds = None
# Load existing token if available
if os.path.exists(token_file):
creds = Credentials.from_authorized_user_file(token_file, SCOPES)
# Refresh or re-authenticate if needed
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request()) # auto-refresh
else:
# Opens browser for user consent (first time only)
flow = InstalledAppFlow.from_client_secrets_file(
creds_file, SCOPES
)
creds = flow.run_local_server(port=0)
# Save token for next run
with open(token_file, 'w') as f:
f.write(creds.to_json())
return credsUwierzytelnianie za pomocą konta usługi
Konta usługi są idealne dla zautomatyzowanych agentów działających bez interakcji z użytkownikiem. Agent uwierzytelnia się za pomocą klucza prywatnego, a następnie działa w imieniu użytkownika Google Workspace dzięki delegowaniu w całej domenie. Bez ekranu zgody i bez przeglądarki — wystarczy plik klucza JSON.
from google.oauth2 import service_account
import os
SCOPES = [
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.send'
]
def get_service_account_credentials(impersonate_user):
service_account_file = os.environ.get(
'GOOGLE_SERVICE_ACCOUNT_JSON',
'service-account.json'
)
credentials = service_account.Credentials.from_service_account_file(
service_account_file,
scopes=SCOPES
)
# Impersonate a real user (requires domain-wide delegation in Admin)
delegated = credentials.with_subject(impersonate_user)
return delegated
creds = get_service_account_credentials('agent@yourcompany.com')
print('Service account credentials ready')Tworzenie obiektu usługi Gmail
Po uzyskaniu danych uwierzytelniających należy użyć googleapiclient.discovery.build(), aby utworzyć obiekt usługi Gmail. Jest to główny interfejs wszystkich wywołań Gmail API. Należy przekazać nazwę usługi 'gmail' oraz wersję 'v1'.
from googleapiclient.discovery import build
def build_gmail_service(credentials):
service = build(
'gmail',
'v1',
credentials=credentials,
cache_discovery=False # avoid file warnings in some environments
)
return service
# Full setup: credentials -> service
creds = get_credentials() # or get_service_account_credentials()
gmail = build_gmail_service(creds)
# Test: get user profile
profile = gmail.users().getProfile(userId='me').execute()
print('Email:', profile['emailAddress'])
print('Total messages:', profile['messagesTotal'])Tworzenie obiektu usługi Calendar
Ta sama konfiguracja danych uwierzytelniających działa w przypadku Google Calendar. Wystarczy utworzyć obiekt za pomocą wartości 'calendar' i 'v3'. Jeśli agent potrzebuje zarówno Gmail, jak i Google Calendar, oba obiekty usług można utworzyć na podstawie tego samego obiektu danych uwierzytelniających.
from googleapiclient.discovery import build
def build_google_services(credentials):
gmail = build(
'gmail', 'v1',
credentials=credentials,
cache_discovery=False
)
calendar = build(
'calendar', 'v3',
credentials=credentials,
cache_discovery=False
)
return gmail, calendar
# Use both in one agent
creds = get_credentials()
gmail_service, calendar_service = build_google_services(creds)
# Test calendar access
cal_list = calendar_service.calendarList().list().execute()
for cal in cal_list.get('items', []):
print(f'Calendar: {cal["summary"]}')Obsługa błędów Google API
Błędy Google API są zgłaszane jako googleapiclient.errors.HttpError. Błąd zawiera kod stanu HTTP oraz treść JSON ze szczegółami błędu. Należy zawsze go przechwytywać i rejestrować stan oraz komunikat na potrzeby debugowania.
from googleapiclient.errors import HttpError
import json
def safe_gmail_call(service, user_id='me'):
try:
profile = service.users().getProfile(userId=user_id).execute()
return profile
except HttpError as e:
status = e.resp.status
try:
error_body = json.loads(e.content.decode())
message = error_body.get('error', {}).get('message', str(e))
except Exception:
message = str(e)
if status == 401:
print('AUTH ERROR: Credentials invalid or expired')
elif status == 403:
print(f'PERMISSION ERROR: {message}')
print('Check scopes and domain-wide delegation settings')
elif status == 429:
print('QUOTA EXCEEDED: Gmail API rate limit hit')
else:
print(f'Gmail API error {status}: {message}')
return NoneLimity wykorzystania i szybkości Google API
Gmail API ma limity wykorzystania: domyślnie 1 miliard jednostek limitu dziennie, przy czym każde wywołanie kosztuje od 1 do 100 jednostek, zależnie od operacji. Odczytywanie wiadomości kosztuje więcej niż ich wyświetlanie na liście. Aby zmieścić się w limitach, należy używać żądań zbiorczych oraz wycofywania wykładniczego w przypadku błędów 429/503.
import time
from googleapiclient.errors import HttpError
def gmail_call_with_retry(func, max_retries=5):
for attempt in range(max_retries):
try:
return func()
except HttpError as e:
if e.resp.status in (429, 500, 503):
wait = (2 ** attempt) + 1
print(f'Quota/server error. Waiting {wait}s (attempt {attempt+1})')
time.sleep(wait)
elif e.resp.status == 403:
# Check if it's a quota exceeded vs permission error
import json
body = json.loads(e.content.decode())
reason = body.get('error', {}).get('errors', [{}])[0].get('reason', '')
if reason == 'rateLimitExceeded':
time.sleep(2 ** attempt)
else:
raise # real permission error, don't retry
else:
raise
raise Exception(f'Gmail API call failed after {max_retries} attempts')Bezpieczne przechowywanie danych uwierzytelniających
Nigdy nie należy umieszczać plików token.json, credentials.json ani service-account.json w systemie kontroli wersji. Należy dodać je do pliku .gitignore. W środowisku produkcyjnym plik JSON konta usługi należy przechowywać w zmiennej środowiskowej lub menedżerze sekretów i wczytywać go w czasie działania.
import json
import os
from google.oauth2 import service_account
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
def get_credentials_from_env():
# Load service account JSON from environment variable
sa_json = os.environ.get('GOOGLE_SERVICE_ACCOUNT_JSON')
if not sa_json:
raise EnvironmentError(
'GOOGLE_SERVICE_ACCOUNT_JSON env var not set. '
'Set it to the contents of your service-account.json'
)
sa_info = json.loads(sa_json)
credentials = service_account.Credentials.from_service_account_info(
sa_info,
scopes=SCOPES
)
return credentials
# In production: export GOOGLE_SERVICE_ACCOUNT_JSON=$(cat service-account.json)
creds = get_credentials_from_env()
print('Service account loaded from env var')Szybki test: konto usługi a OAuth użytkownika
Sprawdź swoją wiedzę na temat metod uwierzytelniania Gmail API.
Podsumowanie połączenia z Gmail API
Agent potrafi teraz łączyć się z Gmail:
- OAuth użytkownika: używa
InstalledAppFlowi przechowujetoken.json; przy kolejnych uruchomieniach token jest automatycznie odświeżany - Konto usługi: wczytuje klucz JSON i wywołuje
.with_subject(user_email)w celu delegowania - Zakresy: żąda minimalnego niezbędnego zakresu (
gmail.readonly,gmail.send,calendar.events) - Tworzy obiekt usługi za pomocą
build('gmail', 'v1', credentials=creds) - Przechwytuje
HttpErrorw przypadku błędów API; ponawia próby po błędach 429/503 - Nigdy nie umieszcza plików danych uwierzytelniających w repozytorium — w środowisku produkcyjnym używa zmiennych środowiskowych
Często zadawane pytania
Czy lekcja „Łączenie z Gmailem przez API” jest bezpłatna?
Tak — pełny tekst „Łączenie z Gmailem przez API” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Agents, przejdź na CoddyKit PRO. Kurs AI Agents zawiera 4 lekcji w sumie.
Co nauczysz się w „Łączenie z Gmailem przez API”?
Biblioteka klienta Google API, zgoda OAuth2 i wybór zakresów uprawnień Gmaila. Ćwiczysz AI Agents z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć AI Agents?
Nie wymagamy żadnego doświadczenia. AI Agents w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Łączenie z Gmailem przez API”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji AI Agents?
Tak. Każda lekcja AI Agents zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Łączenie z Gmailem przez API
- Programowe odczytywanie i wysyłanie e-maili
- Tworzenie i wyszukiwanie wydarzeń w kalendarzu
- Tworzenie prostego agenta asystenta e-mail