--- title : Google.Apis.Calendar.v3 tags: Google.Apis.Calendar.v3 creat-date: 2022-01-19 update_date : 2022-01-19 --- --- # 使用 Google.Apis.Calendar.v3 --- ## 步驟一:取得授權 **1.建立 Google 一個專案,申請網址:** https://console.developers.google.com/projectselector/apis/library?supportedpurview=project **2.專案建立完成後「建立憑證」,選擇「OAuth用戶端ID」** ![](https://i.imgur.com/8jKpHRh.png) **3.填寫相關資料,「已授權的重新導向URI」一定要填寫** ![](https://i.imgur.com/zdpAxkh.png) **4.下載JSON,並在系統程式中建立一個資料夾GoogleStorage存放檔案「client_secret.json」** ![](https://i.imgur.com/G0FwTv9.png) **5.Nuget 下載 Google.Apis.Calendar.v3 套件** ![](https://i.imgur.com/8bEUGPu.png) **6.點擊授權後的程式碼** ```C#=1 protected void btnStart_Click(object sender, EventArgs e) { GoogleClientSecrets clientSecret; //匯入專案憑證 using (var stream = new FileStream(Gfolder + @"\client_secret.json", FileMode.Open, FileAccess.Read)) { clientSecret = GoogleClientSecrets.Load(stream); } //建立流程權限 IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow( new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = clientSecret.Secrets, DataStore = new FileDataStore(Gfolder), Scopes = new[] { CalendarService.Scope.Calendar } }); var uri = System.Web.HttpContext.Current.Request.Url.ToString(); var result = new AuthorizationCodeWebApp(flow, uri, "success").AuthorizeAsync(UserId, CancellationToken.None).Result; if (result.RedirectUri != null) { //導去授權頁 Response.Redirect(result.RedirectUri); } } ``` **從Google 授權後回來的處理** ```C#=1 /// <summary>App 憑證資料的檔案夾</summary> public static string Gfolder = AppDomain.CurrentDomain.BaseDirectory + "GoogleStorage" + System.IO.Path.DirectorySeparatorChar; /// <summary>通常在就是用戶的資料庫 id</summary> public static string UserId = "CSMS"; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { GoogleClientSecrets clientSecret; using (var stream = new FileStream(Gfolder + @"\client_secret.json", FileMode.Open, FileAccess.Read)) { clientSecret = GoogleClientSecrets.Load(stream); } IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow( new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = clientSecret.Secrets, DataStore = new FileDataStore(Gfolder), Scopes = new[] { CalendarService.Scope.Calendar } }); var uri = HttpContext.Current.Request.Url.ToString(); var code = HttpContext.Current.Request["code"]; if (code != null) { var token = flow.ExchangeCodeForTokenAsync(UserId, code, uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result; //儲存使用者的Token var oauthState = AuthWebUtility.ExtracRedirectFromState( flow.DataStore, UserId, Request["state"]).Result; //印出儲存狀態 Response.Write(oauthState); } } } ``` **7.執行結果** ![](https://i.imgur.com/w59JkE0.png) **成功回來後,會在資料夾「GoogleStorage」看到多一個檔案 : Google.Apis.Auth.OAuth2.Responses.TokenResponse-CSMS (我的UserId = "CSMS",所以檔名會是CSMS)** ![](https://i.imgur.com/R7sUWu9.png) ## 步驟二:交換 Token ### **說明:access_token 只能存活一小時,需要跟 google 再重新交換以取得新的Token。** ```C#=1 /// <summary>App 憑證資料的檔案夾</summary> public static string Gfolder = AppDomain.CurrentDomain.BaseDirectory + "GoogleStorage" + System.IO.Path.DirectorySeparatorChar; /// <summary>通常在就是用戶的資料庫 id </summary> public static string UserId = "CSMS"; protected void btnRefreshToken_Click(object sender, EventArgs e) { var userAccessToken = JsonConvert.DeserializeObject<GoogleTokenModel>(File.ReadAllText(Gfolder + "Google.Apis.Auth.OAuth2.Responses.TokenResponse-" + UserId)); try { using (var wb = new WebClient()) { var data = new NameValueCollection(); data["refresh_token"] = userAccessToken.refresh_token; data["client_id"] = "000000000-xxxxxxxxx.apps.googleusercontent.com"; data["client_secret"] = "xxxxxxxxx"; data["grant_type"] = "refresh_token"; var response = wb.UploadValues("https://accounts.google.com/o/oauth2/token?", "POST", data); string responseUTF8 = System.Text.Encoding.UTF8.GetString(response); var changeTokenResponse = JsonConvert.DeserializeObject<GoogleTokenModel>(responseUTF8); Response.Write("Token 從原本的 :" + userAccessToken.access_token + " 換成: " + changeTokenResponse.access_token); userAccessToken.access_token = changeTokenResponse.access_token; File.WriteAllText(Gfolder + "Google.Apis.Auth.OAuth2.Responses.TokenResponse-" + UserId, JsonConvert.SerializeObject(userAccessToken)); } } catch (Exception ex) { Response.Write(ex.Message); } } ``` ## 步驟三:新增、刪除、取得資料範例 ```C#=1 /// <summary>App 憑證資料的檔案夾</summary> public static string Gfolder = AppDomain.CurrentDomain.BaseDirectory + "GoogleStorage" + System.IO.Path.DirectorySeparatorChar; /// <summary>通常在就是用戶的資料庫 id </summary> public static string UserId = "CSMS"; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { RefreshToken(); // 重新取得 Google Token } } /// <summary> /// 重新取得 Google Token /// </summary> protected void RefreshToken() { ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; var userAccessToken = JsonConvert.DeserializeObject<GoogleTokenModel>(File.ReadAllText(Gfolder + "Google.Apis.Auth.OAuth2.Responses.TokenResponse-" + UserId)); try { using (var wb = new WebClient()) { var data = new NameValueCollection(); data["refresh_token"] = userAccessToken.refresh_token; data["client_id"] = "00000000-xxxxxx.apps.googleusercontent.com"; data["client_secret"] = "XXXXXXXXXXX"; data["grant_type"] = "refresh_token"; var response = wb.UploadValues("https://accounts.google.com/o/oauth2/token?", "POST", data); string responseUTF8 = System.Text.Encoding.UTF8.GetString(response); var changeTokenResponse = JsonConvert.DeserializeObject<GoogleTokenModel>(responseUTF8); //Response.Write("Token 從原本的 :" + userAccessToken.access_token + " 換成: " + changeTokenResponse.access_token); userAccessToken.access_token = changeTokenResponse.access_token; File.WriteAllText(Gfolder + "Google.Apis.Auth.OAuth2.Responses.TokenResponse-" + UserId, JsonConvert.SerializeObject(userAccessToken)); } } catch (Exception ex) { //Response.Write(ex.Message); } } /// <summary> /// 新增行事曆資料[測試] /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnAddCalendar_Click(object sender, EventArgs e) { Event event1 = new Event() { Summary = "隨身秘書[測試]", Location = "立法院群賢樓202會議室", Description = "主持人:張廖萬堅<br/>本局與會人員:堅測管理組坡地管理科周玉奇科長、農村建設組農村規劃科陳明賢科長", Start = new EventDateTime() { DateTime = new DateTime(2019, 12, 31), TimeZone = "Asia/Taipei" }, End = new EventDateTime() { DateTime = new DateTime(2019, 12, 31).AddHours(1), TimeZone = "Asia/Taipei" }, }; var d = JsonConvert.DeserializeObject<GoogleTokenModel>(File.ReadAllText(Gfolder + "Google.Apis.Auth.OAuth2.Responses.TokenResponse-" + UserId)); CalendarService calService = GetCalendarService(d); EventsResource eventResource = new EventsResource(calService); var insertEntry = eventResource.Insert(event1, "primary").Execute(); txtEventId.Text = insertEntry.Id; } /// <summary> /// 刪除行事曆資料[測試] /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnDel_Click(object sender, EventArgs e) { var d = JsonConvert.DeserializeObject<GoogleTokenModel>(File.ReadAllText(Gfolder + "Google.Apis.Auth.OAuth2.Responses.TokenResponse-" + UserId)); CalendarService calService = GetCalendarService(d); EventsResource eventResource = new EventsResource(calService); eventResource.Delete("primary", txtEventId.Text).Execute(); Response.Write("成功刪除 :" + txtEventId.Text); } /// <summary> /// 取得日期區間的行事曆[測試] /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnRequest_Click(object sender, EventArgs e) { var d = JsonConvert.DeserializeObject<GoogleTokenModel>(File.ReadAllText(Gfolder + "Google.Apis.Auth.OAuth2.Responses.TokenResponse-" + UserId)); CalendarService calService = GetCalendarService(d); EventsResource.ListRequest listRequest = new EventsResource.ListRequest(calService, "primary"); listRequest.TimeMin = new DateTime(2019, 12, 31); listRequest.TimeMax = new DateTime(2019, 12, 31); listRequest.ShowDeleted = false; listRequest.SingleEvents = true; listRequest.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime; Events events = listRequest.Execute(); string response = ""; if (events.Items != null && events.Items.Count > 0) { foreach (var eventItem in events.Items) { string when = eventItem.Start.DateTime.ToString(); if (String.IsNullOrEmpty(when)) { when = eventItem.Start.Date; } string sContent = string.Format("時間:{0}<br/>主旨:{1}<br/>地點:{2}<br/>內容:{3}", when, eventItem.Summary, eventItem.Location, eventItem.Description); response += sContent + "<br/>"; } } Response.Write("取得資料 :<br/><br/>" + response); } ``` ## 步驟四:防火牆使用申請 (1) accounts.google.com (2) oauth2.googleapis.com (3) www.googleapis.com ## 測試執行畫面 **1.新增資料** ![](https://i.imgur.com/xSJPOHE.png) ![](https://i.imgur.com/l3cVy6e.png) **2.取得行事曆資料** ![](https://i.imgur.com/JAPuhvg.png) **3.刪除資料** ![](https://i.imgur.com/zeDWw74.png) ![](https://i.imgur.com/IKTXrla.png) ## 參考來源: (1)憑證授權:https://blog.no2don.com/2017/12/caspnet-googleapiscalendarv3.html (2)新增刪除:https://blog.no2don.com/2017/12/caspnet-googleapiscalendarv3_19.html (3)交換Token:https://blog.no2don.com/2017/12/caspnet-googleapiscalendarv3-token.html