Управление встречами: создание и изменение, конвертация ICS в MSG
В этой статье рассматриваются стандартные iCalendar (ICS) встречи, обрабатываемые через Appointment класс. Чтобы работать с Outlook MapiCalendar элементы вместо этого, см. Управление элементами календаря Outlook; чтобы хранить и считывать элементы календаря внутри PST, см. Управление элементами календаря в файлах PST.
Создать встречу и сохранить её на диск в формате MSG или ICS
Этот Appointment класс в Aspose.Email для .NET может использоваться для создания новой встречи. В этой статье мы сначала создаём встречу и сохраняем её на диск в формате ICS. Для создания встречи и сохранения её на диск требуются следующие шаги.
- Создать экземпляр Appointment класс и инициализировать его с помощью этого конструктора.
- Передайте следующие аргументы в указанный выше конструктор
- Место
- Сводка
- Описание
- Дата начала
- Дата завершения
- Организатор
- Участники
- Вызвать Save() метод и указать имя файла и формат в аргументах.
Встречу можно открыть в Microsoft Outlook или любой программе, способной загрузить файл ICS. Если файл открыт в Microsoft Outlook, он автоматически добавит встречу в календарь Outlook.
Следующий фрагмент кода показывает, как создать и сохранить встречу на диск в формате ICS или MSG.
// Create and initialize an instance of the Appointment class
Appointment appointment = new Appointment(
"Meeting Room 3 at Office Headquarters",// Location
"Monthly Meeting", // Summary
"Please confirm your availability.", // Description
new DateTime(2015, 2, 8, 13, 0, 0), // Start date
new DateTime(2015, 2, 8, 14, 0, 0), // End date
"from@domain.com", // Organizer
"attendees@domain.com"); // Attendees
// Save the appointment to disk in ICS format
appointment.Save(fileName + ".ics", new AppointmentIcsSaveOptions());
Console.WriteLine("Appointment created and saved to disk successfully.");
// Save the appointment to disk in MSG format
appointment.Save(fileName + ".msg", new AppointmentMsgSaveOptions());
Console.WriteLine("Appointment created and saved to disk successfully.");
Создание встречи с HTML‑содержимым
Вы можете указать альтернативные представления описания события в разных типах контента, используя заголовок X-ALT-DESC. Это позволяет получателям файла iCalendar выбирать представление, которое лучше соответствует их потребностям. Например, можно включить описание в простом тексте с типом контента "text/plain" и описание в HTML с типом контента "text/html". Для каждого альтернативного представления добавляется заголовок X-ALT-DESC. Чтобы создать встречу с HTML‑содержимым, установите HtmlDescription свойство.
Попробуйте следующий пример кода для создания встречи с альтернативным HTML‑описанием:
- Создайте новый экземпляр класса Appointment.
- Передайте необходимые параметры в конструктор Appointment:
- Укажите место проведения встречи.
- Установите дату и время начала.
- Установите дату и время окончания.
- Укажите организатора.
- Укажите участника.
- Установите HtmlDescription свойство объекта встречи, указывающее, что описание в формате HTML.
- Установите свойство Description объекта встречи в строку формата HTML, заключённую в многострочную строку:
- Разметка HTML включает блок <style>, определяющий CSS‑класс с именем "text" со стилями шрифта.
- Тело HTML содержит тег абзаца <p> с CSS‑классом "text" и фактическое сообщение‑приглашение.
- Объект встречи теперь готов, и вы можете выполнять дальнейшие операции или сохранить его как файл iCalendar.
var appointment = new Appointment("Bygget 83",
DateTime.UtcNow, // start date
DateTime.UtcNow.AddHours(1), // end date
new MailAddress("TintinStrom@from.com", "Tintin Strom"), // organizer
new MailAddress("AinaMartensson@to.com", "Aina Martensson")) // attendee
{
HtmlDescription = @"
<html>
<style type=""text/css"">
.text {
font-family:'Comic Sans MS';
font-size:16px;
}
</style>
<body>
<p class=""text"">Hi, I'm happy to invite you to our party.</p>
</body>
</html>"
};
Создание запроса черновика встречи
В наших предыдущих статьях было показано, как создать и сохранить встречу в формате ICS. Часто требуется создать запрос встречи в режиме черновика, чтобы базовая информация была внесена, а затем такой черновик встречи мог быть переслан другим пользователям для внесения необходимых изменений в соответствии с их потребностями. Чтобы сохранить встречу в режиме черновика, MethodType свойство класса Appointment должно быть установлено в AppointmentMethodType.Publish. Следующий фрагмент кода показывает, как создать черновик запроса встречи.
string sender = "test@gmail.com";
string recipient = "test@email.com";
MailMessage message = new MailMessage(sender, recipient, string.Empty, string.Empty);
Appointment app = new Appointment(string.Empty, DateTime.Now, DateTime.Now, sender, recipient)
{
MethodType = AppointmentMethodType.Publish
};
message.AddAlternateView(app.RequestApointment());
MapiMessage msg = MapiMessage.FromMailMessage(message);
// Save the appointment as draft.
msg.Save(dstDraft);
Console.WriteLine(Environment.NewLine + "Draft saved at " + dstDraft);
Создание черновика встречи из текста
Следующий фрагмент кода показывает, как создать черновик встречи из текста.
string ical = @"BEGIN:VCALENDAR
METHOD:PUBLISH
PRODID:-//Aspose Ltd//iCalender Builder (v3.0)//EN
VERSION:2.0
BEGIN:VEVENT
ATTENDEE;CN=test@gmail.com:mailto:test@gmail.com
DTSTART:20130220T171439
DTEND:20130220T174439
DTSTAMP:20130220T161439Z
END:VEVENT
END:VCALENDAR";
string sender = "test@gmail.com";
string recipient = "test@email.com";
MailMessage message = new MailMessage(sender, recipient, string.Empty, string.Empty);
AlternateView av = AlternateView.CreateAlternateViewFromString(ical, new ContentType("text/calendar"));
message.AlternateViews.Add(av);
MapiMessage msg = MapiMessage.FromMailMessage(message);
msg.Save(dataDir + "draft_out.msg");
Настройка встреч
Установка статуса участников встречи
API Aspose.Email для .NET позволяет задавать статус участников встречи при формировании сообщения-ответа. Это добавляет свойство PARTSTAT в файлICS.
DateTime startDate = new DateTime(2011, 12, 10, 10, 12, 11),
endDate = new DateTime(2012, 11, 13, 13, 11, 12);
MailAddress organizer = new MailAddress("aaa@amail.com", "Organizer");
MailAddressCollection attendees = new MailAddressCollection();
MailAddress attendee1 = new MailAddress("bbb@bmail.com", "First attendee");
MailAddress attendee2 = new MailAddress("ccc@cmail.com", "Second attendee");
attendee1.ParticipationStatus = ParticipationStatus.Accepted;
attendee2.ParticipationStatus = ParticipationStatus.Declined;
attendees.Add(attendee1);
attendees.Add(attendee2);
Appointment target = new Appointment(location, startDate, endDate, organizer, attendees);
Настройка идентификатора продукта для iCalendar
API Aspose.Email для .NET позволяет получать или задавать идентификатор продукта, создавшего объект iCalendar.
string description = "Test Description";
Appointment app = new Appointment("location", "test appointment", description, DateTime.Today,
DateTime.Today.AddDays(1), "first@test.com", "second@test.com");
AppointmentIcsSaveOptions saveOptions = AppointmentIcsSaveOptions.Default;
saveOptions.ProductId = "Test Corporation";
app.Save(dataDir + "ChangeProdIdOfICS.ics", saveOptions);
Загрузка встреч
Также Appointment класс может использоваться для загрузки встречи из файла ICS.
Загрузка встречи в формате ICS
Чтобы загрузить встречу в формате ICS, требуется выполнить следующие шаги:
- Создать экземпляр Appointment класс.
- Вызвать Load() метод, указывая путь к файлу ICS.
- Прочитайте любое свойство, чтобы получить любую информацию о встрече (файл ICS).
Следующий фрагмент кода показывает, как загрузить встречу в формате ICS.
// Load an Appointment just created and saved to disk and display its details.
Appointment loadedAppointment = Appointment.Load(dstEmail);
Console.WriteLine(Environment.NewLine + "Loaded Appointment details are as follows:");
// Display the appointment information on screen
Console.WriteLine("Summary: " + loadedAppointment.Summary);
Console.WriteLine("Location: " + loadedAppointment.Location);
Console.WriteLine("Description: " + loadedAppointment.Description);
Console.WriteLine("Start date: " + loadedAppointment.StartDate);
Console.WriteLine("End date: " + loadedAppointment.EndDate);
Console.WriteLine("Organizer: " + loadedAppointment.Organizer);
Console.WriteLine("Attendees: " + loadedAppointment.Attendees);
Console.WriteLine(Environment.NewLine + "Appointment loaded successfully from " + dstEmail);
Конвертировать ICS в MSG
API позволяет легко преобразовать встречу в объект сообщения. Следующий пример кода показывает, как конвертировать запрос встречи в MailMessage или MapiMessage:
var appointment = Appointment.Load("appRequest.ics");
var eml = appointment.ToMailMessage();
var msg = appointment.ToMapiMessage();
Чтение нескольких событий из файла ICS
List<Appointment> appointments = new List<Appointment>();
CalendarReader reader = new CalendarReader(dataDir + "US-Holidays.ics");
while (reader.NextEvent())
{
appointments.Add(reader.Current);
}
//working with appointments...
Записать несколько событий в файл ICS
AppointmentIcsSaveOptions saveOptions = new AppointmentIcsSaveOptions();
saveOptions.Action = AppointmentAction.Create;
using (CalendarWriter writer = new CalendarWriter(dataDir + "WriteMultipleEventsToICS_out.ics", saveOptions))
{
for (int i = 0; i < 10; i++)
{
Appointment app = new Appointment(string.Empty, DateTime.Now, DateTime.Now, "sender@domain.com", "receiver@domain.com");
app.Description = "Test body " + i;
app.Summary = "Test summary:" + i;
writer.Write(app);
}
}
Определить версию встречи
Чтобы определить версию встречи, вы можете использовать Appointment.Version свойство Appointment класс. Это свойство помогает определить, на какой версии основаны их файлы, обеспечивая интеграцию с другими системами и приложениями.
Следующий образец кода показывает, как реализовать это свойство в вашем проекте:
var app = Appointment.Load("meeting.ics");
// Version is a string that holds the ICS/VCS version, e.g. "2.0" for iCalendar
if (app.Version == "2.0")
{
// do something
}
Отправка и отмена запросов на встречи
Этот Appointment класс, вместе с SmtpClient, может использоваться для отправки запросов на встречи, повторяющихся встреч, обновлений и отмен по электронной почте. Встреча добавляется в MailMessage в виде альтернативного представления.
Отправить запрос на встречу
Чтобы отправить запрос на встречу, создайте Appointment, добавьте её к сообщению с помощью RequestApointment метод, и отправьте сообщение. Сохраните UniqueId значение, чтобы позже можно было сослаться на ту же встречу при отправке обновления или отмены.
// Create an instance of SmtpClient
SmtpClient client = new SmtpClient("smtp.gmail.com", 587, "user@gmail.com", "password");
client.SecurityOptions = SecurityOptions.Auto;
// Gather the attendees
MailAddressCollection attendees = new MailAddressCollection();
attendees.Add(new MailAddress("first.attendee@domain.com", "First Attendee"));
attendees.Add(new MailAddress("second.attendee@domain.com", "Second Attendee"));
// Create the message and the appointment
MailMessage msg = new MailMessage();
msg.From = "organizer@domain.com";
msg.To = attendees;
Appointment app = new Appointment("Meeting Room 1", DateTime.Now, DateTime.Now.AddHours(1), msg.From, attendees);
app.Summary = "Monthly Meeting";
app.Description = "Please confirm your availability.";
// Add the appointment to the message and send it
msg.AddAlternateView(app.RequestApointment());
client.Send(msg);
Отправить запрос на повторяющуюся встречу
Чтобы создать запрос на встречу с повторением, укажите рекуррентный паттерн (например, WeeklyRecurrencePattern) к Appointment.Recurrence свойство. Сохранение уникального идентификатора встречи позволяет позже отправлять обновления.
// Create a mail message
MailMessage msg1 = new MailMessage();
msg1.To.Add("to@domain.com");
msg1.From = new MailAddress("from@gmail.com");
// Fill the appointment object
DateTime startDate = new DateTime(2013, 12, 1, 17, 0, 0);
DateTime endDate = new DateTime(2013, 12, 31, 17, 30, 0);
Appointment agendaAppointment = new Appointment("same place", startDate, endDate, msg1.From, msg1.To);
// Create a unique id so the appointment can be accessed later
string szUniqueId = Guid.NewGuid().ToString();
agendaAppointment.UniqueId = szUniqueId;
agendaAppointment.Description = "----------------";
// Create a weekly recurrence pattern: Mon, Tue and Thu
WeeklyRecurrencePattern pattern1 = new WeeklyRecurrencePattern(14);
pattern1.StartDays = new CalendarDay[3];
pattern1.StartDays[0] = CalendarDay.Monday;
pattern1.StartDays[1] = CalendarDay.Tuesday;
pattern1.StartDays[2] = CalendarDay.Thursday;
pattern1.Interval = 1;
// Set the recurrence pattern for the appointment
agendaAppointment.Recurrence = pattern1;
// Attach the appointment to the mail
msg1.AlternateViews.Add(agendaAppointment.RequestApointment());
// Send the mail with the appointment request
SmtpClient client = new SmtpClient("smtp.gmail.com", 587, "your.email@gmail.com", "your.password");
client.SecurityOptions = SecurityOptions.Auto;
client.Send(msg1);
Отправить запрос обновления встречи
Для отправки обновления ранее отправленной встречи требуется уникальный идентификатор встречи. Используйте UpdateAppointment метод для создания альтернативного представления обновления.
static public void SendUpdate(string szUniqueId)
{
DateTime startDate = new DateTime(2013, 12, 12, 17, 0, 0);
DateTime endDate = new DateTime(2013, 12, 12, 17, 30, 0);
Appointment appUpdate = new Appointment("Different Place", startDate, endDate,
"organizer@gmail.com", "attendee@domain.com");
appUpdate.UniqueId = szUniqueId;
appUpdate.Summary = "update meeting request summary";
appUpdate.Description = "update";
MailMessage msgUpdate = new MailMessage("organizer@gmail.com", "attendee@domain.com",
"test email - update meeting request", "test email");
msgUpdate.AddAlternateView(appUpdate.UpdateAppointment());
SmtpClient smtp = new SmtpClient("server.domain.com", 587, "username", "password");
smtp.Send(msgUpdate);
}
Отменить запрос на встречу
Чтобы отменить встречу, сформируйте такой же Appointment (используя информацию, сохраненную при отправке запроса), добавьте её к сообщению с помощью CancelAppointment метод, и отправьте сообщение участникам.
// Re-create the attendee collection and the appointment from your stored data
MailAddressCollection attendees = new MailAddressCollection();
attendees.Add(new MailAddress("first.attendee@domain.com", "First Attendee"));
attendees.Add(new MailAddress("second.attendee@domain.com", "Second Attendee"));
Appointment app = new Appointment("Meeting Room 1", "Monthly Meeting", "Please confirm your availability.",
DateTime.Now, DateTime.Now.AddHours(1),
new MailAddress("organizer@domain.com", "Organizer"), attendees);
// Create the cancellation message
MailMessage msg = new MailMessage();
msg.From = new MailAddress("organizer@domain.com", "");
msg.To = attendees;
msg.Subject = "Cancel meeting";
msg.AddAlternateView(app.CancelAppointment());
SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587, "user@gmail.com", "password");
smtp.Send(msg);
Работа с рекуррентными паттернами iCalendar
Рекуррентный паттерн — способ описать конкретное расписание. Он содержит достаточную информацию для построения списка повторений (дат и времени) согласно заданному расписанию. Паттерн может включать правила повторения, комбинирующиеся в общий паттерн. Чем сложнее паттерн, тем больше правил он содержит.
Рекуррентные паттерны могут включать исключения (не путать с исключениями, представляющими ошибки во время выполнения программы). Исключения добавляют или удаляют даты повторений относительно исходного паттерна. Их можно задавать как явные повторения или как собственный паттерн. Примеры рекуррентных паттернов с исключениями:
- Каждая вторая пятница, кроме периода с июня по август.
- 1‑е число каждого месяца, кроме января, когда должно быть 2‑е.
RFC iCalendar определяет компоненты, такие как VEVENT или VTODO, которые представляют события или задачи. У компонентов могут быть свойства, такие как дата/время начала, описание, местоположение, участники и повторения. Паттерн повторения обычно является свойством повторяющейся задачи или события. Свойства паттерна повторения, определенные iCalendar:
- DTSTART — дата и время начала паттерна (также представляет первое событие, если оно явно не исключено).
- RRULE — задает правило повторения для набора повторений.
- RDATE — определяет список дат и времени, включаемых в набор повторений.
- EXRULE — задает правило повторения для исключений из набора повторений.
- EXDATE — определяет список дат и времени исключений из набора повторений.
Требуется только DTSTART, и он может быть указан только один раз. Все остальные свойства являются необязательными и могут задаваться более одного раза.
Модель объектов рекуррентности Aspose.Email
Этот Aspose.Email.Calendar.Recurrences пространство имен содержит классы для работы с рекуррентными объектами iCalendar. CalendarRecurrence и RecurrenceRule являются центральными классами и предоставляют конкретные реализации соответствующих элементов RFC 2445.
- Этот
CalendarRecurrenceкласс представляет весь рекуррентный паттерн. Вы можете создать новый паттерн с нуля, используя конструктор по умолчанию, или загрузить существующий паттерн в формате iCalendar, используя статическийFromiCalendarметод. - Этот
RecurrenceRuleкласс представляет часть RRULE или EXRULE шаблона повторения.RecurrenceRuleоткрывает ряд свойств, напрямую сопоставляемых с их аналогами в стандарте iCalendar. Например,ByMonthсоответствует BYMONTH в iCalendar и т.д. Анализируя или задавая значенияRecurrenceRuleсвойства, вы можете анализировать или изменять правило повторения.
Следующий фрагмент кода загружает рекуррентный паттерн (в котором часть RRULE содержит правило повторения) и генерирует повторения:
// Ten team meetings, every Monday at 10am.
CalendarRecurrence pattern = new CalendarRecurrence("DTSTART:20040301T100000\n" + "RRULE:FREQ=WEEKLY;COUNT=10;BYDAY=MO");
DateCollection dates = pattern.GenerateOccurrences();
Генерация повторений из рекуррентного паттерна
С Aspose.Email можно генерировать повторения из рекуррентного паттерна. Чтобы получить «следующее» повторение, используйте GenerateOccurrences метод с параметром nNextOccurrences = 1. Следующий фрагмент кода генерирует 20 повторений, используя GenerateOccurrences(20).
CalendarRecurrence recurrencePattern = new CalendarRecurrence();
recurrencePattern.StartDate = new DateTime(1997, 9, 10, 9, 0, 0);
RecurrenceRule rule = recurrencePattern.RRules.Add();
rule.Frequency = Frequency.Monthly;
rule.Count = 20;
rule.Interval = 18;
rule.ByMonthDay.Add(new int[] { 10, 11, 12, 13, 14, 15 });
DateCollection expectedDates = recurrencePattern.GenerateOccurrences(20);
Console.WriteLine("expectedDates.Count = " + expectedDates.Count);
foreach (DateTime date in expectedDates)
{
Console.WriteLine("DateTime = " + date);
}
Получить удобный для пользователя текст рекуррентного правила
Текст, удобный для пользователя, для правила можно получить с помощью FriendlyText свойство. Вывод следующего кода: "Повторять каждый месяц 1‑е и 1‑е с конца дня(дней) месяца максимум 2 раза."
RecurrenceRule rule = new RecurrenceRule();
rule.Frequency = Frequency.Monthly;
rule.Count = 2;
rule.ByMonthDay.Add(1);
rule.ByMonthDay.Add(-1);
Console.WriteLine(rule.FriendlyText);
Примеры рекуррентных паттернов
Следующие образцы строк RRULE показывают, как выражать типичные расписания.
-
Последний день месяца, каждый месяц. Если вам нужно событие за день до последнего дня месяца, используйте
BYMONTHDAY=-2. Если вы указываетеBYMONTHDAY=31, тогда согласно стандарту iCalendar, событие не генерируется в месяцах, в которых меньше 31 дня.RRULE:FREQ=MONTHLY;BYMONTHDAY=-1 -
Последний рабочий день каждого месяца. Это правило выбирает все рабочие дни месяца и выбирает последний из них. В результате получается последний рабочий день месяца.
RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1 -
Последний понедельник года.
RRULE:FREQ=YEARLY;BYDAY=-1MO -
Пятница первой недели ISO 8601 года. В спецификации ISO 8601 первая неделя года — первая, содержащая минимум четыре дня.
FREQ=YEARLY;BYWEEKNO=1;BYDAY=FR -
Первый пятничный день года. В 1999 году, например, первый пятничный день года — 1999/01/01, тогда как пятница первой недели ISO 8601 — 1999/01/08.
FREQ=YEARLY;BYDAY=1FR
Важные детали iCalendar (RFC 2445)
Даты или даты со временем могут использоваться в элементах DTSTART, UNTIL, EXDATE и RDATE при указании рекуррентного паттерна. iCalendar определяет тип значения DATE для календарных дат и тип DATE‑TIME для точных дат и времени. DATE‑TIME может быть задан в трех формах: локальное время, время UTC и локальное время с часовым поясом.
- DATE. Согласно стандарту iCalendar, значения DATE должны соответствовать
yyyyMMddформат. Например,19970714представляет 14 июля 1997 года. - DATE‑TIME с локальным временем. Дата в форме локального времени — это просто значение даты‑времени без индикатора UTC и без ссылки на часовой пояс. Например,
DTSTART:19980118T230000представляет 18 января 1998 года, 23:00. Дата‑временные значения этого типа называют «плавающими»; они не привязаны к какому‑либо часовому поясу и представляют одинаковые часы, минуты и секунды независимо от текущего часового пояса. - DATE‑TIME с временем UTC. Дата с UTC‑временем (абсолютным временем) обозначается заглавной буквой
Zдобавляемый к значению времени. Например,DTSTART:19980119T070000Zпредставляет 19 января 1998 года, 07:00 UTC. Обратите внимание, что Aspose.Email игнорирует суффикс UTC,Zсуффикс и считает время локальным. Стандарт RFC 2445 гласит, что время в правиле UNTIL рекуррентного паттерна должно быть в формате UTC; Aspose.Email принимает время в любом формате в правиле UNTIL. - DATE‑TIME с локальным временем и часовым поясом. Для указания часового пояса свойство DATE‑TIME изменяется с помощью свойства TZID. Например,
DTSTART;TZID=US-Eastern:19980119T020000представляет 2 утра в Нью‑Йорке 19 января 1998 года. Обратите внимание, что Aspose.Email в текущей версии игнорирует параметр TZID и считает время локальным. - BYWEEKNO и соответствие ISO 8601. Используйте BYWEEKNO только когда требуется соответствие ISO 8601 требуется. Номера недель, определяемые ISO 8601, отличаются от обычных: первая неделя календарного года — это первая неделя, содержащая минимум четыре дня. Правило BYWEEKNO задает список номеров недель года через запятую (допустимые значения от 1 до 53 и от -1 до -53) и доступно только для YEARLY‑правил.
См. также
- Управление элементами календаря Outlook — создавать и управлять элементами календаря как Outlook
MapiCalendar(MSG) объекты. - Управление элементами календаря в файлах PST — хранить и считывать элементы календаря внутри PST.