Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Calendar API - Access own calendar via Service account

I want to access the Google Calendar API to insert entries with Python. I created a Service account on the Google API console, added an private key, downloaded it.

But when I try to modify anyting of my calendar, it is on the same account, I get the following error message. Reading works.

Code is

import httplib2

from oauth2client.client import SignedJwtAssertionCredentials 
from apiclient.discovery import build

event = {
         'summary' : 'Appointment',
         'location' : 'Somewhere',
         'start' : {
                    'dateTime' : '2012-09-03T10:00:00.000-07:00'
                    },
         'end' :    {
                 'dateTime' : '2012-09-03T10:25:00.000-07:00'
                    }
}


f = file("key.p12", "rb")
key = f.read()
f.close()

credentials = SignedJwtAssertionCredentials(
                                                service_account_name='[email protected]',
                                                private_key=key,

                                                scope='https://www.googleapis.com/auth/calendar'                                            
                                            )

http = httplib2.Http()
http = credentials.authorize(http)

service = build('calendar', 'v3', http=http)
request = service.events().insert(calendarId='[email protected]', body=event)

response = request.execute()

print(response)

Error message is:

apiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/[email protected]/events?alt=json returned "Forbidden">

I would have thought that I can access my own data with this service account, but it seems not to be.

Google claims that

After the Service Account has been created, you will also have access to the client ID associated with the private key. You will need both when coding your application. - https://developers.google.com/accounts/docs/OAuth2?hl=de#scenarios

I googled about 2 hours, but it seems to be documented very bad. Is there a way I can insert new events via the Google Calendar API without user interaction (aka 3-legged OAuth) or is there a way to fix it?

I just found deprecated ClientLoging. Why does Google makes it that difficult?

Kind regards

like image 803
jcklie Avatar asked Sep 03 '12 18:09

jcklie


People also ask

How do I use Google Calendar with non Gmail users?

Go to https://accounts.google.com/NewAccount and create a Google Account for your business email address or any other email address that you would like the Google Calendar account to use.


1 Answers

I realized that 3-stepped OAuth works if one dumps the resulting credentials to JSON and reads them in every time you need them.

So the flow is: Add your client_secrets.json as stated on Google API in the same folder as this script. Grab the key from the url given in the prompt. Enter it on request to the prompt. Party!11. I hope these credentials last forever.

from oauth2client.client import flow_from_clientsecrets

flow = flow_from_clientsecrets('client_secrets.json',
                               scope='https://www.googleapis.com/auth/calendar',
                               redirect_uri='urn:ietf:wg:oauth:2.0:oob')

auth_uri = flow.step1_get_authorize_url()
print('Visit this site!')
print(auth_uri)
code = raw_input('Insert the given code!')
credentials = flow.step2_exchange(code)
print(credentials)

with open('credentials', 'wr') as f:
    f.write(credentials.to_json())

Now, in the application itself:

def __create_service():
    with open('credentials', 'rw') as f:
        credentials = Credentials.new_from_json(f.read())

    http = httplib2.Http()
    http = credentials.authorize(http)

    return build('calendar', 'v3', http=http)

To get a service object, one can now call

service = __create_service()

and use the API on it.

like image 99
jcklie Avatar answered Sep 19 '22 07:09

jcklie