Item.Id.UniqueId is not unique - exchange-server

We have a service which syncs our calender with an exhange calender. In the synchronisation process we use the unique ids to identify the appointments. Now we have a customer, which has non-unique UniqueIds.
I used the EwsEditor (https://github.com/dseph/EwsEditor) to inspect the elements and yes, both appointments (same user, same month, same UniqueId, but a different appointment) have exact the same UniqueId.
Both appointments are not created with our software. They are manually created by the user via Outlook.
Is there a reason why the exchange creates appointments/meetings with the same Ids?

Are you saying that an Id has been reused (if so that's possible as it will still be unique). Or are you saying that you have two id's in the same calendar that are the same if so are you sure your not confusing recurring appointments or that fact that the UnqiueId's are base64 encoded so this means the Id's are case sensitive.
That said using the UniqueId for calendar appointment isn't a great idea and you would be better using the GOID property like PidLidCleanGlobalObjectId https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidlidcleanglobalobjectid-canonical-property

Related

Google Reports API for Meet attendance - strange conference_id

I'm trying to query attendance for a Google Meet conference created via Google Calendars API.
I've found that the conferenceId returned by Calendar API > Events > insert it's different from the one I can use to filter in Reports API.
conferenceId from Calendar API --> ["conferenceId"]=>string(12) "xxx-xxxx-xxx"
conferenceId from Reports API{"name": "conference_id", "value": "xxxxxxx_12234XXXXXxxxxXX56"}
Does anyone knows why?
How can I query attendance based on the data returned by Calendar API > Events > insert ?
Steps to reprocuduce:
Insert calendar events (be sure to add conferenceData structure to create also the Meet conference):
https://developers.google.com/calendar/api/v3/reference/events/insert
Use the conference
List activities from Report API and check the conference_id: https://developers.google.com/admin-sdk/reports/reference/rest/v1/activities/list
It seems that the conferenceId from the Calendar event object is different from the conference_id in the Reports (note that the name is different). The activities.list output also has another field called meeting_code, it's also under items.events.parameters:
{
"name": "meeting_code",
"value": "ASDFASFFGJ"
}
This one matches the conferenceId in a calendar event, except that it's without dashes and capitalized, so for the example "conferenceId": "asd-fasf-fgj" in a Calendar Event object you'll find "meeting_code": "ASDFASFFGJ" in the activity reports. So you can just remove the dashes and capitalize the conferenceId to match it to its corresponding meeting_code.
As to why this discrepancy exists, my guess after reading the definition of the Meet activity events is that it tracks different "conference sessions" within the same meeting code. For example, if you join the meeting asd-fasf-fgj it will create a new conference_id until everyone leaves the meeting. Then if the same meeting code is used again a different conference_id will be created to track the new session and so on.
I did some cursory testing and the logs do create a different conference_id every time I joined the same Meeting code. I didn't have multiple accounts to test so I'm not sure if two users can have matching IDs, but I may be close. I couldn't find any in-depth documentation so it would require more testing to figure out exactly how it works.
Either way, to address your immediate concern, you should be able to match the Event's conferenceId with the Report's meeting_code to track the attendance.
Reference:
Meet Activity log definition

Get unique ID before saving the meeting in Outlook that must be same after saving the meeting

I'm working on Outlook add-in, In which we are providing the service for ordering the catering products during the meeting scheduling.
I want to send the order along with the meeting (for which meeting i ordered the products) so in this case i need any id i.e MeetingId So can save this meetingId and order detail in the database.
When i will open scheduled meeting from my Outlook calendar and on the behalf of that meetingId i can get the order detail from the server and i can update the order.
So i'm looking any solution, Please share your suggestion here how can i update my order inside the Add-ins from already scheduled meeting.
On the compose form you may call the Office.context.mailbox.item.saveAsync method and then get the itemId property value. There is no need to call the saveAsync method if the appointment was saved previously.

Possible ways to optimize batch Outlook appointment processing with MAPITable

I'm working in a component that syncs our own appointment data with the ones in a selected calendar folder in Outlook.
The first time when our appointments sync to Outlook, the ID of our appointment is stored in the user properties of the newly created Outlook appointment.
Therefore, before syncing each appointment to Outlook, our code has to check if there is already an appointment in Outlook that has their ID. The code is currently looping through the Folder.Items collection and look into the UserProperties of each one of them, this is obviously very slow.
I found this stackoverflow question, which suggests that I can query the MAPITable to filter out appointments that has no user properties first.
However, as more and more appointments are synced to Outlook overtime, the filtered result would become pretty big too.
Does anybody know if there is any faster way to go through user properties of all appointments in an Outlook folde?
I had a similar problem of filtering Appointments using a UserProperty say 'MyUserProperty' of olText type. I used a DASL query which filtered the Folder Items using UserProperty.
string myPropertyValue = "SomeID";
filter = "#SQL=\"http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/MyUserProperty/0x0000001F\" = '" + myPropertyValue + "' ";
filteredAppointment = myFolderItems.Find(filter);
MSDN Documentation : Filtering a Custom Field
Use the Find/FindNext or Restrict methods of the Items class instead of integrating over all items in the folder.
Take a look at the following articles which illustrate how to use them:
How To: Retrieve Outlook calendar items using Find and FindNext methods
How To: Use Restrict method in Outlook to get calendar items

google calendar api: calendars vs calendarList

I was messing around trying to add a new calendar and it took me quite a while to figure out that I had to add it to 'Calendars' and not to 'CalendarList'. It works now, which is nice, but I what is the difference between the two concepts? It seems to me I only need Calendars? Also, CalendarList doesn't seem to work, trying to insert a Calendar returned a 404 error.
Calendars is a collection of all calendars in the world (it does not have a list method). When creating a new calendar, you should call an insert on the calendars collection. When you want calendar specific data (such as the timezone, the name) then you should retrieve a calendar from calendars collection using get.
CalendarLists is a collection of all calendar entries that a user added to their list (in the web UI it's the list of calendars in the left panel). You cannot create a new calendar through the calendar list collection but you can add an existing calendar to the list of your users calendars. Each user can for example have a different color for the same calendar and this detail will be stored in the calendar list entries.
What is sometimes confusing is that when you create a new calendar through calendars collection, it will be automatically added to your list.
Let me give you an example of how Calendars and CalendarLists work. Imagine your friend creates a calendar for a trip that you will be going on together. He does so by doing a Calendars.insert() call.
Now he makes the calendar public (via ACLs collection) and sends you and all the friends an email of this calendar. You can go into the CalendarLists collection and do an insert() call there to add it into your list of calendars and make it blue.
Calendars:
The Calendars collection represents all existing calendars. It can be
used to create and delete calendars. You can also retrieve or set
global properties shared across all users with access to a calendar.
For example, a calendar's title and default time zone are global
properties.
CalendarList:
The CalendarList is a collection of all calendar entries that a user
has added to their list (shown in the left panel of the web UI). You
can use it to add and remove existing calendars to/from the users’
list. You also use it to retrieve and set the values of user-specific
calendar properties, such as default reminders. Another example is
foreground color, since different users can have different colors set
for the same calendar.
Here the comparison table:
https://developers.google.com/google-apps/calendar/concepts/events-calendars

Outlook contact sync - How to identify the correct object to sync with?

I have a web application that syncs Outlook contacts to a database (and back) via CDO. The DB contains every contact only once (at least theoretically, of course doublets happen), providing a single point of change for a contact, regardless of how many users have that particular contact in Outlook (like Interaction or similar products).
The sync process is not automatic, but user-initialized. An arbitrary timespan can pass before users decide to sync their contacts. A subset of these contacts may have been updated by other users in the meantime.
Generally, this runs fine, but I have never been able to solve this fundamental problem:
How do I doubtlessly identify a contact object in a mailbox?
I can't rely on PR_ENTRYID, this
property changes on contact move or
mailbox move.
I can't rely on my own IDs (e.g. DB
table ID), because these get copied
with the contact.
I absolutely can't rely on fields
like name or e-mail address, they
are subject to changes and updates.
Currently I use a combination of 1 (preferred) and 2 (fall-back). But inevitably, sometimes users run into the problem of synching to the wrong contact because there is none with a given PR_ENTRYID, but two with the same DB ID, of which the wrong one is chosen.
There are a bunch of Outlook-synching products out there, so I guess the problem must be solvable.
I had a similar problem to overcome with an internal outlook plugin that does contact syncing. I ended up sticking a database id in the Outlook object and referring to that when doing syncs.
The difference here is that our system has a bunch of duplicates that get resolved later by the users. When they get merged I'll remove the old records and update outlook with all of the new information along with a new id.
You could do fuzzy matching to identify duplicates, but duplicate resolution is a funny problem that's mostly trial and error. We've been successful at implementing "fuzzy" matching logic using the levenshtein distance algorithm for names and addresses cleaned down to a hash code.
Good luck, my syncing experiences have been somewhat painful.

Resources