Managing Outlook Calendar Items
This article covers Outlook MapiCalendar calendar items saved as MSG. To work with standards-based iCalendar (ICS) appointments and meeting requests, see Manage Appointments; to store and read calendar items inside a PST, see Managing Calendar Items in PST Files.
Aspose.Email MapiCalendar class provides methods and attributes to set various properties of a calendar item. This section provides code samples for:
- Create and Save Calendar Items
- Save Calendar Items as MSG Files
- Save Product IDs for MAPI Calendar Items to ICS
- Get Total Number of Events
- Add Display Reminders
- Add Audio Reminders
- Add/Retrieve Attachments from Calendar Files
- Check Recipients’ Status in Meeting Requests
- Create MAPI Calendar TimeZone from Standard Timezone
- Set Reminders for Appointments
- Convert Appointment EML to MSG with HTML Body
- Set the State of MAPI Calendar Items Manually
Create and Save Calendar Items
The following code snippet shows you how to create and save a calendar item in ICS format.
// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Outlook();
// Create the appointment
MapiCalendar calendar = new MapiCalendar(
"LAKE ARGYLE WA 6743",
"Appointment",
"This is a very important meeting :)",
new DateTime(2012, 10, 2, 13, 0, 0),
new DateTime(2012, 10, 2, 14, 0, 0));
calendar.Save(dataDir + "CalendarItem_out.ics", AppointmentSaveFormat.Ics);
Save Calendar Items as MSG Files
The following code snippet shows you how to save the calendar item as MSG.
calendar.Save(dataDir + "CalendarItemAsMSG_out.Msg", AppointmentSaveFormat.Msg);
Save Product IDs for MAPI Calendar Items to ICS
The ProductIdentifier property of the MapiCalendarIcsSaveOptions class is used to save a MAPI calendar item to an iCalendar (ICS) file preserving original date and time information as well as a custom product identifier. The property specifies the identifier for the product that created the iCalendar object.
The following code sample shows how to work with iCalendar (ICS) data within a MAPI calendar object:
var icsSaveOptions = new MapiCalendarIcsSaveOptions
{
KeepOriginalDateTimeStamp = true,
ProductIdentifier = "Foo Ltd"
};
mapiCalendar.Save("my.ics", icsSaveOptions);
Get Total Number of Events
The CalendarReader class enables handling calendar events effortlessly. The following properties and a method allow you to work with multiple events:
- CalendarReader.Count - The Count property of the CalendarReader class allows you to retrieve the number of Vevent components (events) present in the calendar, making it easier to track the total number of events.
- CalendarReader.IsMultiEvents - This property determines whether the calendar contains multiple events. It provides a boolean value indicating whether the calendar contains more than one event, aiding in identifying calendars with single or multiple events.
- CalendarReader.Method - The Method property obtains the iCalendar method type associated with the calendar object. It returns the method type, such as “REQUEST,” “PUBLISH,” or “CANCEL,” providing valuable insights into the purpose of the calendar.
- CalendarReader.Version - Gets the Version of iCalendar.
- CalendarReader.LoadAsMultiple() This method enables the loading of a list of events from a calendar containing multiple events. It returns a list of Appointment objects, allowing easy access and processing of each event individually.
The following code example demonstrates how you can implement these capabilities in your project:
var reader = new CalendarReader(fileName);
Console.WriteLine("Calendar contains " + reader.Count + " events");
Console.WriteLine("The Version of the calendar is " + reader.Version);
Console.WriteLine("The Method of the calendar is " + reader.Method);
Console.WriteLine("Does the calendar contain multiple events? - " + reader.IsMultiEvents);
List<Appointment> appointments = reader.LoadAsMultiple();
Add Display Reminders
The following code snippet shows you how to add a display reminder to a calendar.
// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Outlook();
// Create Appointment
Appointment app = new Appointment("Home", DateTime.Now.AddHours(1), DateTime.Now.AddHours(1), "organizer@domain.com", "attendee@gmail.com");
MailMessage msg = new MailMessage();
msg.AddAlternateView(app.RequestApointment());
MapiMessage mapi = MapiMessage.FromMailMessage(msg);
MapiCalendar calendar = (MapiCalendar)mapi.ToMapiMessageItem();
// Set calendar Properties
calendar.ReminderSet= true;
calendar.ReminderDelta = 45;//45 min before start of event
string savedFile = (dataDir + "calendarWithDisplayReminder.ics");
calendar.Save(savedFile, AppointmentSaveFormat.Ics);
Add Audio Reminders
The following code snippet shows you how to add an audio reminder to a calendar.
// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Outlook();
Appointment app = new Appointment("Home", DateTime.Now.AddHours(1), DateTime.Now.AddHours(1), "organizer@domain.com", "attendee@gmail.com");
MailMessage msg = new MailMessage();
msg.AddAlternateView(app.RequestApointment());
MapiMessage mapi = MapiMessage.FromMailMessage(msg);
MapiCalendar calendar = (MapiCalendar)mapi.ToMapiMessageItem();
// Set calendar properties
calendar.ReminderSet = true;
calendar.ReminderDelta = 58;//58 min before start of event
calendar.ReminderFileParameter = dataDir + "Alarm01.wav";
string savedFile = (dataDir + "calendarWithAudioReminder_out.ics");
calendar.Save(savedFile, AppointmentSaveFormat.Ics);
Add/Retrieve Attachments from Calendar Files
The following code snippet shows you how to add/retrieve attachments from calendar files.
string[] files = new string[3];
files[0] = dataDir + "attachment_1.doc";
files[1] = dataDir + "download.png";
files[2] = dataDir + "Desert.jpg";
Appointment app1 = new Appointment("Home", DateTime.Now.AddHours(1), DateTime.Now.AddHours(1), "organizer@domain.com", "attendee@gmail.com");
foreach (string file in files)
{
using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(file)))
{
app1.Attachments.Add(new Attachment(ms, Path.GetFileName(file)));
}
}
app1.Save(dataDir + "appWithAttachments_out.ics", AppointmentSaveFormat.Ics);
Appointment app2 = Appointment.Load(dataDir + "appWithAttachments_out.ics");
Console.WriteLine(app2.Attachments.Count);
foreach (Attachment att in app2.Attachments)
Console.WriteLine(att.Name);
Check Recipients’ Status in Meeting Requests
The following code snippet shows you how to show the status of recipients from a meeting request.
MapiMessage message = MapiMessage.FromFile(fileName);
foreach (MapiRecipient recipient in message.Recipients)
{
Console.WriteLine(recipient.RecipientTrackStatus);
}
Create MAPI Calendar TimeZone from Standard Timezone
The following code snippet shows you how to Create MapiCalendarTimeZone from standard Timezone.
MapiCalendarTimeZone timeZone = new MapiCalendarTimeZone(TimeZoneInfo.Local);
Set Reminders for Appointments
A reminder can be added when an appointment is created. These alarms can trigger based on different criteria like n minutes before the schedule starts, repeat n times at n intervals. Different tags can be used to create these triggers in the script enclosed by BEGIN:VALARM and END:VALARM within an appointment. There is a number of variants in which the reminder can be set on an appointment.
Add Tags to Set Reminders
The following code snippet shows you how to set a reminder by adding tags.
// The path to the File directory.
string dataDir = RunExamples.GetDataDir_Outlook();
string location = "Meeting Location: Room 5";
DateTime startDate = new DateTime(1997, 3, 18, 18, 30, 00),
endDate = new DateTime(1997, 3, 18, 19, 30, 00);
MailAddress organizer = new MailAddress("aaa@amail.com", "Organizer");
MailAddressCollection attendees = new MailAddressCollection();
attendees.Add(new MailAddress("bbb@bmail.com", "First attendee"));
Appointment target = new Appointment(location, startDate, endDate, organizer, attendees);
// Audio alarm that will sound at a precise time and
// Repeat 4 more times at 15 minute intervals:
AppointmentReminder audioReminder = new AppointmentReminder();
audioReminder.Trigger = new ReminderTrigger(new DateTime(1997, 3, 17, 13, 30, 0, DateTimeKind.Utc));
audioReminder.Repeat = 4;
audioReminder.Duration = new ReminderDuration(new TimeSpan(0, 15, 0));
audioReminder.Action = ReminderAction.Audio;
ReminderAttachment attach = new ReminderAttachment(new Uri("ftp://Host.com/pub/sounds/bell-01.aud"));
audioReminder.Attachments.Add(attach);
target.Reminders.Add(audioReminder);
// Display alarm that will trigger 30 minutes before the
// Scheduled start of the event it is
// Associated with and will repeat 2 more times at 15 minute intervals:
AppointmentReminder displayReminder = new AppointmentReminder();
ReminderDuration dur = new ReminderDuration(new TimeSpan(0, -30, 0));
displayReminder.Trigger = new ReminderTrigger(dur, ReminderRelated.Start);
displayReminder.Repeat = 2;
displayReminder.Duration = new ReminderDuration(new TimeSpan(0, 15, 0));
displayReminder.Action = ReminderAction.Display;
displayReminder.Description = "Breakfast meeting with executive team at 8:30 AM EST";
target.Reminders.Add(displayReminder);
// Email alarm that will trigger 2 days before the
// Scheduled due date/time. It does not
// Repeat. The email has a subject, body and attachment link.
AppointmentReminder emailReminder = new AppointmentReminder();
ReminderDuration dur1 = new ReminderDuration(new TimeSpan(-2, 0, 0, 0));
emailReminder.Trigger = new ReminderTrigger(dur1, ReminderRelated.Start);
ReminderAttendee attendee = new ReminderAttendee("john_doe@host.com");
emailReminder.Attendees.Add(attendee);
emailReminder.Action = ReminderAction.Email;
emailReminder.Summary = "REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING";
emailReminder.Description = @"A draft agenda needs to be sent out to the attendees to the weekly managers meeting (MGR-LIST). Attached is a pointer the document template for the agenda file.";
ReminderAttachment attach1 = new ReminderAttachment(new Uri("http://Host.com/templates/agenda.doc"));
emailReminder.Attachments.Add(attach1);
target.Reminders.Add(emailReminder);
// Procedural alarm that will trigger at a precise date/time
// And will repeat 23 more times at one hour intervals. The alarm will
// Invoke a procedure file.
AppointmentReminder procReminder = new AppointmentReminder();
procReminder.Trigger = new ReminderTrigger(new DateTime(1998, 1, 1, 5, 0, 0, DateTimeKind.Utc));
procReminder.Repeat = 23;
procReminder.Duration = new ReminderDuration(new TimeSpan(1, 0, 0));
procReminder.Action = ReminderAction.Procedure;
ReminderAttachment attach2 = new ReminderAttachment(new Uri("ftp://Host.com/novo-procs/felizano.exe"));
procReminder.Attachments.Add(attach2);
target.Reminders.Add(procReminder);
target.Save(dataDir + "savedFile_out.ics");
Convert Appointment EML to MSG with HTML Body
Since version 19.3, Aspose.Email provides the ability to convert Appointment EML to MSG while retaining the HTML body of the appointment. Aspose.Email provides a MapiConversionOptions.ForcedRtfBodyForAppointment property which has a default value of true. When the value of MapiConversionOptions.ForcedRtfBodyForAppointment is set to true, the appointment body is converted to RTF format. To keep the appointment body format in HTML format, set the value of MapiConversionOptions.ForcedRtfBodyForAppointment to false.
The following example demonstrates the use of MapiConversionOptions.ForcedRtfBodyForAppointment property to keep the appointment body format in HTML format.
// Outlook directory
string dataDir = RunExamples.GetDataDir_Outlook();
MailMessage mailMessage = MailMessage.Load(dataDir + "TestAppointment.eml");
MapiConversionOptions conversionOptions = new MapiConversionOptions();
conversionOptions.Format = OutlookMessageFormat.Unicode;
// default value for ForcedRtfBodyForAppointment is true
conversionOptions.ForcedRtfBodyForAppointment = false;
MapiMessage mapiMessage = MapiMessage.FromMailMessage(mailMessage, conversionOptions);
Console.WriteLine("Body Type: " + mapiMessage.BodyType);
mapiMessage.Save(dataDir + "TestAppointment_out.msg");
Set the State of MAPI Calendar Items Manually
Set the state of a MAPI Calendar object explicitly, overriding default behavior. This allows better control over calendar event states, particularly when handling received meeting requests. By default, when a meeting is created, its state is MapiCalendarState.Meeting. When received in a recipient’s inbox, it automatically changes to MapiCalendarState.Received, and its message class is updated to “IPM.Schedule.Meeting.Request”. Using SetStateForced allows manually setting the state to Received, which can be useful for preserving organizer information when saving the calendar as an MSG file. However, this may prevent proper forwarding or resending of the meeting.
The code sample below demonstrates how to create a MapiCalendar object, assign an organizer, and explicitly set its state to both Meeting and Received using SetStateForced. It then saves the calendar item as an .msg file.
MapiCalendar appointment = new MapiCalendar(
"LAKE ARGYLE WA 6743",
"Appointment",
"This is a very important meeting :)",
new DateTime(2024, 5, 10, 12, 30, 0, DateTimeKind.Utc),
new DateTime(2024, 5, 10, 13, 30, 0, DateTimeKind.Utc));
appointment.Organizer = new MapiElectronicAddress
{
EmailAddress = "test@aaa.com",
DisplayName = "test display Name"
};
appointment.SetStateForced(MapiCalendarState.Meeting | MapiCalendarState.Received);
appointment.Save("appointment.msg", AppointmentSaveFormat.Msg);
See Also
- Manage Appointments — work with iCalendar (ICS) appointments and meeting requests.
- Managing Calendar Items in PST Files — store and read calendar items inside a PST.