0
votes

I am trying to access the Google Calendar API using VBScript and Oauth offline access. I managed to get a refresh token and an access token, and now I want to get to the step where I actually use the API, using the following code:

sUrl="https://www.googleapis.com/calendar/v3/users/me/calendarList"
sRequest = "access_token="&accesstoken

response=HTTPPost (sUrl, sRequest)

Function HTTPPost(sUrl, sRequest)
    set oHTTP = CreateObject("MSXML2.ServerXMLHTTP")
    oHTTP.open "POST", sUrl,false
    oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    oHTTP.setRequestHeader "Content-Length", Len(sRequest)
    oHTTP.send sRequest
    HTTPPost = oHTTP.responseText
End Function

The response I get is :

    {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}

This is even though the access token is valid - If I change sURL to https://www.googleapis.com/oauth2/v1/tokeninfo and run the script I get the following response showing a valid token:

{
"issued_to": "...",
 "audience": "...,
"scope": "https://www.googleapis.com/auth/calendar",
"expires_in": 2568,
"access_type": "offline"
}

And also if I paste the URL https://www.googleapis.com/calendar/v3/users/me/calendarList?access_token=... into a browser I get a valid response from Google listing the user's calendars

3

3 Answers

0
votes

401: Invalid Credentials

Invalid authorization header. The access token you're using is either expired or invalid.

Access tokens are only good for 1 hour. After the hour is up the access token has expired and you need to use the refresh token to request a new one.

The raw code to get a new acesss token looks something like this. the key is grant_type=refresh_token this tells the authentication server you are requesting a new token.

https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
0
votes

Your code uses HTTP POST but use an HTTP GET request is required as specified here: https://developers.google.com/google-apps/calendar/v3/reference/calendarList/list. Also, you can provide the access token in the access_token parameter (and not in the oauth_token parameter as suggested in the other answer), but another option is to provide it in an Authorization header as in:

Authorization: Bearer <token>

As an example, a token that returns from:

curl -v https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<token>`

the following introspection result:

{
 "issued_to": "<...>.apps.googleusercontent.com",
 "audience": "<...>.apps.googleusercontent.com",
 "user_id": "<...>",
 "scope": "<> https://www.googleapis.com/auth/calendar",
 "expires_in": 3527,
 "email": "<...>",
 "verified_email": true,
 "access_type": "offline"
}

can be used in against the Calendar API URL:

curl -v -H "Authorization: Bearer <>" https://www.googleapis.com/calendar/v3/users/me/calendarList

so that it gives me a list of JSON calendar data:

{
 "kind": "calendar#calendarList",
 "etag": "\"1420511621463000\"",
 "nextSyncToken": "00001420511621463000",
 "items": [
  {
   "kind": "calendar#calendarListEntry",
   "etag": "\"1418127331044000\"",
...
0
votes

I managed to figure this out - the calendarList API requires sending an empty body, therefore I change the code to:

set oHTTP = CreateObject("MSXML2.ServerXMLHTTP")
oHTTP.open "GET", sUrl&srequest,false
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHTTP.send

getcal = oHTTP.responseText