Last active
November 14, 2016 22:26
-
-
Save ryancollingwood/0bec04df27b33c609a860e6c747212bb to your computer and use it in GitHub Desktop.
A Class Encapsulating The Microsoft Exchange 2007 Managed Api. Some methods are not available on Exchange Server 2007, particularly meeting rooms. Will require a reference to Microsoft.Exchange.WebServices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Microsoft.Exchange.WebServices.Data; | |
using System.Net; | |
namespace ExchangeConnector | |
{ | |
/// <summary> | |
/// <br>A Class Encapsulating The Microsoft Exchange Managed Api</br> | |
/// <br>Some methods are not available on Exchange Server 2007, particularly meeting rooms</br> | |
/// <br>Will require a reference to Microsoft.Exchange.WebServices</br> | |
/// </summary> | |
public class Connection | |
{ | |
private ExchangeService _exchangeService = new ExchangeService(ExchangeVersion.Exchange2007_SP1); | |
private String SMTPAddress = String.Empty; | |
public ExchangeService exchangeService | |
{ | |
get { return _exchangeService; } | |
} | |
/// <summary> | |
/// Connect To Exchange Server using User Impersonation | |
/// </summary> | |
/// <param name="UserName">String - Username Without Domain</param> | |
/// <param name="Password">String - User Password</param> | |
/// <param name="Domain">String - User Domain</param> | |
/// <param name="Email">String - User Email Address, used in finding the Exchange Server</param> | |
public Connection(String UserName, String Password, String Domain, String Email) | |
{ | |
this.SMTPAddress = Email; | |
_exchangeService.Credentials = new NetworkCredential(UserName, Password, Domain); | |
_exchangeService.AutodiscoverUrl(Email); | |
} | |
/// <summary> | |
/// Connect To Exchange Server as User | |
/// </summary> | |
/// <param name="Email">String - User Email Address Used In Discovery Of Exchange Server</param> | |
public Connection(String Email) | |
{ | |
this.SMTPAddress = Email; | |
_exchangeService.UseDefaultCredentials = true; | |
_exchangeService.AutodiscoverUrl(Email); | |
} | |
/// <summary> | |
/// Create A New Appointment | |
/// </summary> | |
/// <param name="Title">String - Appointment Title</param> | |
/// <param name="Body">String - Appointment Details</param> | |
/// <param name="Start">DateTime - Appointment Start</param> | |
/// <param name="End">DateTime - Appointment End</param> | |
/// <param name="IsAllDay">bool - All Day Event</param> | |
public void CreateAppointment(string Title, string Body, DateTime Start, DateTime End, bool IsAllDay) | |
{ | |
this.CreateAppointment(Title, Body, Start, End, IsAllDay, DateTime.MinValue, SendInvitationsMode.SendToNone, LegacyFreeBusyStatus.Free); | |
} | |
/// <summary> | |
/// Create A New Appointment | |
/// </summary> | |
/// <param name="Title">String - Appointment Title</param> | |
/// <param name="Body">String - Appointment Details</param> | |
/// <param name="Start">DateTime - Appointment Start</param> | |
/// <param name="End">DateTime - Appointment End</param> | |
/// <param name="IsAllDay">bool - All Day Event</param> | |
/// <param name="Reminder">DateTime - Appointment Reminder, if DateTime.Min no reminder is set</param> | |
/// <param name="SendInvitations">SendInvitationsMode - Send Invitations Mode</param> | |
/// <param name="FreeBusyStatus">LegacyFreeBusyStatus - Mark the time as Busy or Free in Calender. Set to LegacyFreeBusyStatus.Free for events such as sports seasons.</param> | |
/// <param name="Catagories">String[] - Catagories This Appointment Falls Under. If not in the Exchange master catagory list and not in the users catagory list, will appear without visual colour information</param> | |
/// <param name="RequiredAttendeesID">String[] - Unique IDs of Required Attendees</param> | |
/// <param name="OptionalAttendessID">String[] - Unique IDs of Optional Attendees</param> | |
public void CreateAppointment( | |
String Title, | |
String Body, | |
DateTime Start, | |
DateTime End, | |
bool IsAllDay, | |
DateTime Reminder, | |
SendInvitationsMode SendInvitations, | |
LegacyFreeBusyStatus FreeBusyStatus, | |
String[] Catagories = null, | |
String[] RequiredAttendeesID = null, | |
String[] OptionalAttendessID = null | |
) | |
{ | |
Appointment newAppointment = new Appointment(_exchangeService); | |
newAppointment.Subject = Title; | |
newAppointment.Body = Body; | |
newAppointment.IsAllDayEvent = IsAllDay; | |
newAppointment.Start = Start; | |
newAppointment.End = End; | |
if (Reminder == DateTime.MinValue) | |
{ | |
newAppointment.IsReminderSet = false; | |
} | |
else | |
{ | |
newAppointment.IsReminderSet = true; | |
newAppointment.ReminderDueBy = Reminder; | |
} | |
AddContactAddress(newAppointment, RequiredAttendeesID, true); | |
AddContactAddress(newAppointment, OptionalAttendessID, false); | |
foreach (String sCat in Catagories) | |
{ | |
newAppointment.Categories.Add(sCat); | |
} | |
newAppointment.LegacyFreeBusyStatus = FreeBusyStatus; | |
newAppointment.Save(SendInvitations); | |
} | |
/// <summary> | |
/// Delete An Appointment | |
/// </summary> | |
/// <param name="ID">String - Unique ID of Appointment</param> | |
/// <param name="SendCancellations">bool - Send Cancellations or Stealthy Delete</param> | |
public void DeleteAppointment(string ID, bool SendCancellations) | |
{ | |
Appointment appDelete = Appointment.Bind(_exchangeService, new ItemId(ID)); | |
if (appDelete == null) | |
{ | |
return; | |
} | |
appDelete.Delete(DeleteMode.MoveToDeletedItems, SendCancellationsMode.SendOnlyToAll); | |
} | |
/// <summary> | |
/// Add Attnedess To An Appointment | |
/// </summary> | |
/// <param name="Appointment">Appointment - Instance to be updated</param> | |
/// <param name="Addresses">String[] - Array of Contact/Contact Group Unique IDs</param> | |
/// <param name="IsRequired">bool - Required or Optional Attendees</param> | |
private void AddContactAddress(Appointment Appointment, String[] Addresses, bool IsRequired) | |
{ | |
if (Addresses != null) | |
{ | |
foreach (String item in Addresses) | |
{ | |
var con = Item.Bind(_exchangeService, item); | |
if (con.GetType() == typeof(ContactGroup)) | |
{ | |
AddContactGroupAddress(Appointment, item, IsRequired); | |
continue; | |
} | |
EmailAddress conEmail = new EmailAddress(); | |
if (((Contact)con).EmailAddresses.TryGetValue(EmailAddressKey.EmailAddress1, out conEmail)) | |
{ | |
if (IsRequired) | |
{ | |
Appointment.RequiredAttendees.Add(conEmail.Address); | |
} | |
else | |
{ | |
Appointment.OptionalAttendees.Add(conEmail.Address); | |
} | |
} | |
} | |
} | |
} | |
/// <summary> | |
/// Add members of Contact Group To An Appointment | |
/// </summary> | |
/// <param name="Appointment">Appointment - Appointment </param> | |
/// <param name="GroupID">String - Unique identity of the contact group</param> | |
/// <param name="IsRequired">Boolean - Required or Optional Attendee</param> | |
private void AddContactGroupAddress(Appointment Appointment, String GroupID, bool IsRequired) | |
{ | |
ContactGroup con = ContactGroup.Bind(_exchangeService, GroupID); | |
// GroupMember Functions Only Implement in Exchange Server > 2007 | |
if (_exchangeService.RequestedServerVersion == ExchangeVersion.Exchange2007_SP1) | |
{ | |
ExpandGroupResults groupResults = _exchangeService.ExpandGroup(con.Id); | |
foreach (var member in groupResults) | |
{ | |
if (IsRequired) | |
{ | |
Appointment.RequiredAttendees.Add(member.Address); | |
} | |
else | |
{ | |
Appointment.OptionalAttendees.Add(member.Address); | |
} | |
} | |
} | |
else | |
{ | |
foreach (GroupMember itemGroupMember in con.Members) | |
{ | |
if (IsRequired) | |
{ | |
Appointment.RequiredAttendees.Add(itemGroupMember.AddressInformation.Address); | |
} | |
else | |
{ | |
Appointment.OptionalAttendees.Add(itemGroupMember.AddressInformation.Address); | |
} | |
} | |
} | |
} | |
/// <summary> | |
/// Return Appointments In The Exchange Calendar | |
/// </summary> | |
/// <param name="AStart">DateTime - Start Date For Matching Appointments</param> | |
/// <param name="AEnd">DateTime - End Date For Matching Appointments</param> | |
/// <returns></returns> | |
public FindItemsResults<Appointment> FindAppointments(DateTime AStart, DateTime AEnd) | |
{ | |
CalendarView calendarView = new CalendarView(AStart, AEnd); | |
return _exchangeService.FindAppointments(WellKnownFolderName.Calendar, calendarView); | |
} | |
/// <summary> | |
/// Return an Appointment By Unique ID | |
/// </summary> | |
/// <param name="ID">String - Appoint Unique ID</param> | |
/// <returns></returns> | |
public Appointment GetAppointmentByID(String ID) | |
{ | |
Appointment current = Appointment.Bind(_exchangeService, ID); | |
return current; | |
} | |
/// <summary> | |
/// Gets the object id string from uid. | |
/// <remarks>The UID is formatted as a hex-string and the GlobalObjectId is displayed as a Base64 string.</remarks> | |
/// </summary> | |
/// <param name="id">The uid.</param> | |
/// <returns></returns> | |
private String GetObjectIdStringFromUid(String id) | |
{ | |
var buffer = new byte[id.Length / 2]; | |
for (int i = 0; i < id.Length / 2; i++) | |
{ | |
var hexValue = byte.Parse(id.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier); | |
buffer[i] = hexValue; | |
} | |
return Convert.ToBase64String(buffer); | |
} | |
/// <summary> | |
/// Find Exchange Contacts In User Address Book | |
/// </summary> | |
/// <param name="Search">String - Substring To Match Display Name On</param> | |
/// <returns></returns> | |
public FindItemsResults<Item> FindPeople(String Search) | |
{ | |
ItemView result = new ItemView(100) { PropertySet = new PropertySet(BasePropertySet.FirstClassProperties) }; | |
SearchFilter FinalsearchFilter = new SearchFilter.ContainsSubstring(ContactSchema.DisplayName, Search); | |
return this._exchangeService.FindItems(WellKnownFolderName.Contacts, FinalsearchFilter, result); | |
} | |
/// <summary> | |
/// Return (maximum 1000) Contacts In Exchange Address Book | |
/// </summary> | |
/// <returns></returns> | |
public FindItemsResults<Item> GetContacts() | |
{ | |
ItemView result = new ItemView(1000) { PropertySet = new PropertySet(BasePropertySet.FirstClassProperties) }; | |
SearchFilter FinalsearchFilter = new SearchFilter.Exists(ContactSchema.DisplayName); | |
return this._exchangeService.FindItems(WellKnownFolderName.Contacts, FinalsearchFilter, result); | |
} | |
// RYCOL: Presently unable to enumerate delegate access via Exchange Webservices Due to Configuration | |
// issue with Exchange 2007 :/ | |
/* | |
/// <summary> | |
/// Does the passed email account have delegate access to the Current Exchange Account | |
/// </summary> | |
/// <param name="EmailAddress"></param> | |
/// <returns></returns> | |
public bool AllowedAccess(String EmailAddress) | |
{ | |
UserId passedUser = new UserId(EmailAddress); | |
Mailbox mail = new Mailbox(this.SMTPAddress); | |
DelegateInformation delegates = _exchangeService.GetDelegates(mail, true); | |
foreach (DelegateUserResponse item in delegates.DelegateUserResponses) | |
{ | |
if (item.DelegateUser.UserId.SID == passedUser.SID) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
*/ | |
/// <summary> | |
/// Finds the related appiontment. | |
/// </summary> | |
/// <param name="apptRequest">The appt request.</param> | |
/// <returns></returns> | |
private Appointment FindRelatedAppiontment(Appointment apptRequest) | |
{ | |
var filter = new SearchFilter.IsEqualTo | |
{ | |
PropertyDefinition = new ExtendedPropertyDefinition | |
(DefaultExtendedPropertySet.Meeting, 0x03, MapiPropertyType.Binary), | |
Value = GetObjectIdStringFromUid(apptRequest.ICalUid) //Hex value converted to byte and base64 encoded | |
}; | |
var view = new ItemView(1) { PropertySet = new PropertySet(BasePropertySet.FirstClassProperties) }; | |
return _exchangeService.FindItems(WellKnownFolderName.Calendar, filter, view).Items[0] as Appointment; | |
} | |
/// <summary> | |
/// Returns Master Category List | |
/// </summary> | |
/// <remarks>Only Works In Exchange Server 2010</remarks> | |
/// <returns></returns> | |
public MasterCategoryList.MasterCategoryList MasterCategoryList() | |
{ | |
return ExchangeConnector.MasterCategoryList.MasterCategoryList.Bind(_exchangeService); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For interacting with a Microsoft Exchange Server 2007
It's a little late, but at this point if you're still in 2007 land, you're more than welcome to my code 👍