Creating appointments on other calendars, shared with me, using EWS API - c#

I hope this is the right forum to ask this question.
My requirement is as mentioned below:
-> I need to create an appointment on my Default calendar and the same on other calendars that are shared with me (or created by me and shared with others) by using Exchange Services (EWS).
-> By shared, i mean all those calendars that I can see under my 'Other Calendars' group in Office 365.
-> Now, I have reffered many links which help to create appointments on my mailbox, default Calendar. This part works fine(Link : (http://technico.qnownow.com/how-to-create-appointment-using-ews-exchange-web-services/)
-> Then I moved on to access shared calendars so that I can create the same appointment on them.
Used this : EWS - Access All Shared Calendars
-> However I do not get the PidTagWlinkAddressBookEID property in any of the items fetched.
The code works fine till I get the fiResults collection.
I get names of all the calendars under Other Calendars section in this collection.
The problem is when I iterate over this collection (as you can see in the code) , i am trying to get the PidTagWlinkAddressBookEID property value in each item and its not present in the item.
And this is the reason I am not able to retrieve the FolderID at the end.
But i tried number of ways to do it since i get the collection of items and I can see my shared calendars' names in those items.
Since i created the shared calendars, I tried to use my mailbox address at the end in this part of the code :
FolderId SharedCalendarId = new FolderId(WellKnownFolderName.Calendar, ncCol[0].Mailbox.Address);
However the calendar retrieved in this case is the default calendar with displayName as Calendar.
Since each item in the itemcollection ( fiResults collection) represents the corresponding shared calendar
Please let me know if we can use any property in the Item class to create an appointment.
I tried one more approach to create appointments on shared calendars:
First i tried to access all the calendar folders by using:
private void ViewCalendarFolders(string mailBox)
{
ExtendedPropertyDefinition PR_Folder_Path = new ExtendedPropertyDefinition(26293, MapiPropertyType.String);
PropertySet psPropSet = new PropertySet(BasePropertySet.FirstClassProperties);
psPropSet.Add(PR_Folder_Path);
FolderId rfRootFolderid = new FolderId(WellKnownFolderName.Root, mailBox);
FolderView fvFolderView = new FolderView(1000);
fvFolderView.Traversal = FolderTraversal.Deep;
fvFolderView.PropertySet = psPropSet;
SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.FolderClass, "IPF.Appointment");
FindFoldersResults ffoldres = exchangeService.FindFolders(rfRootFolderid, sfSearchFilter, fvFolderView);
var res = ffoldres.Where(f => f is CalendarFolder).ToList();
if (res.Any())
{
foreach (Folder fld in res)
{
Console.WriteLine(fld.DisplayName);
}
}
}
Then I tried to create appointments on the CalendarFolders fetched.
I succeeded in creating appointments on two calendars:
1) My default calendar
2) The calendar which I have created and shared with others.
the piece of code shown above fetches all the calendar folders except those which are created by other users and shared with me. (Even though I can see them under the Other Calendars section in office 365 and can even create appointments on them through UI i.e. manually)
Kindly let me know how to create appointments on such calendars which are shared by others with me.
Note: I have Editor rights on these type of calendars
Thanks

Related

Get user defined categories from Shared Mailbox in Outlook C#

I am working on Outlook add-in which would pull the list of pre-defined categories from shared mailbox. User then assign each email from shared mailbox to those categories.
My issue is I can get access to all categories linked to account using
Outlook.Application application = new Outlook.Application();
Outlook.Categories categories = application.Session.Categories;
but can't find a way to get categories linked to shared mailbox.
Is there any way to get shared mailbox categories?
If not, how would I deal with this scenario, so later on I can create view based on those categories.
Thank you in advance.
Categories are stored in a hidden message with the message class of "IPM.Configuration.CategoryList" in the store's Calendar folder. You can see it in OutlookSpy if you go to the shared Calendar folder and click the IMAPIFolder button, then go to the "Associated Contents" tab.
That hidden message can be accessed using MAPIFolder.GetStorage in the Outlook Object Model.
You can also access the Categories collection in Redemption (I ma its author) using RDOCategories collection. Redemption exposes categories both on the session level (RDOSession.Categories from the default store) and on the store level (RDOStore2.Categories). A shared mailbox can be opened using RDOSession.GetSharedMailbox.
Following is the code to get Categories of selected folder.
public void LoadCategories()
{
CategoriesCombo.Items.Clear();
Outlook.Application application = new Outlook.Application();
Outlook.NameSpace ns = application.GetNamespace("MAPI");
Outlook.MAPIFolder selectedFolder = application.ActiveExplorer().CurrentFolder;
if (selectedFolder is Outlook.MAPIFolder)
{
Outlook.Folder folder = selectedFolder as Outlook.Folder;
Outlook.Store store = folder.Store;
Outlook.Categories categories = store.Categories;
}
}
If someone has better answer, I would look forward to see it.

Using Microsoft's EWS to create online Lync/Skype meeting

Anybody knows how to create meeting request with online conference(Lync/Skype) using EWS?
So my approach is first getting an online and regular meeting created via Outlook and then simulate the creation of event with the same property.
Here is my code snippet for getting the meeting (calendarView is already initialized with start date, end date etc.):
ExtendedPropertyDefinition extendedOnlineMeetingProperty =
new ExtendedPropertyDefinition(new Guid("{00062008-0000-0000-c000-000000000046}"), 34112,
MapiPropertyType.Integer);
var properties = new PropertySet(
ItemSchema.Id,
AppointmentSchema.ICalUid,
ItemSchema.Subject,
AppointmentSchema.Start,
AppointmentSchema.End,
AppointmentSchema.Organizer,
AppointmentSchema.Location,
AppointmentSchema.LegacyFreeBusyStatus,
AppointmentSchema.IsCancelled,
AppointmentSchema.ICalRecurrenceId,
AppointmentSchema.MyResponseType, // Mandatory Meeting.MyResponseType can be retrieved without a search in the participant list
ItemSchema.LastModifiedTime,
AppointmentSchema.IsOnlineMeeting,
AppointmentSchema.IsMeeting,
ItemSchema.DisplayTo) { };
properties.Add(extendedOnlineMeetingProperty);
var activeResults = service.FindAppointments(WellKnownFolderName.Calendar, calendarView).ToList();
if (activeResults.Count > 0)
{
service.LoadPropertiesForItems(activeResults, properties);
}
I got the property IsOnlineMeeting with the correct bool value (tested -
created online and regular meeting with Outlook) in variable activeResults but I do not understand where to get conference link and other Lync/Skype properties needed for joining a conference.
Also I am not sure where and how to assign the values of Lync/Skype conference URL and other properties.
Sometimes I ask myself if it's worth it to developed some app based on MS products since their documentation suck.
After one week of cursing MS I have found a solution. Using the tool MFCMAPI you can check what property and their values your item in mailbox have.
download the program link
build and run it
Session - Logon - choose your mail profile - pick the mailbox and double click
actions - open special folder - calendar - double click on calendar
open the item with online S4B/Lync conference
the UC* properties are the one I was looking for.
If you open the property you can see something like this on the top:
ag: 0x8096001E
Type: PT_STRING8
DASL: http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/UCMeetingSetting
Named Prop Name: UCMeetingSetting
Named Prop Guid: {00020329-0000-0000-C000-000000000046} = PS_PUBLIC_STRINGS
So my definition of the extended property was wrong. It is not only one property but actually you need all 7 of them.
So the definition should be:
private static ExtendedPropertyDefinition CreateOnlineMeetingProperty()
{
ExtendedPropertyDefinition extendedUCMeetingSetting =
new ExtendedPropertyDefinition(new Guid("{00020329-0000-0000-C000-000000000046}"), "UCMeetingSetting",
MapiPropertyType.String);
return extendedUCMeetingSetting;
}
With the correct extended definition you can get the values from the item easily.
accessing the Value of ExtendedProperties
Calling TryGetProperty
var activeResults = service.FindAppointments(new
FolderId(WellKnownFolderName.Calendar, resource.Email),calendarView).ToList();
service.LoadPropertiesForItems(activeResults, properties);
foreach (Appointment result in activeResults)
{
// 1.
var b = result.ExtendedProperties[1].Value;
// 2.
string UCMeetingSetting;
result.TryGetProperty(extendedUCMeetingSetting, out UCMeetingSetting);
}
using steps above you can get whatever extended property you want, not only Unified Communications (UC) properties.
Ok, I managed to have this working (almost!) by setting just one of the extended properties:
appointment.SetExtendedProperty(
new ExtendedPropertyDefinition(
new Guid("00020329-0000-0000-C000-000000000046"),
"OnlineMeetingExternalLink",
MapiPropertyType.String
),
skypeMeeting.JoinUrl
);
I say almost because the appointment doesn't look exactly like a Skype meeting when you open it in Outlook: doesn't have the footer will the Join link and phone number etc.
Maybe there are other differences, but for now we see it in Skype for business with the Join button and also we see the it in the Outlook reminder with the Join button.
As a workaround, we have to hard-code the body content of the appointment.
Also conference ID, can be taken using UCWA 2.0 (https://learn.microsoft.com/en-us/skype-sdk/ucwa/myonlinemeetings_ref)
We used UCWA 2.0 to create the Skype conference call and attached it to the EWS appointment object.

Access Public String MAPI Properties through EWS

I've created custom properties in an Appointment in Outlook through JavaScript in an App for Outlook, which have saved successfully. I have checked the MAPI properties of this appointment and I can see the property as a JSON dictionary.
MFCMAPI display of the stored property:
I'm now trying to retrieve this through EWS in a C# application. For troubleshooting purposes, I also attempt to retrieve another property, with the ID of 33336.
ExtendedPropertyDefinition epd = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "cecp-propertyNames", MapiPropertyType.String);
ExtendedPropertyDefinition epd2 = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Appointment, 33336, MapiPropertyType.String);
//Create our sync window. This is the period of appointments it will capture and sync
CalendarView cv = new CalendarView(START_DATE_SYNC, END_DATE_SYNC);
cv.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties, epd, epd2);
FolderId calendarFolderId = new FolderId(WellKnownFolderName.Calendar, room.Address);
FindItemsResults<Appointment> fappts = service.FindAppointments(calendarFolderId, cv);
Exchange returns the appropriate appointment items, but when accessing the extended properties, only the property with the ID of 33336 (the test one) is returned. Any time I try and retrieve a PS_PUBLIC_STRINGS item, nothing comes back.
Your imgur link is frustratingly cropped. I cannot see the named property guid column to check if it matches what you're trying there in the EWS code. So I can only guess that I think you've got the wrong property set.
Have you tried looking at the item with EWS Editor to see if it finds the property you're looking for naturally? If it does, you can read off the details you need to construct your EWS code.

How to use Microsoft Exchange Web Services to retrieve meeting form other contacts in the same domain?

I would like to retrieve calender items from Outlook 2010. Currently I could only retrieve items from my own calender by following this tutorial. But I want to get meeting from my colleagues calender. I have tried many option so far but nothing is working. Could you please show me how to use these api to get all calender meeting from the same exchange server? Thanks in advance!
Well, there is no answer within 2 days. Meanwhile I found a way to access others calender. I want to share my solution so that other can get a helsp:-
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.Credentials = new WebCredentials();
Mailbox principle = new Mailbox("usedr#domain.com");
CalendarFolder calendar2 = CalendarFolder.Bind(service, new FolderId(WellKnownFolderName.Calendar, principle), new PropertySet());
// Retrieve a collection of appointments by using the calendar view.
FindItemsResults<Appointment> appointments2 = calendar2.FindAppointments(cView2);
appointments2 should have all the calender meeting.

Accessing a Resource Calendar with no mailbox via EWS and C#

Our Exchange Admins (Exchange 2010 SP1) have setup a shared resource calendar. There is no mailbox assigned to this resource calendar. I want to be able to read the meetings using EWS and C#.
Snippet:
ExchangeService esvc = new ExchangeService(ExchangeVersion.Exchange2010);
esvc.Credentials = new WebCredentials(username, password, "ourplace.org");
esvc.Url = new Uri("https://OWA.OURPLACE.ORG/EWS/Exchange.asmx");
FolderId shareFolderId = new FolderId(WellKnownFolderName.Calendar, "Shared Calendar Name");
CalendarFolder.Bind(esvc, shareFolderId);
the bind statement throws the error: "The SMTP address has no mailbox associated with it."
How can I read the items on a Share Resource Calendar that has no associated mailbox... or is it even possible?
Thanks !!
Bind to that Calendar with a mail-Adress
Create first of all a FolderId:
FolderId parkplatzCalendarId = new FolderId(WellKnownFolderName.Calendar,"de.calendar.name#company.com");
Then bind to this one:
CalendarFolder calendar = CalendarFolder.Bind(_service, parkplatzCalendarId);
Now you can use this calendar!
CalendarView cView = new CalendarView(start, end, int.MaxValue);
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Duration, AppointmentSchema.LastModifiedName, AppointmentSchema.Organizer, AppointmentSchema.Categories);
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);
With something like that ;D
If the calendar is actually not in any particular mailbox, then it should be in a public folder, and you should look in a subfolder WellKnownFolderName.PublicFoldersRoot.
Otherwise, please tell where exactly does it appear in Outlook folders hierarchy.

Categories