Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use iCal.Net to Send Meeting Invite for Microsoft Outlook

I am trying to send a meeting invite with C# and am able to get what I want with a manually formatted static string - and here is the screenshot of what I was able to get with the static string

public static void SendEmailString()
{
    MailMessage msg = new MailMessage();
    msg.From = new MailAddress("[email protected]", "Song");
    msg.To.Add(new MailAddress("[email protected]", "John"));
    msg.Subject = "CS Inquiry";
    msg.Body = "TESTING";

    string test = @"BEGIN:VCALENDAR
    PRODID: -//Company & Com//Credit Inquiry//EN
    VERSION:2.0
    METHOD:REQUEST
    BEGIN:VEVENT
    ATTENDEE;CN=""John, Song"";ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:[email protected]
    ATTENDEE;CN=""Lay, Sean"";ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:[email protected]
    ORGANIZER: John, Song
    DTSTART:20171205T040000Z
    DTEND:20171206T040000Z
    LOCATION:New York
    TRANSP:TRANSPARENT
    SEQUENCE:0
    UID:a16fbc2b-72fd-487f-adee-370dc349a2273asfdasd
    DTSTAMP:20171027T215051Z
    DESCRIPTION:Request for information regarding Test
    SUMMARY:Summary 
    PRIORITY: 5
    CLASS: PUBLIC
    BEGIN:VALARM
    TRIGGER:-PT1440M
    ACTION: DISPLAY
    DESCRIPTION:REMINDER
    END:VALARM
    END:VEVENT
    END:VCALENDAR
    ";

    SmtpClient sc = new SmtpClient("smtp.company.com");

    System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
    ct.Parameters.Add("method", "REQUEST");
    AlternateView avCal = AlternateView.CreateAlternateViewFromString(test, ct);
    msg.AlternateViews.Add(avCal);

    sc.Send(msg);
}

I am now trying to replicate that with iCal.Net (because the date and attendees are dynamic) and couldn't get what I want. Please see this screenshot of what I get with the code below:

public static void SendICal()
{            
    DateTime dtStart = new DateTime(2017, 12, 4);
    DateTime dtEnd = dtStart.AddDays(1);

    CalendarEvent e = new CalendarEvent()
    {
        DtStart = new CalDateTime(dtStart),
        DtEnd = new CalDateTime(dtEnd),
        DtStamp = new CalDateTime(DateTime.Now),
        IsAllDay = true,
        Sequence = 0,
        Transparency = TransparencyType.Transparent,
        Description = "Test with iCal.Net",
        Priority = 5,
        Class = "PUBLIC",
        Location = "New York",
        Summary = "Tested with iCal.Net Summary",
        Uid = Guid.NewGuid().ToString(),
        Organizer = new Organizer() {
            CommonName = "John, Song",
            Value = new Uri("mailto:[email protected]")
        } 
    };

    e.Attendees.Add(new Attendee()
    {
        CommonName = "John, Song",
        ParticipationStatus = "REQ-PARTICIPANT",
        Rsvp = true,
        Value = new Uri("mailto:[email protected]")
    });

    e.Attendees.Add(new Attendee()
    {
        CommonName = "John, Sean",
        ParticipationStatus = "REQ-PARTICIPANT",
        Rsvp = true,
        Value = new Uri("mailto:[email protected]")
    });

    Alarm alarm = new Alarm()
    {
        Action = AlarmAction.Display,
        Trigger = new Trigger(TimeSpan.FromDays(-1)),
        Summary = "Inquiry due in 1 day"                 
    };

    e.Alarms.Add(alarm);            

    Calendar c = new Calendar();
    c.Events.Add(e);

    CalendarSerializer serializer = new CalendarSerializer(new SerializationContext());            
    Console.WriteJohne(serializer.SerializeToString(c));

    MailMessage msg = new MailMessage();
    msg.From = new MailAddress("[email protected]", "Credit Inquiry");
    msg.To.Add(new MailAddress("[email protected]", "Song John"));
    msg.Subject = "CS Inquiry";

    System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
    ct.Parameters.Add("method", "REQUEST");
    AlternateView avCal = AlternateView.CreateAlternateViewFromString(serializer.SerializeToString(c), ct);
    msg.AlternateViews.Add(avCal);
    //Response.Write(str);
    // sc.ServicePoint.MaxIdleTime = 2;

    SmtpClient sc = new SmtpClient("smtp.company.com");            
    sc.Send(msg);
}

I am not exactly sure what I am missing here. The iCalendar information generated from iCal.net is almost identical to the static string I used.

Thanks!

like image 211
Brian Avatar asked Oct 28 '17 02:10

Brian


1 Answers

Apparently the low case of TRANSP:Transparent (not TRANS :)) doesn't bother Outlook. It was actually because I forgot to specify the Method property on Calendar.

Based on the spec https://www.kanzaki.com/docs/ical/method.html - "When used in a MIME message entity, the value of this property MUST be the same as the Content-Type "method" parameter value. This property can only appear once within the iCalendar object. If either the "METHOD" property or the Content-Type "method" parameter is specified, then the other MUST also be specified."

I added the line c.Method = "REQUEST"; and it worked as expected.

With one exception though - Apparently Outlook doesn't like the period in Organizer's email address. The meeting invite will not be sent with email address like "[email protected]", it will work if I change it to "[email protected]"

            e.Attendees.Add(new Attendee()
        {
            CommonName = "Lay, Song",
            ParticipationStatus = "REQ-PARTICIPANT",
            Rsvp = true,
            Value = new Uri("mailto:[email protected]")
        });

I will open another thread for that, but would love to hear it if someone knows why :)

like image 175
Brian Avatar answered Oct 17 '22 04:10

Brian