Search code examples
pythondjangogoogle-apigoogle-calendar-apigoogle-oauth

403 error when receiving Google Calendar API notification


I have calendar events being created successfully for various GSuite users, then I'd like to set a watch event. I'm able to do that successfully:

SCOPES = ['https://www.googleapis.com/auth/calendar']
SERVICE_ACCOUNT_FILE = BASE_DIR + 'path_to_json'

credentials = service_account.Credentials.from_service_account_file(
    SERVICE_ACCOUNT_FILE, scopes=SCOPES)

delegated_user = credentials.with_subject(user)
delegated_service = googleapiclient.discovery.build('calendar', 'v3', credentials=delegated_user)


event = {
        'summary': '%s at %s' % (event_name, event_location),
        'description': 'description',
        'location': event_address,
        'extendedProperties': {
            "private": {
                'briefType': event_name,
            }
        },
        'start': {
            'dateTime': event_start_time.astimezone().isoformat(),
        },
        'end': {
            'dateTime': event_end_time.astimezone().isoformat(),
        }

    }


event = delegated_service.events().insert(calendarId='primary', body=event).execute()

watch_body = {
    'id': event['id'],
    'type': 'web_hook',
    'address': 'https://example.com/googleapi'
}

watch = delegated_service.events().watch(calendarId='primary', body=watch_body).execute()

I'm not quite sure how to receive the push notification. I've registered/added my domain (per https://developers.google.com/calendar/v3/push), and when I change the event in Google Calendar I'm getting an API Push notification, but I'm receiving a 403 error:

Dec 11 20:58:38 ip-xxx gunicorn[3104]:  - - [11/Dec/2019:20:58:38 +0000] "POST /googleapi HTTP/1.0" 403 1889 "-" "APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)"

How do I authenticate in the view that process /googleapi to be able to actually receive the API notification from Google?

I've tried the following just to try to debug what I'm receiving from Google, but I get nothing besides the 403 error:

def GoogleAPIWatchView(request):

    SCOPES = ['https://www.googleapis.com/auth/calendar']
    SERVICE_ACCOUNT_FILE = BASE_DIR + 'path_to_json'

    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    regex = re.compile('^HTTP_')
    headers = dict((regex.sub('', header), value) for (header, value) 
           in request.META.items() if header.startswith('HTTP_'))

    print(headers)
    print(request)

    return JsonResponse('success', status=200, safe=False)

Solution

  • It seems like this HTTP 403 raised because of failed verification of CSRF token. So, use csrf_exempt--Django doc decorator to skip the verification process

    #views.py
    from django.views.decorators.csrf import csrf_exempt
    
    
    @csrf_exempt  # This skips csrf validation.
    def GoogleAPIWatchView(request):
        ...
        # do something useful