djangogoogle-calendar-apipython-social-auth

Can't get calendar api events from user


So I can currently log in with my social user account but can't seem to access the calendar api events of that user. It is a web app so the following code seems to open another tab.

enter image description here

Flow: login->main page->calendar(localhost:8000/accounts/login-> localhost:8000->localhost:8000/calendar)

@login_required
def calendar(request):
    context={}  
    results = get_user_events(request)
    context['results'] = results
    context['nmenu'] = 'calendar'
   

    return render(request, 'home.html', context)

calendar.py

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
import os
def get_user_events(request):
    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 os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # 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:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    try:
        service = build('calendar', 'v3', credentials=creds)

        # Call the Calendar API
        now = datetime.datetime.utcnow().isoformat() + 'Z'  # 'Z' indicates UTC time
        print('Getting the upcoming 10 events')
        events_result = service.events().list(calendarId='primary', timeMin=now,
                                              maxResults=10, singleEvents=True,
                                              orderBy='startTime').execute()
        events = events_result.get('items', [])

        if not events:
            print('No upcoming events found.')
            return

        # Prints the start and name of the next 10 events
        for event in events:
            start = event['start'].get('dateTime', event['start'].get('date'))
            print(start, event['summary'])
        return events

    except HttpError as error:
        print('An error occurred: %s' % error)
        return []

My Uris

enter image description here

urls.py:

from django.conf import settings
from django.contrib import admin
from django.conf.urls.static import static
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('pages.urls')),
    path('accounts/', include('django.contrib.auth.urls')),
    path('oauth/', include('social_django.urls', namespace='social'))
    
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 

Solution

  • Redirect URI miss match is a common oauth error. This is the locaion that you wish the authorization to be returned to. It must be registered in Google cloud console

    according to the error message you are sending http://localhost:someport/

    This must exactly match one of the ones that you have added in google cloud console for your project you do not apear to have that listed.

    The solution is to take the uri from the error message and add it. Remember it must match exactly that means port and your trailing /. If your app is changing the port every time you run you will need to fix it so that it runs off of a static port so that you can add it as a redirect uri.

    If you dont know how to fix it this video will show you how to do that. Google OAuth2: How the fix redirect_uri_mismatch error. Part 2 server sided web applications.