2009-01-20 19 views
36

Zastanawiam się, czy można wysyłać prośby o spotkanie do ludzi bez zainstalowanego Outlooka na Serwerze i korzystania z COM Interop (którego chcę za wszelką cenę uniknąć na serwerze).Wysyłanie zaproszeń na spotkania Outlook bez programu Outlook?

Posiadamy Exchange 2003 w domenie Windows 2003, a wszyscy użytkownicy są użytkownikami domeny. Sądzę, że mogę wysłać "round iCal/vCal" lub coś takiego, ale zastanawiam się, czy istnieje odpowiedni standardowy sposób wysyłania wezwań na spotkanie za pośrednictwem Exchange bez Outlooka?

To jest C#/.net, jeśli to ma znaczenie.

+1

Ilość czasu wybrania czekać czyni mnie myślę, że moja sugestia nie jest dokładnie tym, o czym myślałeś. Czy przynajmniej zmusiłeś go do działania? – Tomalak

+1

Po prostu nie miałem czasu, aby przetestować go wcześniej. Wydawało się, że szybki test zadziałał, i wysłałem zaproszenie na konferencję Outlook na konto z włączonym protokołem POP3, aby uzyskać "surowy zrzut".Te dwa bity są wystarczająco dobre, bym mógł wymyślić resztę, ponieważ muszę tylko wysyłać spotkania, ale nie dbam o odpowiedź. –

+1

W każdym razie twoja odpowiedź była ogromnie pomocna, wielkie dzięki! –

Odpowiedz

47

Sposób wysłać wezwanie na spotkanie do Outlook (i to rozpoznawane) idzie tak:

  • przygotować plik iCalendar, należy ustawić te dodatkowe właściwości, jak Outlook ich potrzebuje:
  • przygotować multipart/alternative mail:
    • Część 1: text/html (lub cokolwiek chcesz) - ten jest wyświetlany dla czytelników "zwykły" poczty lub jako fall-back i zawiera podsumowanie zdarzenia w postaci czytelnej dla człowieka
    • Część 2: text/calendar; method=REQUEST, przechowuje zawartość pliku ics (parametr nagłówka method musi być zgodny z metodą w yc). Uważaj na poprawne kodowanie tekstu, deklarując, że parametr nagłówka charset nie zaszkodzi.
    • Część 3: Opcjonalnie można dołączyć sam plik .ics, aby zwykli czytelnicy poczty mogli zaoferować użytkownikowi coś, co można kliknąć. Program Outlook tak naprawdę nie wymaga załącznika, ponieważ po prostu czyta część text/calendar.
  • Wyślij wiadomość do użytkownika programu Outlook. Jeśli wszystko jest poprawne, poczta pojawia się jako wezwanie na spotkanie, wraz z przyciskami obecności i automatycznym wprowadzaniem do kalendarza użytkowników po zaakceptowaniu.
  • Skonfiguruj coś, co przetwarza odpowiedzi (trafiają do organizatora spotkania). Nie udało mi się jeszcze automatycznie śledzić uczestników, aby pracować ze skrzynką pocztową Exchange, ponieważ wydarzenie nie będzie istniało w kalendarzu organizatorów. Program Outlook potrzebuje identyfikatorów UID i SEQUENCES, aby pasowały do ​​oczekiwań, ale z UID, który Ci się podoba, prawie nie będzie działać.

Aby uzyskać pomoc dotyczącą szczegółów i właściwości pliku formatu ics, należy odwiedzić stronę iCalendar Specification Excerpts by Masahide Kanzaki. Są światłem w ciemności, o wiele lepszym niż przegryzanie się przez RFC 2445. Ale znowu, może przydatna biblioteka istnieje dla .NET.

+0

Po prostu nie miałem czasu, aby przetestować go wcześniej. Wydawało się, że szybki test zadziałał, i wysłałem zaproszenie na konferencję Outlook na konto z włączonym protokołem POP3, aby uzyskać "surowy zrzut". Te dwa bity są wystarczająco dobre, bym mógł wymyślić resztę, ponieważ muszę tylko wysyłać spotkania, ale nie dbam o odpowiedź. –

+1

Usunięcie następującego nagłówka z części 2 zrobiło dla mnie pewną sztuczkę: Treść - Uporządkowanie: załącznik; filename = meeting.ics Dopóki ten nagłówek znajdował się w poczcie, Outlook wyświetlał ICS jako załącznik. – Bob

+0

Tak dzieje się, gdy obecny jest nagłówek 'Content-Disposition: attachment'. ;-) – Tomalak

3

Poniższy kod wyśle ​​zaproszenie na spotkanie w taki sposób, że Outlook wyświetli przyciski Akceptuj/Odrzuć.

Należy pamiętać, że identyfikator UID musi być unikalny dla każdego spotkania, użyłem identyfikatora GUID.

Należy również wymienić CREATED, DTSTART, DTEND, DTSTAMP, LAST-MODIFIED. Są to data/czas UTC.

var m = new MailMessage(); 

    m.Subject = "Meeting"; 

    m.Body = ""; 

    string iCal = 
@"BEGIN:VCALENDAR 
PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN 
VERSION:2.0 
METHOD:PUBLISH 
X-MS-OLK-FORCEINSPECTOROPEN:TRUE 
BEGIN:VEVENT 
CLASS:PUBLIC 
CREATED:20140423T045933Z 
DESCRIPTION:desc 
DTEND:20140430T080000Z 
DTSTAMP:20140423T045933Z 
DTSTART:20140430T060000Z 
LAST-MODIFIED:20140423T045933Z 
LOCATION:location... 
PRIORITY:5 
SEQUENCE:0 
SUMMARY;LANGUAGE=en-us:Summary... 
TRANSP:OPAQUE 
UID:D8BFD357-88A7-455C-86BC-C2CECA9AC5C6 
X-MICROSOFT-CDO-BUSYSTATUS:BUSY 
X-MICROSOFT-CDO-IMPORTANCE:1 
X-MICROSOFT-DISALLOW-COUNTER:FALSE 
X-MS-OLK-AUTOFILLLOCATION:FALSE 
X-MS-OLK-CONFTYPE:0 
BEGIN:VALARM 
TRIGGER:-PT60M 
ACTION:DISPLAY 
DESCRIPTION:Reminder 
END:VALARM 
END:VEVENT 
END:VCALENDAR"; 

    using (var iCalView = AlternateView.CreateAlternateViewFromString(iCal, new System.Net.Mime.ContentType("text/calendar"))) 
    { 
     m.AlternateViews.Add(iCalView); 

     var c = new SmtpClient(); 

     // Send message 
     c.Send(m); 
    } 

Zakłada masz lokalny serwer SMTP skonfigurowany w pliku konfiguracyjnym:

<system.net> 
    <mailSettings> 
     <smtp deliveryMethod="Network" from="[email protected]"> 
     <network defaultCredentials="true" host="smtp.example.local" /> 
     </smtp> 
    </mailSettings> 
    </system.net> 
5

iCalendar jest doskonałym rozwiązaniem ogólnego przeznaczenia, a biblioteka DDay.iCal jest doskonałym sposobem, aby to zrobić z .NET, ale uważam, że Exchange Web Services (EWS) są lepszym rozwiązaniem w kontekście pierwotnego pytania (Exchange, C#/.NET).

Jeśli używasz języka .NET, takiego jak C#, powinieneś użyć opakowania typu EWS Managed API, co znacznie upraszcza pracę z EWS.

Od the docs, oto jak używać EWS Managed API do tworzenia spotkania i wysłać prośbę do zaproszonych:

// Create the appointment. 
Appointment appointment = new Appointment(service); 

// Set properties on the appointment. Add two required attendees and one optional attendee. 
appointment.Subject = "Status Meeting"; 
appointment.Body = "The purpose of this meeting is to discuss status."; 
appointment.Start = new DateTime(2009, 3, 1, 9, 0, 0); 
appointment.End = appointment.Start.AddHours(2); 
appointment.Location = "Conf Room"; 
appointment.RequiredAttendees.Add("[email protected]"); 
appointment.RequiredAttendees.Add("[email protected]"); 
appointment.OptionalAttendees.Add("[email protected]"); 

// Send the meeting request to all attendees and save a copy in the Sent Items folder. 
appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy); 
+1

Zgadzam się, to rozwiązanie jest znacznie prostsze niż inne. Należy również zauważyć, że EWS nie wymaga współpracy programu Outlook COM. – JordanTDN

3

można wysyłać wezwania na spotkania za pośrednictwem poczty do programu Outlook za pomocą iCal Standard (RFC 5545)

You nie można wysyłać w ten sposób elementów todo. Możesz wysłać "Nominacje", ale te pojawiają się w widoku jako załączniki .ics, które muszą być zaakceptowane "na ślepo".

Żądania spotkań pojawiają się w widoku z dobrym podglądem i można je zaakceptować lub odrzucić. Program wysyłający może zmodyfikować lub anulować spotkanie po jego wysłaniu.

To easieset stworzyć ważny element iCal z DDay.iCal .Net Library

Poniższy kod jest kompletnym przykładem pracy. Tworzy ciąg znaków z ważnym wezwaniem na spotkanie iCal i wysyła je pocztą.

Kod tworzy mail z:

  • zwykłego ciała tekstu dla prostych klientów pocztowych
  • ciało HTML diplay w nowoczesnych klientów pocztowych
  • iCal wezwanie na spotkanie jako AlternateView (wyświetla w Outlooku)
  • iCal wezwanie na spotkanie jako załącznik (nadające się do klientów pocztowych innych niż Outlook)

kodu pokazuje, jak dodać:

  • opis tekst w formacie HTML, wygląda ładniej w Outlook
  • Priorytet, widoczność (publiczne/prywatne/poufne)
  • opcjonalnie organizator (pokaże w programie Outlook zamiast nadawcy poczty)
  • opcjonalne uczestnicy
  • opcjonalny alarm
  • opcjonalne załączniki do spotkania. pojawi się w kalendarzu Outlooka

kilka ważnych szczegółów:

  • mail nadawcy (lub opcjonalnie organizatora) oraz odbiornik mail musi być inny do tej pracy w programie Outlook
  • metody w .ics i metoda w Mime.ContentType musi pasować
  • spotkanie musi leżeć w przyszłości do tej pracy w programie Outlook
  • część .ics musi być ostatnią częścią alternateView w mailu MIME

Dokładne szczegóły na temat perspektyw sposób interpretuje pliki .ics są wyszczególnione w [MS-OXCICAL]: iCalendar to Appointment Object Conversion Algorithm

Użyjemy tych zespołów:

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

Dla DDay.iCal jej wystarczająco, aby pobrać DDay.iCal binary Files. Jeśli chcesz dodać niektóre funkcje, najlepiej przyjrzeć się źródłom DDay.iCal, ponieważ dokumentacja jest nieaktualna, a źródła zawierają całkiem kompletne testy, które wykorzystują wszystkie jej funkcje.

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 = "[email protected]"; 
string bodyPlainText = "This is the simple iCal plain text msg"; 
string bodyHtml = "This is the simple <b>iCal HTML message</b>"; 
string location = "Meeting room 101"; 
// 1: High 
// 5: Normal 
// 9: low 
int priority = 1; 
//===================================== 
MailMessage message = new MailMessage(); 

message.From = new MailAddress("[email protected]"); 
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<Event>(); 
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("[email protected]"); 
//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:[email protected]"); 
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); 

Tutaj ReadBinary() funkcja:

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; 
} 

Jego najłatwiej skonfigurować smtpclient w pliku konfiguracyjnym jak ten:

<configuration> 
    ... 
    <system.net> 
    <mailSettings> 
     <smtp> 
     <network host="mysmtp.server.com" port="25" userName="mySmtpUserName" password="myPassword" /> 
     </smtp> 
    </mailSettings> 
    </system.net> 
    ... 
+0

Dzięki za tak dokładną odpowiedź! Oszczędzi wiele prób i błędów –

Powiązane problemy