Sending Outlook meeting requests without Outlook?

前端 未结 5 1828
广开言路
广开言路 2020-11-28 02:32

I just wonder if it is possible to send Meeting Requests to people without having Outlook installed on the Server and using COM Interop (which I want to avoid on a server at

5条回答
  •  被撕碎了的回忆
    2020-11-28 02:46

    You can send meeting requests by mail to outlook using the iCal Standard (RFC 5545)

    You can't send todo items this way. You may send "Appointments" but these appear in outlook as .ics attachments which have to be accepted "blindly".

    Meeting requests appear in outlook with a nice preview and can be accepted or rejeted. The sending program may modify or cancel the meeting after it was sent.

    It's easieset to create a valid iCal item with the DDay.iCal .Net Library

    The code below is a complete working example. It builds a string with a valid iCal meeting request and sends it by mail.

    The code creates a mail with:

    • plain text body for simple mail clients
    • HTML body for diplay in modern mail clients
    • iCal meeting request as AlternateView (will display in Outlook)
    • iCal meeting request as Attachment (usable in mail clients other than outlook)

    The code shows how to add:

    • description text as HTML, looks nicer in outlook
    • Priority, visibility (public/private/confidential)
    • optional organizer (will show in outlook instead of the mail sender)
    • optional attendees
    • optional alarm
    • optional attachments to the meeting. will show up in outlook's calendar

    Some important details:

    • mail sender (or optional organizer) and mail receiver must be different to make this work in outlook
    • METHOD in .ics and METHOD in Mime.ContentType must match
    • The meeting must lie in the future to make this work in outlook
    • the .ics part must be the last alternateView part in the MIME mail

    The exact details about the way outlook interprets .ics files are detailed in [MS-OXCICAL]: iCalendar to Appointment Object Conversion Algorithm

    We'll use these assemblies:

    using System;
    using System.IO;
    using System.Net.Mail;
    using DDay.iCal;
    using DDay.iCal.Serialization.iCalendar;
    

    For DDay.iCal its enough to download the DDay.iCal binary Files. If you want to add some features it's best to look at the DDay.iCal sources because the documentation is outdated and the sources contain pretty complete tests which excercise all its features.

    const string filepath = @"C:\temp\ical.test.ics";
    // use PUBLISH for appointments
    // use REQUEST for meeting requests
    const string METHOD = "REQUEST";
    
    // Properties of the meeting request
    // keep guid in sending program to modify or cancel the request later
    Guid uid = Guid.Parse("2B127C67-73B3-43C5-A804-5666C2CA23C9");
    string VisBetreff = "This is the subject of the meeting request";
    string TerminVerantwortlicherEmail = "mr.asker@myorg.com";
    string bodyPlainText = "This is the simple iCal plain text msg";
    string bodyHtml = "This is the simple iCal HTML message";
    string location = "Meeting room 101";
    // 1: High
    // 5: Normal
    // 9: low
    int priority = 1;
    //=====================================
    MailMessage message = new MailMessage();
    
    message.From = new MailAddress("sender@myorg.com");
    message.To.Add(new MailAddress(TerminVerantwortlicherEmail));
    message.Subject = "[VIS-Termin] " + VisBetreff;
    
    // Plain Text Version
    message.Body = bodyPlainText;
    
    // HTML Version
    string htmlBody = bodyHtml;
    AlternateView HTMLV = AlternateView.CreateAlternateViewFromString(htmlBody,
      new System.Net.Mime.ContentType("text/html"));
    
    // iCal
    IICalendar iCal = new iCalendar();
    iCal.Method = METHOD;
    iCal.ProductID = "My Metting Product";            
    
    // Create an event and attach it to the iCalendar.
    Event evt = iCal.Create();
    evt.UID = uid.ToString();
    
    evt.Class = "PUBLIC";
    // Needed by Outlook
    evt.Created = new iCalDateTime(DateTime.Now);
    
    evt.DTStamp = new iCalDateTime(DateTime.Now);
    evt.Transparency = TransparencyType.Transparent;
    
    // Set the event start / end times
    evt.Start = new iCalDateTime(2014, 10, 3, 8, 0, 0); 
    evt.End = new iCalDateTime(2014, 10, 3, 8, 15, 0); 
    evt.Location = location;
    
    //var organizer = new Organizer("the.organizer@myCompany.com");
    //evt.Organizer = organizer;
    
    // Set the longer description of the event, plain text
    evt.Description = bodyPlainText;
    
    // Event description HTML text
    // X-ALT-DESC;FMTTYPE=text/html
    var prop = new CalendarProperty("X-ALT-DESC");
    prop.AddParameter("FMTTYPE", "text/html");
    prop.AddValue(bodyHtml);
    evt.AddProperty(prop);
    
    // Set the one-line summary of the event
    evt.Summary = VisBetreff;
    evt.Priority = priority;
    
    //--- attendes are optional
    IAttendee at = new Attendee("mailto:Peter.Black@MyOrg.com");
    at.ParticipationStatus = "NEEDS-ACTION";
    at.RSVP = true;
    at.Role = "REQ-PARTICIPANT";
    evt.Attendees.Add(at);
    
    // Let’s also add an alarm on this event so we can be reminded of it later.
    Alarm alarm = new Alarm();
    
    // Display the alarm somewhere on the screen.
    alarm.Action = AlarmAction.Display;
    
    // This is the text that will be displayed for the alarm.
    alarm.Summary = "Upcoming meeting: " + VisBetreff;
    
    // The alarm is set to occur 30 minutes before the event
    alarm.Trigger = new Trigger(TimeSpan.FromMinutes(-30));
    
    //--- Attachments
    string filename = "Test.docx";
    
    // Add an attachment to this event
    IAttachment attachment = new DDay.iCal.Attachment();
    attachment.Data = ReadBinary(@"C:\temp\Test.docx");
    attachment.Parameters.Add("X-FILENAME", filename);
    evt.Attachments.Add(attachment);
    
    iCalendarSerializer serializer = new iCalendarSerializer();
    serializer.Serialize(iCal, filepath);
    
    // the .ics File as a string
    string iCalStr = serializer.SerializeToString(iCal);
    
    // .ics as AlternateView (used by Outlook)
    // text/calendar part: method=REQUEST
    System.Net.Mime.ContentType calendarType = 
      new System.Net.Mime.ContentType("text/calendar");
    calendarType.Parameters.Add("method", METHOD);
    AlternateView ICSview =
      AlternateView.CreateAlternateViewFromString(iCalStr, calendarType);
    
    // Compose
    message.AlternateViews.Add(HTMLV);
    message.AlternateViews.Add(ICSview); // must be the last part
    
    // .ics as Attachment (used by mail clients other than Outlook)
    Byte[] bytes = System.Text.Encoding.ASCII.GetBytes(iCalStr);
    var ms = new System.IO.MemoryStream(bytes);
    var a = new System.Net.Mail.Attachment(ms,
      "VIS-Termin.ics", "text/calendar");
    message.Attachments.Add(a);     
    
    // Send Mail
    SmtpClient client = new SmtpClient();
    client.Send(message);
    

    Here the ReadBinary() function:

    private static byte[] ReadBinary(string fileName)
    {
        byte[] binaryData = null;
        using (FileStream reader = new FileStream(fileName,
          FileMode.Open, FileAccess.Read))
        {
            binaryData = new byte[reader.Length];
            reader.Read(binaryData, 0, (int)reader.Length);
        }
        return binaryData;
    }
    

    Its easiest to configure the SmtpClient in the config file like this:

    
      ...
        
        
          
            
          
        
      
      ...
    

提交回复
热议问题