0Pricing
AI Agents · Lezione

Connessione a Gmail tramite API

Libreria client Google API, consenso OAuth2 e selezione degli scope di Gmail

Connessione a Gmail tramite API è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.

Perché usare Gmail API invece di SMTP?

L'automazione tradizionale della posta elettronica utilizza SMTP/IMAP, ma la Gmail API offre molto di più: leggere conversazioni, cercare tramite query, gestire etichette e inviare messaggi con autenticazione completa. Supporta anche OAuth 2.0, quindi il Suo agente non memorizza mai una password, ma solo un token di accesso con scope limitato.

La Gmail API fa parte delle Google Workspace APIs, a cui si accede tramite la libreria 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')

Autenticazione: account di servizio o autenticazione utente

Per la Gmail API esistono due approcci all'autenticazione:

  • Account di servizio: ideale per l'uso in ambienti Workspace o organizzativi con delega a livello di dominio; non richiede interazione dell'utente
  • User OAuth (OAuth2 con schermata di consenso): necessario per gli account Gmail personali; l'utente concede l'accesso una volta e l'agente utilizza un refresh token

Per la maggior parte delle automazioni con agenti, gli account di servizio sono preferibili per la loro affidabilità.

# 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')

Struttura JSON delle credenziali OAuth2

Google fornisce le credenziali in un file JSON che l'agente carica per autenticarsi. Per User OAuth, si tratta di un file credentials.json scaricato dalla Google Cloud Console. Il file contiene l'ID client, il segreto e l'URI di reindirizzamento: non lo inserisca mai nel controllo versione.

# 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')

Scope della Gmail API

Gli scope OAuth definiscono esattamente a quali risorse può accedere il Suo agente. Richieda solo gli scope necessari: questo è il principio del privilegio minimo. Gli scope Gmail vanno dall'accesso in sola lettura all'accesso completo.

  • gmail.readonly — lettura di tutti i messaggi
  • gmail.send — solo invio, senza lettura
  • gmail.modify — lettura, invio e modifica delle etichette
  • gmail.compose — creazione delle sole bozze
# 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')

User OAuth: flusso di autenticazione al primo utilizzo

La prima volta che un utente esegue l'agente, quest'ultimo apre un browser per consentirgli di concedere l'autorizzazione. L'agente memorizza il token risultante in token.json. Alle esecuzioni successive carica il token memorizzato e lo aggiorna automaticamente, senza richiedere ulteriori interazioni con il browser.

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 creds

Autenticazione con account di servizio

Per gli agenti automatizzati eseguiti senza interazione dell'utente, gli account di servizio sono ideali. L'agente si autentica utilizzando una chiave privata, quindi impersona un utente Google Workspace tramite la delega a livello di dominio. Nessuna schermata di consenso, nessun browser: solo un file di chiavi 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')

Creazione dell'oggetto del servizio Gmail

Una volta ottenute le credenziali, utilizzi googleapiclient.discovery.build() per creare l'oggetto del servizio Gmail. Questa è l'interfaccia principale per tutte le chiamate alla Gmail API. Passi il nome del servizio 'gmail' e la versione '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'])

Creazione dell'oggetto del servizio Calendar

La stessa configurazione delle credenziali funziona anche per Google Calendar. È sufficiente creare il servizio con 'calendar' e 'v3'. Se il Suo agente deve utilizzare sia Gmail sia Calendar, crei entrambi i servizi a partire dallo stesso oggetto delle credenziali.

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"]}')

Gestione degli errori delle API Google

Gli errori delle API Google vengono sollevati come googleapiclient.errors.HttpError. L'errore contiene un codice di stato HTTP e un corpo JSON con i dettagli dell'errore. Gestisca sempre questa eccezione e registri lo stato e il messaggio per il debug.

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 None

Quote e limiti di frequenza delle API Google

La Gmail API prevede quote di utilizzo: per impostazione predefinita, 1 miliardo di unità quota al giorno; ogni chiamata costa da 1 a 100 unità a seconda dell'operazione. La lettura dei messaggi costa più della loro elencazione. Utilizzi richieste batch e il backoff esponenziale in caso di errori 429/503 per rimanere entro i limiti.

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')

Memorizzazione sicura delle credenziali

Non inserisca mai token.json, credentials.json o service-account.json nel controllo versione. Li aggiunga a .gitignore. In produzione, memorizzi il JSON dell'account di servizio in una variabile d'ambiente o in un gestore dei segreti e lo carichi a runtime.

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')

Verifica rapida: account di servizio o User OAuth

Verifichi di aver compreso i metodi di autenticazione della Gmail API.

Riepilogo della connessione alla Gmail API

Ora può connettere un agente a Gmail:

  • User OAuth: utilizzi InstalledAppFlow e memorizzi token.json; il token viene aggiornato automaticamente alle esecuzioni successive
  • Service Account: carichi la chiave JSON e chiami .with_subject(user_email) per la delega
  • Scope: richieda il minimo necessario (gmail.readonly, gmail.send, calendar.events)
  • Crei il servizio con build('gmail', 'v1', credentials=creds)
  • Gestisca HttpError per gli errori dell'API e riprovi in caso di 429/503
  • Non inserisca mai i file delle credenziali nel controllo versione: in produzione utilizzi variabili d'ambiente

Domande Frequenti

La lezione «Connessione a Gmail tramite API» è gratuita?

Sì — il testo completo di «Connessione a Gmail tramite API» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.

Cosa imparerò in «Connessione a Gmail tramite API»?

Libreria client Google API, consenso OAuth2 e selezione degli scope di Gmail Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Agents?

Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Connessione a Gmail tramite API»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Agents?

Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Connessione a Gmail tramite API
  2. Lettura e invio programmatico delle email
  3. Creazione e consultazione degli eventi del calendario
  4. Creazione di un semplice agente assistente email
← Torna a AI Agents