Solución:
Investigando muchos enfoques diferentes, descubrí que lo que quería era la autenticación de servidor a servidor. De esta manera, ningún usuario tiene que otorgar permisos explícitamente y los tokens de autenticación adquiridos no tienen que renovarse. En cambio, utilizando una cuenta de servicio, un servidor puede realizar llamadas por sí mismo.
Antes de que pueda comenzar a codificar, debe configurar dicha cuenta de servicio y agregarla a su calendario al que desea que acceda la cuenta de servicio. Google ha escrito los tres pasos para crear una cuenta aquí. Luego, vaya a https://calendar.google.com, ubique en el lado izquierdo de la pantalla el calendario que desea compartir con su nueva cuenta de servicio y haga clic en el triángulo al lado. En el menú desplegable, elija la configuración del calendario. Esto lo lleva a una pantalla donde encontrará el ID de calendario que necesitará más adelante (así que anótelo) y también muestra una pestaña en la parte superior para compartir el acceso al calendario. Como “persona” inserta la dirección de correo electrónico de la cuenta de servicio, dale los permisos respectivos y clic en Guardar (si no hace clic en guardar, la cuenta de servicio no se agregará).
El código para esto es bastante elegante:
import os
from datetime import timedelta
import datetime
import pytz
import httplib2
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
service_account_email="[email protected]"
CLIENT_SECRET_FILE = 'creds.p12'
SCOPES = 'https://www.googleapis.com/auth/calendar'
scopes = [SCOPES]
def build_service():
credentials = ServiceAccountCredentials.from_p12_keyfile(
service_account_email=service_account_email,
filename=CLIENT_SECRET_FILE,
scopes=SCOPES
)
http = credentials.authorize(httplib2.Http())
service = build('calendar', 'v3', http=http)
return service
def create_event():
service = build_service()
start_datetime = datetime.datetime.now(tz=pytz.utc)
event = service.events().insert(calendarId='<YOUR EMAIL HERE>@gmail.com', body={
'summary': 'Foo',
'description': 'Bar',
'start': {'dateTime': start_datetime.isoformat()},
'end': {'dateTime': (start_datetime + timedelta(minutes=15)).isoformat()},
}).execute()
print(event)
Estoy usando la versión 2.2.0 de oauth2client (pip install oauth2client
).
Espero que esta respuesta ayude 🙂
Como esta publicación fue hace bastante tiempo, quería compartir mi versión 2020. Gracias por esta publicación. Me ayudó mucho a lograr mi objetivo.
import datetime
from datetime import timedelta
import pytz
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
service_account_email = "INSERT_HERE"
SCOPES = ["https://www.googleapis.com/auth/calendar"]
credentials = ServiceAccountCredentials.from_json_keyfile_name(
filename="FILENAME.json", scopes=SCOPES
)
def build_service():
service = build("calendar", "v3", credentials=credentials)
return service
def create_event():
service = build_service()
start_datetime = datetime.datetime.now(tz=pytz.utc)
event = (
service.events()
.insert(
calendarId="[email protected]",
body={
"summary": "Foo",
"description": "Bar",
"start": {"dateTime": start_datetime.isoformat()},
"end": {
"dateTime": (start_datetime + timedelta(minutes=15)).isoformat()
},
},
)
.execute()
)
print(event)
create_event()
Solo una nota aquí: aunque el código funciona, según https://github.com/googleapis/google-auth-library-python/blob/7a8641a7f0718c0dce413436f23691e8590face1/docs/index.rst, oauth2client ha sido obsoleto recientemente a favor de google- biblioteca de autenticación: https://github.com/googleapis/google-auth-library-python/tree/edfe24602051969e32917e82bcedd2bace43e260
Puede encontrar la documentación de la nueva biblioteca aquí: https://google-auth.readthedocs.io/en/latest/user-guide.html
Para usar la nueva biblioteca, el código se puede escribir como
import datetime
from datetime import timedelta
import pytz
from google.oauth2 import service_account
from googleapiclient.discovery import build
service_account_email = "[email protected]"
SCOPES = ["https://www.googleapis.com/auth/calendar"]
credentials = service_account.Credentials.from_service_account_file('google_calendar_credential.json')
scoped_credentials = credentials.with_scopes(SCOPES)
def build_service():
service = build("calendar", "v3", credentials=scoped_credentials)
return service
def create_event():
service = build_service()
start_datetime = datetime.datetime.now(tz=pytz.utc)
event = (
service.events()
.insert(
calendarId="primary",
body={
"summary": "Foo 2",
"description": "Bar",
"start": {"dateTime": start_datetime.isoformat()},
"end": {
"dateTime": (start_datetime + timedelta(minutes=15)).isoformat()
},
},
)
.execute()
)
print(event)
create_event()
Como no tengo suficiente reputación para publicar esto como comentario, lo estoy publicando como una publicación separada.