
Posted on • Edited on • Originally published atMedium
🧑💻AI Calendar🗓️Agent in 7 minutes! 🔥
Hi Buddy! Welcome to a quick tutorial on building an AI Calendar agent that will allow you to create calendar events using Semantic Kernel, Google Calendar APIs & Open API (model GPT 4o).
This will be a quick tutorial aimed to be max of 7mins for you to quickly create an AI Agent.
This tutorial uses three major tools.
- Semantic Kernel (Chat completion & Function plugins)
- Google Workspace (Google Calendar APIs)
- Open AI Account (with paid or trail use)
So, without wasting anymore time lets dive into the rest of the steps.
Prerequisites:
- Create anOpen AI Account.
- Create aprojectin Open AI Account.
- Add a token amount if you are choosing the paid version in the billing section.
- Create newGoogle Workspace Project.
- Enable Google Workspace APIs | Google for Developers
- We are going to use Service to Service Authentication flow for this AI Agent as it will be a console application. So, create a service account.
- Once Service account is created, add keys as shown below. Choose JSON as the option. This will download a JSON key into your machine. Name it as
apikey.json
. Which we will be using later in our agent building process.
- Download Visual Studio and .NET 9 framework through thislink.
Step by Step Project setup:
- Create new Console Application using
.NET9
. - Install below necessary packages.
dotnetaddpackageMicrosoft.SemanticKerneldotnetaddpackageMicrosoft.Extensions.LoggingdotnetaddpackageMicrosoft.Extensions.Logging.ConsoledotnetaddMicrosoft.Extensions.Configuration.FileExtensionsdotnetaddMicrosoft.Extensions.Configuration.JsondotnetaddMicrosoft.Extensions.Configuration.UserSecretsdotnetaddMicrosoft.Extensions.Configuration.CommandLinedotnetaddMicrosoft.Extensions.Configuration.EnvironmentVariablesdotnetaddGoogle.Apis.Calendar.v3dotnetaddGoogle.Apis.Auth
- Add
appsettings.json
file to the project directory and add below code to thecsproj
project file.
<ItemGroup><NoneUpdate="appsettings.json"><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory></None></ItemGroup>
- Add the downloaded
apikey.json
into the project folder. - Create a new
CalendarService.cs
class underServices
folder.
usingAICalendarAgent.Configurations;usingGoogle.Apis.Auth.OAuth2;usingGoogle.Apis.Calendar.v3.Data;usingMicrosoft.Extensions.Options;namespaceAICalendarAgent.Services;publicinterfaceICalendarService{TaskCreateEventAsync(stringtitle,stringdescription,DateTimeOffsetstartTime,DateTimeOffsetendTime);Task<List<CalendarListEntry>>GetMyCalendarList();}publicclassCalendarService(IOptions<GoogleCalendarAPISettings>options,ILogger<CalendarService>logger):ICalendarService{publicasyncTask<List<CalendarListEntry>>GetMyCalendarList(){// Google credential for getting service account tokensvargoogleCredential=GetGoogleCredential();varservice=newGoogle.Apis.Calendar.v3.CalendarService(newGoogle.Apis.Services.BaseClientService.Initializer{HttpClientInitializer=googleCredential,ApplicationName=options.Value.ApplicationName,});varrequest=service.CalendarList.List();varcalendarList=awaitrequest.ExecuteAsync();return[..calendarList.Items];}publicasyncTaskCreateEventAsync(stringtitle,stringdescription,DateTimeOffsetstartTime,DateTimeOffsetendTime){// Google credential for getting service account tokensvargoogleCredential=GetGoogleCredential();// authentication flow for the google calendar using user auth token// var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(// new ClientSecrets// {// ClientId = options.Value.ClientId,// ClientSecret = options.Value.ClientSecret,// },// options.Value.Scopes,// options.Value.User,// CancellationToken.None// );varservice=newGoogle.Apis.Calendar.v3.CalendarService(newGoogle.Apis.Services.BaseClientService.Initializer{HttpClientInitializer=googleCredential,ApplicationName=options.Value.ApplicationName,});varnewEvent=newEvent{Summary=title,Description=description,Start=newEventDateTime{DateTimeDateTimeOffset=startTime,TimeZone="America/Los_Angeles",},End=newEventDateTime{DateTimeDateTimeOffset=endTime,TimeZone="America/Los_Angeles",},};// Create an event in the calendarvarrequest=service.Events.Insert(newEvent,options.Value.CalendarId);varcreatedEvent=awaitrequest.ExecuteAsync();logger.LogInformation($"Event created:{title} -{description} -{startTime} -{endTime} -{createdEvent.HtmlLink}");}// common code to create Google credential for service accountprotectedGoogleCredentialGetGoogleCredential(){GoogleCredentialgoogleCredential;usingvarstream=newFileStream(Path.Combine(Directory.GetCurrentDirectory(),"apikey.json"),FileMode.Open,FileAccess.Read);googleCredential=GoogleCredential.FromStream(stream).CreateScoped(options.Value.Scopes);returngoogleCredential;}}
- Add a new class called
Brain.cs
to folderBrain
. Then add below code.
usingAICalendarAgent.Configurations;usingMicrosoft.Extensions.Options;namespaceAICalendarAgent.Brain;publicinterfaceIBrain{TaskRun(Kernelkernel);}publicclassBrain(IServiceProviderserviceProvider,ILogger<Brain>logger):IBrain{publicasyncTaskRun(Kernelkernel){varchatCompletionService=serviceProvider.GetRequiredService<IChatCompletionService>();OpenAIPromptExecutionSettingsopenAIPromptExecutionSettings=new(){FunctionChoiceBehavior=FunctionChoiceBehavior.Auto(),};varhistory=newChatHistory();history.AddUserMessage("Can you add an event in my Google Calendar with the title 'Meeting with John' "+"starting at 3 PM and ending at 4 PM EST on March 14th 2025?");varresult=awaitchatCompletionService.GetChatMessageContentAsync(history,executionSettings:openAIPromptExecutionSettings,kernel:kernel);logger.LogInformation("AI Response: {Response}",result.Content??"No response");history.AddMessage(result.Role,result.Content??"No response");}}
- Add a new Function Plugin
CalendarPlugin.cs
underBrain/Plugins/FunctionPlugins
folder with below code.
usingSystem.ComponentModel;usingAICalendarAgent.Services;usingGoogle.Apis.Calendar.v3.Data;namespaceAICalendarAgent.Brain.Plugins.FunctionPlugins;publicclassCalendarPlugin(ICalendarServicecalendarService){privatereadonlyICalendarService_calendarService=calendarService;[KernelFunction("create_google_calendar_event")][Description("Create an event in the Google Calendar.")]publicasyncTaskCreateGoogleCalendarEvent(stringtitle,stringdescription,DateTimeOffsetstartTime,DateTimeOffsetendTime){await_calendarService.CreateEventAsync(title,description,startTime,endTime);}[KernelFunction("get_my_calendar_list")][Description("Get the list of calendars.")]publicasyncTask<List<CalendarListEntry>>GetMyCalendarList(){returnawait_calendarService.GetMyCalendarList();}}
- Now, let's setup configuration classes
GoogleCalendarAPISettings.cs
&OpenAIConfiguration.cs
with below code to hold strongly typed configuration values for two important APIs.
namespaceAICalendarAgent.Configurations;publicclassOpenAIConfiguration{publicconststringSectionName="OpenAIConfiguration";publicstringApiKey{get;set;}=string.Empty;publicstringModelId{get;set;}=string.Empty;publicstringEndpoint{get;set;}=string.Empty;}namespaceAICalendarAgent.Configurations;publicclassGoogleCalendarAPISettings{publicconststringSectionName="GoogleCalendarAPISettings";publicstringClientId{get;set;}=string.Empty;publicstringClientSecret{get;set;}=string.Empty;publicstring[]Scopes{get;set;}=[];publicstringRedirectUri{get;set;}=string.Empty;publicstringCalendarId{get;set;}=string.Empty;publicstringApplicationName{get;set;}=string.Empty;publicstringUser{get;set;}=string.Empty;publicstring[]Attendees{get;set;}=[];}-Now,let’sinjectourservices,plugins,settingsandourrunningcodeto`program.cs`usingAICalendarAgent.Brain;usingAICalendarAgent.Brain.Filters;usingAICalendarAgent.Brain.Plugins.FunctionPlugins;usingAICalendarAgent.Configurations;usingAICalendarAgent.Services;varconfiguration=newConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json",optional:false,reloadOnChange:true).AddEnvironmentVariables().AddUserSecrets<Program>().AddCommandLine(args).Build();varbuilder=Kernel.CreateBuilder();builder.Services.AddLogging(configure=>configure.AddConsole().SetMinimumLevel(LogLevel.Trace));builder.Services.AddSingleton<IConfiguration>(configuration);builder.Services.AddOptions();builder.Services.Configure<OpenAIConfiguration>(configuration.GetSection(OpenAIConfiguration.SectionName));builder.Services.Configure<GoogleCalendarAPISettings>(configuration.GetSection(GoogleCalendarAPISettings.SectionName));builder.Services.AddScoped<ICalendarService,CalendarService>();builder.Services.AddTransient<IBrain,Brain>();varopenAIConfiguration=configuration.GetSection(OpenAIConfiguration.SectionName).Get<OpenAIConfiguration>()??thrownewException("OpenAI configuration is missing");vargoogleCalendarSettings=configuration.GetSection(GoogleCalendarAPISettings.SectionName).Get<GoogleCalendarAPISettings>()??thrownewException("GoogleCalendarAPISettings configuration is missing");// var azureOpenAIConfiguration =// configuration.GetSection(AzureOpenAIConfiguration.SectionName).Get<AzureOpenAIConfiguration>()// ?? throw new Exception("Azure OpenAI configuration is missing");// below is for the azure openai chat completion// builder.AddAzureOpenAIChatCompletion(// azureOpenAIConfiguration.ModelId,// azureOpenAIConfiguration.Endpoint,// azureOpenAIConfiguration.ApiKey// );builder.AddOpenAIChatCompletion(openAIConfiguration.ModelId,openAIConfiguration.ApiKey);varkernel=builder.Build();kernel.ImportPluginFromType<CalendarPlugin>();// Add CalendarPlugin to the kernel. Use ImportPluginFromType instead of AddPluginFromType if you have services to be injected.varlogger=kernel.GetRequiredService<ILogger<Program>>();logger.LogInformation("Starting the AI Calendar Agent");awaitkernel.GetRequiredService<IBrain>().Run(kernel);
- Let’s setup our
appsettings.json
file with below information
{"Logging":{"LogLevel":{"Default":"Information","Microsoft":"Warning","Microsoft.Hosting.Lifetime":"Information"}},"OpenAIConfiguration":{"ModelId":"gpt-4o","ApiKey":"[YourKey]"},"AzureOpenAIConfiguration":{"ModelId":"gpt-4o","ApiKey":"[YourKey]","Endpoint":"[YourEndpoint]"},"GoogleCalendarAPISettings":{"ClientId":"YourClientId",//onlyifyouareusinguseroauthflow"ClientSecret":"YouClientSecret",//onlyifyouareusinguseroauthflow"Scopes":["https://www.googleapis.com/auth/calendar.readonly","https://www.googleapis.com/auth/calendar.events.readonly","https://www.googleapis.com/auth/calendar.events","https://www.googleapis.com/auth/calendar"],"ApplicationName":"AICalendarAgent","RedirectUri":"http://localhost:5000/signin-google",//onlyifyouareusinguseroauthflow"CalendarId":"[YourPersonalCalendarId]",//youpersonalcalendarIDsharedwithyourserviceaccount"User":"user",//onlyifyouareusinguseroauthflow}}
- Let’s share your personal calendar with calendar Id mentioned above in
appsettings.json
file to your service account email fromapikey.json
file downloaded as part of step 7 of prerequisites.
- Now, let's run the code using dotnet run & you will see the below output as well as a new event should be created on your calendar. The one you shared with the service account.
Concepts Showcased:
- OAuth client credential flow with Google Calendar API.
- Function Plugins & Auto Function Invocation from semantic kernel.
- Chat completion with GPT 4o + semantic kernel.
- .NET Dependency Injection.
- .NET Options Pattern.
- Natural Language Processing & Natural Language Understanding.
- Process automation
Conclusion:
Using powerful sematic kernel, we can easily create NLP based AI Agents on fly with few simple steps and configurations. These agents are powerful to automate redundant tasks by connecting to your environment, existing code, existing APIs together.
To get access to my source code. Please visit thisGitHub link. Hope this tutorial can help you get started to build your own AI Agent.
To get more tutorials🧾 like this! Follow me! see ya 👋!
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse