Search code examples
c#asp.netgoogle-apigoogle-calendar-apigoogle-oauth

How to access users calendar list and events from google api using access token and refresh token


I already have obtained users access token from google api using oAuth2. Now i want to use this token to get user events/calendars. I have tried following code but it is not working.

Can anyone here help me with this please. Thanks

    var urlBuilder = new System.Text.StringBuilder();

    urlBuilder.Append("https://");
    urlBuilder.Append("www.googleapis.com");
    urlBuilder.Append("/calendar/v3/users/me/calendarList");
    urlBuilder.Append("?minAccessRole=reader");

    var httpWebRequest = HttpWebRequest.Create(urlBuilder.ToString()) as HttpWebRequest;

    httpWebRequest.CookieContainer = new CookieContainer();
    httpWebRequest.Headers["Authorization"] string.Format("Bearer {0}", data.access_token);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream eventResponseStream = response.GetResponseStream();
    StreamReader eventResponseStreamReader = new StreamReader(responseStream);
    string eventsStr = eventResponseStreamReader.ReadToEnd();

Solution

  • I have found solution using Google.Apis.Calendar.v3, i am posting it here so may help someone else. Following is the code to get the events list when you have refresh token of a user:

    First get new access token using the refresh token:

    string postString = "client_id=yourclientid";
    postString += "&client_secret=youclientsecret&refresh_token=userrefreshtoken";
    postString += "&grant_type=refresh_token";
    string url = "https://www.googleapis.com/oauth2/v4/token";
    
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url.ToString());
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    UTF8Encoding utfenc = new UTF8Encoding();
    byte[] bytes = utfenc.GetBytes(postString);
    Stream os = null;
    
        request.ContentLength = bytes.Length;
        os = request.GetRequestStream();
        os.Write(bytes, 0, bytes.Length);
    
    
        GoogleToken token = new GoogleToken();
    
        HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
        Stream responseStream = webResponse.GetResponseStream();
        StreamReader responseStreamReader = new StreamReader(responseStream);
        string result = responseStreamReader.ReadToEnd();
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        token = serializer.Deserialize<GoogleToken>(result);
    

    Then use the toke and refresh token to create credentials.

    var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                    {
                        ClientId = yourclientid,
                        ClientSecret = yourclientsecret
                    },
                    Scopes = new[] { CalendarService.Scope.Calendar }
                });
    
    
    
                var credential = new UserCredential(flow, Environment.UserName, new TokenResponse
                {
                    AccessToken = token.access_token,
                    RefreshToken = userrefreshtoke
                });
    
    
                CalendarService service = new CalendarService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "application name",
                });
                var list = service.CalendarList.List().Execute().Items;
                foreach (var c in list)
                {
                    var events = service.Events.List(c.Id).Execute().Items.Where(i => i.Start.DateTime >= DateTime.Now).ToList();
                    foreach (var e in events)
                    {
                    }
    }
    

    GoogleToken class:

     public class GoogleToken
        {
            public string access_token { get; set; }
            public string token_type { get; set; }
            public string expires_in { get; set; }       
        }