I am trying to add a new event to a calendar, but I am getting the error that I don't have permission to do that. However, I can get the calendars and the events, because I have read permissions.
My code is this:
static string[] ScopesParaModificar = { CalendarService.Scope.Calendar };
private void SetCredentialParaModificar()
{
using (FileStream stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
string credPath = "token.json";
_credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.FromStream(stream).Secrets,
ScopesParaModificar,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
}
private CalendarService GetCalendarService()
{
return new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = _credential,
ApplicationName = ApplicationName,
});
}
private void ucBtnCrearEvento_Click(object sender, RoutedEventArgs e)
{
CalendarService miCalendarService = GetCalendarService();
IEnumerable<CalendarListEntry> misCalendarios = miCalendarService.CalendarList.List().Execute().Items;
CalendarListEntry miCalendario = misCalendarios.FirstOrDefault(x => string.CompareOrdinal(x.Summary, "TestAGarcia") == 0);
Event miEventoNuevo = new Event();
miEventoNuevo.Id = "1";
miEventoNuevo.Summary = "Esto es Summary 01";
miEventoNuevo.Description = "Esto es el description";
Event.CreatorData miCreador = new Event.CreatorData();
miCreador.DisplayName = "DisplayName of creator";
miCreador.Email = "email del creador";
miCreador.Id = "ID creador";
miEventoNuevo.Creator = miCreador;
miCalendarService.Events.Insert(miEventoNuevo, miCalendario.Id).Execute();
}
Notice that when I set _credential, I am using the array that it uses the scope calendar, that it says that it is what I have to use if I want to modify events.
Thanks.
Related
I have created an ASP.Net Core MVC project and integrated the Google Calendar API:
Google.Apis.Calendar.v3 with a NuGet package
I followed this guide.
it seems to work since i see some records from my calendar in the output window of my visual studio
but the page themself never stops loading?
i removed the default pages and events in the HomeController only Index is left
and replaced the code from the program.cs with the code from google.
namespace CalendarQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-dotnet-quickstart.json
static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
static string ApplicationName = "Google Calendar API .NET Quickstart";`
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
EventsResource.ListRequest request = service.Events.List("primary");
request.TimeMin = DateTime.Now;
request.ShowDeleted = false;
request.SingleEvents = true;
request.MaxResults = 10;
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
// List events.
Events events = request.Execute();
Console.WriteLine("Upcoming events:");
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;
}
Console.WriteLine("{0} ({1})", eventItem.Summary, when);
}
}
else
{
Console.WriteLine("No upcoming events found.");
}
Console.Read();
}
}
}
so I can't see my index view.
replacing the List Events with :
CreateWebHostBuilder(args).Build().Run();
and adding :
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
i am able to see the Index Page/View again
UPDATE: I solved this problem and posted the solution as an answer below! ;)
I need to create an event and add it to Google Calendar using Google API.
For now I only know how to get all the events I have from Google Calendar. This is what I've got so far:
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
namespace CalendarQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-dotnet-quickstart.json
static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
static string ApplicationName = "Google Calendar API .NET Quickstart";
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
EventsResource.ListRequest request = service.Events.List("primary");
request.TimeMin = DateTime.Now;
request.ShowDeleted = false;
request.SingleEvents = true;
request.MaxResults = 10;
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
// List events.
Events events = request.Execute();
Console.WriteLine("Upcoming events:");
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;
}
Console.WriteLine("{0} ({1})", eventItem.Summary, when);
}
}
else
{
Console.WriteLine("No upcoming events found.");
}
Console.Read();
}
}
}
What I am trying to do must be looking something like this:
var ev = new Event();
EventDateTime start = new EventDateTime();
start.DateTime = new DateTime(2019, 3, 11, 10, 0, 0);
EventDateTime end = new EventDateTime();
end.DateTime = new DateTime(2019, 3, 11, 10, 30, 0);
ev.Start = start;
ev.End = end;
ev.Description = "Description...";
events.Items.Insert(0, ev);
I've spent the entire day searching any .NET samples but got nothing.
Any help appreciated! ;)
I've solved this problem! So before building the project change
static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
to
static string[] Scopes = { CalendarService.Scope.Calendar };
If you already built the solution then delete credentials.json file and then reload it. The code for adding an event is here:
var ev = new Event();
EventDateTime start = new EventDateTime();
start.DateTime = new DateTime(2019, 3, 11, 10, 0, 0);
EventDateTime end = new EventDateTime();
end.DateTime = new DateTime(2019, 3, 11, 10, 30, 0);
ev.Start = start;
ev.End = end;
ev.Summary = "New Event";
ev.Description = "Description...";
var calendarId = "primary";
Event recurringEvent = service.Events.Insert(ev, calendarId).Execute();
Console.WriteLine("Event created: %s\n", e.HtmlLink);
This is my first try with Google API so don't judge me ;) Hope it helps somebody one day!
Note : You also need to remove the 'token.json' folder from \bin\debug folder
I started with the basics and learned how to insert a fixed bit of rows to a Google Sheet from my program now I've been trying to figure out how to append output from a SQL. I have a C# program that calls a stored procedure or it can do a select * from table. Simply trying to insert the results/output of that select into a Google Sheet. Every example I find is dealing with hard coded fixed rows and columns. My select produces less than 2000 lines of output. Appreciate the help!
namespace CS_Gsheet1
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-dotnet-quickstart.json
//static string[] Scopes = { SheetsService.Scope.SpreadsheetsReadonly };
//static string ApplicationName = "Google Sheets API .NET Quickstart";
static string[] Scopes = { SheetsService.Scope.Spreadsheets };
static string ApplicationName = "Test3";
static void Main(string[] args)
{
var service = AuthorizeGoogleApp();
String spreadsheetId = "sheetIDstring";
// Write to specified sheet
String writeRange = "Sheet1!A1:K";
ValueRange valueRange = new ValueRange { MajorDimension = "ROWS" };
IList<object> dataList = new List<object>();
using(SqlConnection myConnection = new SqlConnection("connectionstring"))
{
myConnection.Open();
using(SqlCommand cmd = new SqlCommand("storedproc-selectsmultiplecolumnsandrows", myConnection))
{
cmd.CommandType = CommandType.StoredProcedure;
using(SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// dataList.Add(reader.GetString(0));
// dataList.Add(reader.GetValue(0));
IList<IList<Object>> values = new List<IList<Object>>();
values.Add(dataList);
}
}
}
}
// Data is accessible through the DataReader object here.
ValueRange valueDataRange = new ValueRange() { MajorDimension = "ROWS" };
valueDataRange.Values = new List<IList<object>> { dataList };
int c = dataList.Count;
Console.WriteLine("dataList Count {0}", c);
for (int i = 0; i < c; i++)
{
// API to append data to sheet
SpreadsheetsResource.ValuesResource.AppendRequest appendRequest = service.Spreadsheets.Values.Append(valueDataRange, spreadsheetId, writeRange);
appendRequest.ValueInputOption = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.RAW;
appendRequest.InsertDataOption = SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum.INSERTROWS;
AppendValuesResponse appendValueResponse = appendRequest.Execute();
}
}
private static SheetsService AuthorizeGoogleApp()
{
UserCredential credential;
using (var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.ReadWrite))
{
string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
// Create Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
return service;
}
}
}
}
I was able to tweak this solution to get the process to work without requesting a quota increase from Google. It does not run very fast, but ok for ~1000 records.
https://github.com/jeffcrowder/GoogleSheetsAPIExample/blob/master/GoogleSheetsAPIExample/Program.cs
After many trials and errors I managed to compile a piece of code which should return Entities' values from Google Datastore (it's SQL-like db). Code I used:
static async void Run()
{
UserCredential credential;
using (var stream = new FileStream(#"c:/fakepath/client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { DatastoreService.Scope.Datastore }, "user", CancellationToken.None);
}
// Create the service.
var service = new DatastoreService(new BaseClientService.Initializer
{
ApplicationName = "My Project",
HttpClientInitializer = credential
});
// Run the request.
Console.WriteLine("Executing a list request...");
var request = new LookupRequest();
var key = new Google.Apis.Datastore.v1beta2.Data.Key();
key.Path = new List<KeyPathElement> { new KeyPathElement() { Kind = "book", Name = "title42" } };
request.Keys = new List<Key>() { key };
var lookup = service.Datasets.Lookup(request, "project-name-192"); //yea
var response = lookup.Execute();
// Display the results.
if (response.Found != null)
{
foreach (var x in response.Found)
{
foreach (var y in x.Entity.Properties)
{
Console.WriteLine(y.Key.FirstOrDefault() + " " + y.Value);
}
}
}
}
Error I get:
So, what am I missing? I did just like in example on docs.
You need to go to:
https://console.developers.google.com/project/apps~{your-app-name}/apiui/credential
and use http://localhost:63324/authorize/ as the redirect url.
Remember to change it to your production url when you deploy
Currently I'm working with the v3 google calendar API. I have a specification which the local object needs to use dateTime, but google uses EventDateTime. I just wonder if there is a clever way to convert one to the other? I know it is possible to use tostring, but currently I have a hard time figuring out what prefixes I need to do so.
Thanks for any help.
According to the documentation it is possible to use a string formatted datetime.
setDate
public EventDateTime setDate(DateTime date)
The date, in the format "yyyy-mm-dd", if this is an all-day event.
Parameters:
date - date or null for none
Sample:
DateTime myDateTime = DateTime.Now();
string dateTimeString = myDateTime.ToString("yyyy-MM-dd HH:mm");
For the google calendar, your would probably create a EventDateTime object, and then set the date using the setDate(string datetime) method.
EventDateTime eventDateTime = new EventDateTime();
eventDateTime.setDate(dateTimeString);
To use a full day eventdatetime, you will omit the "HH:mm" from the ToString() method. I have never used this API, so something may be a bit off.
I hope this can help someone...building on scheien's answer above.
Im just gonna post all the code..as it might help someone messing with Google Calender.
I have Method Extension that converts DateTime to EventDateTime.
Example from code
evntNew.Start = oCalEvent.Start.ToEventDateTime();
Here the whole source. (feel free to edit)
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.IO;
using System.Threading;
namespace GoogleCalendarAPI
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-dotnet-quickstart.json
static string[] Scopes = { CalendarService.Scope.CalendarReadonly,
CalendarService.Scope.CalendarEvents,
CalendarService.Scope.Calendar};
static string ApplicationName = System.AppDomain.CurrentDomain.FriendlyName;
static void Main(string[] args)
{
CalendarEvent oCalEvent = new CalendarEvent();
oCalEvent.Summary = "Hello Calendar";
oCalEvent.Description = "Just another day";
oCalEvent.Location = "Earth";
oCalEvent.Start = DateTime.Now.AddDays(31);
oCalEvent.Stop = DateTime.Now.AddDays(31);
AddCalendarEvent(oCalEvent);
ListUpComing();
Console.Read();
}
static void ListUpComing()
{
UserCredential credential;
using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"admin",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
EventsResource.ListRequest request = service.Events.List("primary");
request.TimeMin = DateTime.Now;
request.ShowDeleted = false;
request.SingleEvents = true;
request.MaxResults = 10;
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
// List events.
Events events = request.Execute();
Console.WriteLine("Upcoming events:");
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;
}
Console.WriteLine("{0} ({1})", eventItem.Summary, when);
}
}
else
{
Console.WriteLine("No upcoming events found.");
}
Console.Read();
}
static void AddCalendarEvent(CalendarEvent oCalEvent)
{
UserCredential credential;
using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"admin",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
var service = new CalendarService(new BaseClientService.Initializer()
{ HttpClientInitializer = credential, ApplicationName = ApplicationName, }); // Create Google Calendar API service.
Event evntNew = new Event();
evntNew.Summary = oCalEvent.Summary;
evntNew.Location = oCalEvent.Location;
evntNew.Description = oCalEvent.Description;
evntNew.Start = oCalEvent.Start.ToEventDateTime();
evntNew.End = oCalEvent.Stop.ToEventDateTime();
EventsResource.InsertRequest insertRequest = service.Events.Insert(evntNew, "primary");
insertRequest.Execute();
}
}
}
public static class Extensions
{
public static EventDateTime ToEventDateTime(this DateTime dDateTime)
{
EventDateTime edtDateTime = new EventDateTime();
edtDateTime.DateTime = DateTime.ParseExact(dDateTime.ToString("MM/dd/yyyy HH:mm"), "MM/dd/yyyy HH:mm", null);
return edtDateTime;
}
}
public class CalendarEvent
{
public CalendarEvent() { }
public string Summary { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public DateTime Start { get; set; }
public DateTime Stop { get; set; }
}
// END