I'm trying to connect events withing py project to google calendar. my application doesn't used google login as it is intended for only a small group of people. I've been looking for hours on how to get it done and it doesnt work. Any help is appreciated.
models.py
class AgendaClient(models.Model): # used to store info(same as enviroment variables)
name = models.CharField(max_length=30, null=True, blank=True, unique=True)
json = models.TextField(blank=True, null=True)
class Event(models.Model):
summary = models.CharField(max_length=50, choices=EVENT_CHOICES)
description = models.CharField(max_length=50, null=True, blank=True)
start_date = models.DateField()
google_link = models.CharField(max_length=150, null=True, blank=True)
signals.py
import datetime
import json
from django.db.models.signals import post_delete, post_save
from google.auth.transport.requests import Request
from google.cloud import storage
from google.oauth2 import service_account
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from users.models import Lid
from .models import AgendaClient, Event, NIEvent
# If modifying these scopes, delete the file token.json.
try:
SCOPES = (AgendaClient.objects.get(name='SCOPES').json).strip("][").split(', ')
except: pass
def get_service(refresh = False):
'''this functions gets and builds the service using the token and the client_secret'''
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if len(AgendaClient.objects.filter(name='token'))==1:
creds = Credentials.from_authorized_user_info(json.loads(AgendaClient.objects.get(name='token').json), SCOPES)
else:
# pprint(json.loads(AgendaClient.objects.get(name='service_account').json))
creds = service_account.Credentials.from_service_account_info(json.loads(AgendaClient.objects.get(name='service_account').json), scopes=SCOPES)
# Explicitly use service account credentials by specifying the private key
# file.
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
# pprint(json.loads(AgendaClient.objects.get(name='client_secret').json))
flow = InstalledAppFlow.from_client_config(
json.loads(AgendaClient.objects.get(name='client_secret').json), SCOPES)
creds = flow.run_local_server(port=0)
# creds = service_account.Credentials.from_service_account_info(json.loads(AgendaClient.objects.get(name='service_account').json), scopes=SCOPES)
# Save the credentials for the next run
AgendaClient.objects.update_or_create(name='token', defaults = {'json':creds.to_json()})
if not refresh:
service = build('calendar', 'v3', credentials=creds)
return service
def handle_event(sender,created, instance=None, **kwargs):
"""this function creates the events in the google agenda and updates them if changed in the website
"""
service = get_service()
evs = instance
event ={
'summary': evs.description,
'location': evs.location or "",
'description': (evs.description+' '+ evs.summary),
'start': {
'dateTime': datetime.datetime.combine(evs.start_date,evs.start_time).isoformat(),
'timeZone': 'Europe/Amsterdam',
},
'end': {
'dateTime':datetime.datetime.combine(evs.end_date,evs.end_time).isoformat() ,
'timeZone': 'Europe/Amsterdam',
},
'recurrence': [],'reminders': {}}
if created or not instance.google_link:
try:
event = service.events().insert(calendarId=AgendaClient.objects.get(name='calendarId').json, body=event).execute()
instance.google_link = event['id']
instance.save()
except HttpError as error:
print('An error occurred: %s' % error)
pass
else:
try:
# print(type(AgendaClient.objects.get(name='calendarId').json))
event = service.events().update(calendarId=AgendaClient.objects.get(name='calendarId').json, body=event, eventId = instance.google_link).execute()
except HttpError as error:
print('An error occurred: %s' % error)
pass
post_save.connect(handle_event, sender=Event)
Ideally, I would use a service account so that users dont have to log in to google. Maybe someone knows a better solution than this but essentially the website should be able to add events to a calendar that users can follow but not add events to each user's calendar.
After looking every where i found the answer. I posted it under Google Calendar Integration with Django because thats where i got the majority of the info needed
Thanks for the help