Respond to a meeting request item
The downloaded e-mail message containing the meeting request item is an ordinary message with extra body part of "text/calendar" content-type.
Thus, you download such messages as any others:
// Download entire message from the server.
MailMessage msg = pop.DownloadEntireMessage(1);
' Download entire message from the server.
Dim msg As MailMessage = pop.DownloadEntireMessage(1)
To make your application aware of meeting request items, you should check each incoming message for vCalendar events:
// Make sure this message is vCalendar event
if (msg.BodyParts["text/calendar"].Text.Length > 0)
{
calEvent = ParseCalendarRecord(msg.BodyParts["text/calendar"].Text);
}
' Make sure this message is vCalendar event
If msg.BodyParts("text/calendar").Text.Length > 0 Then
calEvent = ParseCalendarRecord(msg.BodyParts("text/calendar").Text)
End If
In order to collect all the available information, we need to check as many fields as possible. The category of the calendar item is important, too: if the event denotes a conference, it becomes an appointment in your organizer software. But if it's a meeting request, you should compose and send the meeting confirmation message to the sender. Such reply messages have the same structure as meeting requests, the only difference is in their method field:
// If we accepted the meeting request, generate and send the
// confirmation message
// ("accepted" in the code below is a boolean whose value was
// already set accordingly the decision made by the human user).
if (calEvent.method == "REQUEST" && accepted)
{
// The only difference between the request and the reply.
calEvent.method = "REPLY";
Smtp mailer = new Smtp();
// Create message
mailer.Message.From.Email = "jdoe@domain.com";
mailer.Message.To.Add(msg.From.Email);
mailer.Message.Subject = "Meeting Request";
// Create calendar body
mailer.Message.BodyParts.Add("text/calendar");
mailer.Message.BodyParts["text/calendar"].Text = CreateCalendarRecord(calEvent);
...
}
' If we accepted the meeting request, generate and send the
' confirmation message
' ("accepted" in the code below is a boolean whose value was
' already set accordingly the decision made by the human user).
If calEvent.method = "REQUEST" And accepted Then
' The only difference between the request and the reply.
calEvent.method = "REPLY"
Dim mailer As New Smtp()
' Create message
mailer.Message.From.Email = "jdoe@domain.com"
mailer.Message.To.Add(msg.From.Email)
mailer.Message.Subject = "Meeting Request"
' Create calendar body
mailer.Message.BodyParts.Add("text/calendar")
mailer.Message.BodyParts("text/calendar").Text = CreateCalendarRecord(calEvent)
...
End If
After creating the vCalendar event, the message can be sent through SMTP server.
Code example:
The sample code below receives a message and analyzes it for vCalendar content. If the message is a meeting request, a confirmation message is sent to the sender. The sample also displays the vCalendar part of the message.
public struct VCalendar
{
public int year, month, day, hour, minute, second, duration;
public string summary, location, method;
}
string CreateCalendarRecord(VCalendar calEvent)
{
string calRecord;
calRecord = "BEGIN:VCalendar" + "\r\n";
calRecord += "METHOD:" + calEvent.method + "\r\n";
calRecord += "BEGIN:VEVENT" + "\r\n";
calRecord += "DTSTART:" + calEvent.year.ToString("0000") + calEvent.month.ToString("00") + calEvent.day.ToString("00");
calRecord += "T" + calEvent.hour.ToString("00") + calEvent.minute.ToString("00") + calEvent.second.ToString("00") + "Z\r\n";
calEvent.hour += calEvent.duration;
calRecord += "DTEND:" + calEvent.year.ToString("0000") + calEvent.month.ToString("00") + calEvent.day.ToString("00");
calRecord += "T" + calEvent.hour.ToString("00") + calEvent.minute.ToString("00") + calEvent.second.ToString("00") + "Z\r\n";
calRecord += "LOCATION:" + calEvent.location + "\r\n";
calRecord += "SUMMARY:" + calEvent.summary+ "\r\n";
calRecord += "END:VEVENT" + "\r\n";
calRecord += "END:VCalendar";
return calRecord;
}
VCalendar ParseCalendarRecord(string msg_string)
{
VCalendar calEvent = new VCalendar();
string [] lines = null;
int delimiterIdx;
string start_time;
string keyName, keyValue;
// Split text on lines
lines = msg_string.Split('\n');
// Iterate thorough all lines
for (int i = 0; i < lines.Length; i++)
{
delimiterIdx = lines[i].IndexOf(":");
// If delimiter ':' char is found
if (delimiterIdx > 0)
{
// First part of the line is the required name
keyName = lines[i].Substring(0, delimiterIdx);
// To the right from delimiter is the value
keyValue = lines[i].Substring(delimiterIdx + 1, lines[i].Length - delimiterIdx - 2);
// If next string begins with space - append it to description
while (i + 1 < lines.Length)
{
if (lines[i + 1][0] == ' ')
{
i++;
keyValue += lines[i].Substring(1, lines[i].Length - 2);
}
else break;
}
// Parse defenitions
switch(keyName)
{
case "METHOD":
calEvent.method = keyValue;
break;
case "DTSTART":
start_time = keyValue;
calEvent.year = int.Parse(start_time.Substring(0,4));
calEvent.month = int.Parse(start_time.Substring(4,2));
calEvent.day = int.Parse(start_time.Substring(6,2));
calEvent.hour = int.Parse(start_time.Substring(9,2));
calEvent.minute = int.Parse(start_time.Substring(11,2));
calEvent.second = int.Parse(start_time.Substring(13,2));
break;
case "LOCATION":
calEvent.location = keyValue;
break;
case "SUMMARY" :
calEvent.summary = keyValue;
break;
default:
break;
}
}
}
return calEvent;
}
Pop3 pop = new Pop3();
// Connect to POP3 server
pop.Connect("mail.domain.com");
pop.Login("jdoe","secret");
// Download entire message from the server.
MailMessage msg = pop.DownloadEntireMessage(1);
// Disconnect from POP3 server
pop.Disconnect();
VCalendar calEvent = new VCalendar();
bool isVCalItem = false;
// Make sure that this message is vCalendar event
if (msg.BodyParts["text/calendar"].Text.Length > 0)
{
calEvent = ParseCalendarRecord(msg.BodyParts["text/calendar"].Text);
isVCalItem = true;
}
// This flag indicates whether the request was accepted or not.
// Let's assume the human user decided to accept this meeting request.
bool accepted = true;
// If request accepted then generate and send message
if (isVCalItem && calEvent.method == "REQUEST" && accepted)
{
calEvent.method = "REPLY";
Smtp mailer = new Smtp();
// Create message
mailer.Message.From.Email = "jdoe@domain.com";
mailer.Message.To.Add(msg.From.Email);
mailer.Message.Subject = "Meeting Request";
// Create calendar body
mailer.Message.BodyParts.Add("text/calendar");
mailer.Message.BodyParts["text/calendar"].Text = CreateCalendarRecord(calEvent);
// Connect to SMTP server and send meeting request
mailer.SmtpServers.Add("mail.domain.com", "jdoe", "secret");
mailer.Send();
}
Public Structure VCalendar
Public year As Integer,month As Integer,day As Integer,hour As Integer,minute As Integer,second As Integer,duration As Integer
Public summary As String,location As String,method As String
End Structure
Private Function CreateCalendarRecord(ByVal calEvent As VCalendar) As String
Dim calRecord As String
calRecord = "BEGIN:VCalendar" + "\r\n"
calRecord += "METHOD:" + calEvent.method + "\r\n"
calRecord += "BEGIN:VEVENT" + "\r\n"
calRecord += "DTSTART:" + calEvent.year.ToString("0000") + calEvent.month.ToString("00") + calEvent.day.ToString("00")
calRecord += "T" + calEvent.hour.ToString("00") + calEvent.minute.ToString("00") + calEvent.second.ToString("00") + "Z\r\n"
calEvent.hour += calEvent.duration
calRecord += "DTEND:" + calEvent.year.ToString("0000") + calEvent.month.ToString("00") + calEvent.day.ToString("00")
calRecord += "T" + calEvent.hour.ToString("00") + calEvent.minute.ToString("00") + calEvent.second.ToString("00") + "Z\r\n"
calRecord += "LOCATION:" + calEvent.location + "\r\n"
calRecord += "SUMMARY:" + calEvent.summary+ "\r\n"
calRecord += "END:VEVENT" + "\r\n"
calRecord += "END:VCalendar"
Return calRecord
End Function
Private Function ParseCalendarRecord(ByVal msg_string As String) As VCalendar
Dim calEvent As New VCalendar()
Dim lines() As String = Nothing
Dim delimiterIdx As Integer
Dim start_time As String
Dim keyName As String,keyValue As String
' Split text on lines
lines = msg_string.Split(vbLf)
' Iterate thorough all lines
Dim i As Integer
For i = 0 To lines.Length- 1 Step i + 1
delimiterIdx = lines(i).IndexOf(":")
' If delimiter ':' char is found
If delimiterIdx > 0 Then
' First part of the line is the required name
keyName = lines(i).Substring(0, delimiterIdx)
' To the right from delimiter is the value
keyValue = lines(i).Substring(delimiterIdx + 1, lines(i).Length - delimiterIdx - 2)
' If next string begins with space - append it to description
While i + 1 < lines.Length
If lines(i + 1)(0) = ' ' Then
i = i + 1
keyValue += lines(i).Substring(1, lines(i).Length - 2)
Else
Exit While
End While
' Parse defenitions
Select Case keyName
Case "METHOD"
calEvent.method = keyValue
Case "DTSTART"
start_time = keyValue
calEvent.year = Integer.Parse(start_time.Substring(0,4))
calEvent.month = Integer.Parse(start_time.Substring(4,2))
calEvent.day = Integer.Parse(start_time.Substring(6,2))
calEvent.hour = Integer.Parse(start_time.Substring(9,2))
calEvent.minute = Integer.Parse(start_time.Substring(11,2))
calEvent.second = Integer.Parse(start_time.Substring(13,2))
Case "LOCATION"
calEvent.location = keyValue
Case "SUMMARY"
calEvent.summary = keyValue
Case Else
End Select
End If
Next
Return calEvent
End Function
Dim pop As New Pop3()
' Connect to POP3 server
pop.Connect("mail.domain.com")
pop.Login("jdoe","secret")
' Download entire message from the server.
Dim msg As MailMessage = pop.DownloadEntireMessage(1)
' Disconnect from POP3 server
pop.Disconnect()
Dim calEvent As New VCalendar()
Dim isVCalItem As Boolean = False
' Make sure that this message is vCalendar event
If msg.BodyParts("text/calendar").Text.Length < 0 Then
calEvent = ParseCalendarRecord(msg.BodyParts("text/calendar").Text)
isVCalItem = True
End If
' This flag indicates whether the request was accepted or not.
' Let's assume the human user decided to accept this meeting request.
Dim accepted As Boolean = True
' If request accepted then generate and send message
If isVCalItem And calEvent.method = "REQUEST" And accepted Then
calEvent.method = "REPLY"
Dim mailer As New Smtp()
' Create message
mailer.Message.From.Email = "jdoe@domain.com"
mailer.Message.To.Add(msg.From.Email)
mailer.Message.Subject = "Meeting Request"
' Create calendar body
mailer.Message.BodyParts.Add("text/calendar")
mailer.Message.BodyParts("text/calendar").Text = CreateCalendarRecord(calEvent)
' Connect to SMTP server and send meeting request
mailer.SmtpServers.Add("mail.domain.com", "jdoe", "secret")
mailer.Send()
End If
You can use the same approach to parse calendar entries of other formats (such as iCalendar).