How to Send Emails and Reminders for Events in Blazor Scheduler
Tags: blazor, webdev, csharp, dotnet
Published: 2021-02-26 04:04:48

---
title: How to Send Emails and Reminders for Events in Blazor Scheduler
published: true
date: 2021-02-25 11:00:52 UTC
tags: blazor, webdev, csharp, dotnet
canonical_url: https://www.syncfusion.com/blogs/post/how-to-send-emails-and-reminders-for-events-in-blazor-scheduler.aspx
cover_image: https://www.syncfusion.com/blogs/wp-content/uploads/2020/12/How-to-Send-Emails-and-Reminders-for-Events-in-Blazor-Scheduler-672x372.png
---

Our Syncfusion [Blazor Scheduler](https://www.syncfusion.com/blazor-components/blazor-scheduler) is a fully-featured calendar component that helps users manage their time efficiently. It facilitates easy resource scheduling, the rescheduling appointments of through editor pop-ups, drag and drop, and resizing actions.

The Blazor Scheduler also allows you to send emails and reminder notifications to each person involved in a project. In this blog, we will discuss how to configure the email and reminder settings in your Blazor Scheduler application.

Let’s get started!

## Project setup

First, create a simple Scheduler in your Blazor server-side application. Refer to this [Getting Started with Blazor Scheduler Component](https://blazor.syncfusion.com/documentation/scheduler/getting-started/#getting-started) UG documentation for an introduction to configuring the common specifications.

## Configuring email settings

Let’s configure the email setup in the project.

**Step 1:** Create a new folder in the project root directory with the name **_Models_** like in the screenshot.  
 ![Create a new folder in the project root directory with the name Models](https://www.syncfusion.com/blogs/wp-content/uploads/2020/12/Create-a-new-folder-in-the-project-root-directory-with-the-name-Models.png)

**Step 2:** Create a class named **_EventModel_** inside the **_Models_** folder.

```csharp
public class EventModel
{
    public int Id { get; set; }
    public string Subject { get; set; }
    public string Location { get; set; }
    public string Description { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public string StartTimezone { get; set; }
    public string EndTimezone { get; set; }
    public bool? IsAllDay { get; set; }
    public bool? IsBlock { get; set; }
    public bool? IsReadonly { get; set; }
    public int? RecurrenceID { get; set; }
    public int? FollowingID { get; set; }
    public string RecurrenceRule { get; set; }
    public string RecurrenceException { get; set; }
    public int? EmployeeId { get; set; }
}
```

**Step 3:** Then, create a new folder in the project root directory and name it **_EmailServices_**.  
 ![Create a new folder in the project root directory and name it EmailServices](https://www.syncfusion.com/blogs/wp-content/uploads/2020/12/create-a-new-folder-in-the-project-root-directory-and-name-it-EmailServices.png)

**Step 4:** Then, create a new class for **_EmailSettings_** inside the **_EmailServices_** folder. Refer to the following code example.

```csharp
public class EmailSettings
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string DisplayName { get; set; }
    public string Host { get; set; }
    public int Port { get; set; }
}
```

**Step 5:** Create an interface for the **_IEmailService_** inside the **_EmailServices_**.

```csharp
interface IEmailService
{
    Task<string> SendEmailAsync(string ToEmailName, string Subject, EventModel Data);
    Task<string> SendEmailAsync(List<string> ToEmailNames, string Subject, EventModel Data);
    bool IsValidEmail(string EmailName);
}
```

**Step 6:** Now, create the **_EmailService_** class inside the **_EmailServices_** folder and inherit it from the **_IEmailService_** interface.

```sharp
public class EmailService : IEmailService
{
    private readonly EmailSettings _mailConfig;
    private static string _mailResponse;

    public EmailService(EmailSettings mailConfig)
    {
        _mailConfig = mailConfig;
    }

    public async Task<string> SendEmailAsync(string ToEmailName, string Subject, EventModel Data)
    {
        return await SendEmailAsync(new List<string>() { ToEmailName }, Subject, Data);
    }

    public async Task<string> SendEmailAsync(List<string> ToEmailName, string Subject, EventModel Data)
    {
        _mailResponse = string.Empty;

        using (SmtpClient smtpClient = new SmtpClient(_mailConfig.Host, _mailConfig.Port))
        {
            smtpClient.UseDefaultCredentials = true;
            smtpClient.Credentials = new NetworkCredential(_mailConfig.Username, _mailConfig.Password);
            smtpClient.EnableSsl = true;
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpClient.SendCompleted += new SendCompletedEventHandler((object sender, AsyncCompletedEventArgs e) => {
                    _mailResponse = (e.Error != null || e.Cancelled != false) ? "failure" : "success";
                });

            MailMessage message = new MailMessage
            {
                From = new MailAddress(_mailConfig.Username, _mailConfig.DisplayName),
                Subject = Subject,
                SubjectEncoding = Encoding.UTF8,
                BodyEncoding = Encoding.UTF8,
                HeadersEncoding = Encoding.UTF8,
                IsBodyHtml = true,
                Body = GetEmailContent(Subject, Data),
                Priority = MailPriority.High
            };
            foreach (string EmailName in ToEmailName)
            {
                message.To.Add(new MailAddress(EmailName));
            }

            await smtpClient.SendMailAsync(message);
        }

        return _mailResponse;
    }

    public bool IsValidEmail(string EmailName)
    {
        return new EmailAddressAttribute().IsValid(EmailName);
    }

    private string GetEmailContent(string Title, EventModel Data)
    {
        string HTMLBody = string.Empty;

            using (FileStream fs = File.Open(Directory.GetCurrentDirectory() + "/Email_Template.html", FileMode.Open, FileAccess.ReadWrite))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    HTMLBody = sr.ReadToEnd();
                }
            }

            HTMLBody = HTMLBody.Replace("###EMAILTITLE###", Title);
            HTMLBody = HTMLBody.Replace("###EVENTSUBJECT###", Data.Subject ?? "(No Title)");
            HTMLBody = HTMLBody.Replace("###EVENTSTART###", Data.StartTime.ToString());
            HTMLBody = HTMLBody.Replace("###EVENTEND###", Data.EndTime.ToString());
            HTMLBody = HTMLBody.Replace("###EVENTLOCATION###", Data.Location ?? "NA");
            HTMLBody = HTMLBody.Replace("###EVENTDETAILS###", Data.Description ?? "NA");
            HTMLBody = HTMLBody.Replace("###CURRENTYEAR###", DateTime.Now.Year.ToString());

            return HTMLBody;
    }
}
```

**Note:** We can also create our own email template in the project root directory under the name **_Email\_Template.html_**.

**Step 7:** In the _appsettings.json_ file, define the email settings-related credentials.

```csharp
"EmailSettings": {
    "DisplayName": "Syncfusion Scheduler",
    "Username": "xxxxxxxxxxxxxxx@outlook.com",
    "Password": "xxxxxxxxxx",
    "Port": 587,
    "Host": "smtp.office365.com"
}
```

**Note:** In the previous settings, the _Port_ number and the _Host_name will vary based on the email domain.

**Step 8:** In the _Startup.cs_ file, add our **_EmailService_** in the **_ConfigureService_** method.

```csharp
public void ConfigureServices(IServiceCollection services)
{
  . . . . . . . . . . . . . 
  . . . . . . . . . . . . .
  services.AddSingleton(Configuration.GetSection("EmailSettings").Get<EmailSettings>());
  services.AddScoped<IEmailService, EmailService>();
}
```

Now, your project has been successfully configured with the EmailService.

**Step 9:** Then, in the _Index.razor_ file, inject the email service like in the following code.

```js
@inject EmailScheduler.EmailServices.IEmailService EmailService
```

Now, use this service to send emails to the appropriate person when an event CRUD action happens.

Here is the code to send the email to a person when a new event is scheduled to them in the Scheduler.

```js
@page "/"
@inject EmailScheduler.EmailServices.IEmailService EmailService

@using EmailScheduler.Models
@using Syncfusion.Blazor.Schedule

<div class="control-container">
    <div class="schedule-control">
        <SfSchedule @ref="ScheduleRef" TValue="EventModel" Height="500px">
            <ScheduleGroup EnableCompactView="false" Resources="@GroupData"></ScheduleGroup>
            <ScheduleResources>
                <ScheduleResource TItem="ResourceModel" TValue="int[]" DataSource="@ResourceData" Field="EmployeeId" Title="Employee Name" Name="Employees" TextField="EmployeeName" IdField="EmployeeId" ColorField="EmployeeColor" AllowMultiple="true"></ScheduleResource>
            </ScheduleResources>
            <ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
            <ScheduleEvents TValue="EventModel" ActionCompleted="OnActionCompleted"></ScheduleEvents>
        </SfSchedule>
    </div>
</div>

@code{
    SfSchedule<EventModel> ScheduleRef;

    private class ResourceModel
    {
        public string EmployeeName { get; set; }
        public int EmployeeId { get; set; }
        public string EmployeeColor { get; set; }
        public string EmployeeEmail { get; set; }
    }

    private string[] GroupData { get; set; } = new string[] { "Employees" };
    private List<ResourceModel> ResourceData { get; set; } = new List<ResourceModel> {
        new ResourceModel { EmployeeId = 1, EmployeeName = "Employee 1", EmployeeColor = "#EA7A57", EmployeeEmail = "xxxxxxxxxxxxxxx@outlook.com" },
        new ResourceModel { EmployeeId = 2, EmployeeName = "Employee 2", EmployeeColor = "#357cd2", EmployeeEmail = "xxxxxxxxxxxxxxx@gmail.com" },
        new ResourceModel { EmployeeId = 3, EmployeeName = "Employee 3", EmployeeColor = "#7fa900", EmployeeEmail = "xxxxxxxxxxxxxxx@yahoo.com" }
    };
    private List<EventModel> DataSource = GenerateEvents();

    private static List<EventModel> GenerateEvents()
    {
        DateTime date1 = DateTime.Now;
        DateTime startDate = new DateTime(date1.Year, date1.Month, date1.Day, date1.Hour, date1.Minute, 0).AddMinutes(6);
        DateTime endDate = new DateTime(startDate.Ticks).AddHours(2);
        List<EventModel> collections = new List<EventModel>() {
            new EventModel { Id = 1, Subject = "Testing", StartTime = startDate, EndTime = endDate, EmployeeId = 1 },
            new EventModel { Id = 2, Subject = "Meeting", StartTime = startDate, EndTime = endDate, EmployeeId = 2 },
            new EventModel { Id = 3, Subject = "Conference", StartTime = startDate, EndTime = endDate, EmployeeId = 3 }
        };
        return collections;
    }

    private async void OnActionCompleted(ActionEventArgs<EventModel> args)
    {
        if (args.ActionType == ActionType.EventCreate || args.ActionType == ActionType.EventChange || args.ActionType == ActionType.EventRemove)
        {
            List<EventModel> added = args.AddedRecords ?? new List<EventModel>();
            List<EventModel> changed = args.ChangedRecords ?? new List<EventModel>();
            List<EventModel> deleted = args.DeletedRecords ?? new List<EventModel>();
            List<EventModel> datas = added.Concat(changed).Concat(deleted).ToList();
            List<string> toEmail = new List<string>();
            foreach (EventModel data in datas)
            {
                string email = ResourceData.Where(e => e.EmployeeId == data.EmployeeId).FirstOrDefault().EmployeeEmail;
                if (EmailService.IsValidEmail(email))
                {
                    toEmail.Add(email);
                }
            }
            toEmail = toEmail.Distinct().ToList();
            string Title = string.Empty;
            switch (args.ActionType)
            {
                case ActionType.EventCreate:
                    Title = "New Event Scheduled";
                    break;
                case ActionType.EventChange:
                    Title = "Scheduled Event Updated";
                    break;
                case ActionType.EventRemove:
                    Title = "Scheduled Event Removed";
                    break;
            }
            await EmailService.SendEmailAsync(toEmail, Title, datas[0]);
        }
    }

}
```

Now, the email will be sent successfully to the person scheduled for the event.

## **Configuring reminder settings**

Reminder settings are used to display notifications before an event begins. We can set different intervals between notifications and events’ beginning times.

Using the Syncfusion Blazor [Toast component](https://www.syncfusion.com/blazor-components/blazor-toast), we can display the event reminders. The complete code of reminder settings is as follows.

```js
@page "/"

@using EmailScheduler.Models
@using Syncfusion.Blazor.Notifications
@using Syncfusion.Blazor.Schedule
@using System.Timers

<div class="control-container">
    <div class="toast-control">
        <SfToast @ref="ToastRef" CssClass="e-schedule-reminder e-toast-info" NewestOnTop="true" ShowCloseButton="true" Target=".e-schedule" Timeout="10000">
            <ToastAnimationSettings>
                <ToastShowAnimationSettings Effect="ToastEffect.SlideRightIn"></ToastShowAnimationSettings>
                <ToastHideAnimationSettings Effect="ToastEffect.SlideRightOut"></ToastHideAnimationSettings>
            </ToastAnimationSettings>
            <ToastPosition X="Right" Y="Top"></ToastPosition>
            <ToastTemplates>
                <Template>
                    <div class="e-toast-template e-toast-info">
                        <div class="e-custom-toast">
                            <div class="e-toast-icon e-icons e-schedule-meeting-icon"></div>
                            <div class="e-avatar e-avatar-xsmall e-avatar-circle e-toast-avatar">
                                <img class="image" src="/images/status/@(EventData.EmployeeId).png" alt="avatar" />
                            </div>
                        </div>
                        <div class="e-toast-message">
                            <div class="e-toast-title">@EventData.Subject</div>
                            <div class="e-toast-content">@(EventData.StartTime.ToShortTimeString() + " - " + EventData.EndTime.ToShortTimeString())</div>
                        </div>
                    </div>
                </Template>
            </ToastTemplates>
            <ToastEvents Created="OnToastCreated"></ToastEvents>
        </SfToast>
    </div>
    <div class="schedule-control">
        <SfSchedule @ref="ScheduleRef" TValue="EventModel" Height="500px">
            <ScheduleGroup EnableCompactView="false" Resources="@GroupData"></ScheduleGroup>
            <ScheduleResources>
                <ScheduleResource TItem="ResourceModel" TValue="int[]" DataSource="@ResourceData" Field="EmployeeId" Title="Employee Name" Name="Employees" TextField="EmployeeName" IdField="EmployeeId" ColorField="EmployeeColor" AllowMultiple="true"></ScheduleResource>
            </ScheduleResources>
            <ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
        </SfSchedule>
    </div>
</div>

<style>
    .e-toast .e-schedule-reminder .e-toast-template {
        display: flex;
    }

    .e-toast .e-schedule-reminder .e-custom-toast {
        display: inline-grid;
    }

    .e-toast .e-schedule-reminder .e-schedule-meeting-icon::before {
        content: "\e763";
        font-size: 20px;
    }

    .e-toast .e-schedule-reminder .e-toast-avatar {
        margin-top: 14px;
    }
</style>

@code{
    SfToast ToastRef;
    SfSchedule<EventModel> ScheduleRef;

    private class ResourceModel
    {
        public string EmployeeName { get; set; }
        public int EmployeeId { get; set; }
        public string EmployeeColor { get; set; }
        public string EmployeeEmail { get; set; }
    }

    private EventModel EventData { get; set; }
    private string[] GroupData { get; set; } = new string[] { "Employees" };
    private List<ResourceModel> ResourceData { get; set; } = new List<ResourceModel> {
        new ResourceModel { EmployeeId = 1, EmployeeName = "Employee 1", EmployeeColor = "#EA7A57", EmployeeEmail = "xxxxxxxxxxxxxxx@outlook.com" },
        new ResourceModel { EmployeeId = 2, EmployeeName = "Employee 2", EmployeeColor = "#357cd2", EmployeeEmail = "xxxxxxxxxxxxxxx@gmail.com" },
        new ResourceModel { EmployeeId = 3, EmployeeName = "Employee 3", EmployeeColor = "#7fa900", EmployeeEmail = "xxxxxxxxxxxxxxx@yahoo.com" }
    };
    private List<EventModel> DataSource = GenerateEvents();

    private void OnToastCreated()
    {
        Timer timer = new Timer(60000);
        timer.Elapsed += new ElapsedEventHandler(async (object sender, ElapsedEventArgs e) =>
        {
            List<EventModel> eventDatas = ScheduleRef.GetCurrentViewEvents();
            int AlertBeforeMinutes = 5;
            DateTime CurrentTime = DateFormat(DateTime.Now);
            foreach (EventModel eventData in eventDatas)
            {
                DateTime StartTime = DateFormat(eventData.StartTime);
                if (DateTime.Compare(CurrentTime, StartTime.AddMinutes(-AlertBeforeMinutes)) == 0)
                {
                    EventData = eventData;
                    await InvokeAsync(async () => await ToastRef.Show());
                }
            }
        });
        timer.Enabled = true;
    }

    private DateTime DateFormat(DateTime date)
    {
        return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, 0);
    }

    private static List<EventModel> GenerateEvents()
    {
        DateTime date1 = DateTime.Now;
        DateTime startDate = new DateTime(date1.Year, date1.Month, date1.Day, date1.Hour, date1.Minute, 0).AddMinutes(6);
        DateTime endDate = new DateTime(startDate.Ticks).AddHours(2);
        List<EventModel> collections = new List<EventModel>() {
            new EventModel { Id = 1, Subject = "Testing", StartTime = startDate, EndTime = endDate, EmployeeId = 1 },
            new EventModel { Id = 2, Subject = "Meeting", StartTime = startDate, EndTime = endDate, EmployeeId = 2 },
            new EventModel { Id = 3, Subject = "Conference", StartTime = startDate, EndTime = endDate, EmployeeId = 3 },
        };
        return collections;
    }

}
```

Now, the reminder notification will be displayed to the appropriate person 5 minutes before the event begins.

## GitHub reference

You can check out the complete working example of this Blazor server application on [this GitHub repository](https://github.com/SyncfusionExamples/email-and-remainder-notification-from-blazor-scheduler).

## Summary

This blog explained in detail how to configure email service and reminder settings in the [Syncfusion Blazor Scheduler](https://www.syncfusion.com/blazor-components/blazor-scheduler). With this, each and every person involved in a project will be informed of the events assigned to them and also get reminder notifications about their tasks. This will enhance their productivity.

So, try these features out and leave your feedback in the comments section below.

[Syncfusion Essential Studio for Blazor](https://www.syncfusion.com/blazor-components) offers 65+ high-performance, lightweight, and responsive UI components for the web, including file-format libraries, in a single package. Please take a look at our live demos in our [sample browser](https://blazor.syncfusion.com/) for a hands-on experience.

For existing customers, the latest version is available for download from the [License and Downloads](https://www.syncfusion.com/account/downloads) page. If you are not yet a Syncfusion customer, you can try our 30-day [free trial](https://www.syncfusion.com/downloads) to check out the available features. You can also try our samples from this [GitHub](https://github.com/syncfusion) location.

If you have questions, you can contact us through our [support forums](https://www.syncfusion.com/forums), [Direct-Trac](https://www.syncfusion.com/support/directtrac/incidents), or [feedback portal](https://www.syncfusion.com/feedback/blazor-components). We are always happy to assist you!

If you like this post, we think you will also like the following:

- [How to Access Microsoft Graph Calendar Events with Syncfusion Blazor Scheduler [Blog]](https://dev.to/karthickramasamy08/how-to-access-microsoft-graph-calendar-events-with-syncfusion-blazor-scheduler-gmo-temp-slug-5642119)
- [Blazor [E-book]](https://www.syncfusion.com/ebooks/blazor-succinctly)