HCAWN / gcal-multical-event-merge

Browser extension that visually merges the same event on multiple Google Calendars into one event.
GNU General Public License v3.0
26 stars 5 forks source link

Allow custom callback for "merge-ability" between events #8

Closed michaelblyons closed 10 months ago

michaelblyons commented 2 years ago

This is maybe a stretch, but one of the issues on Amy's repo asked for some merge-ability criteria beyond just "name = name." I have no idea how much work it would be to let the user write a custom function to return true or false for an arbitrary pair of events (or an arbitrary pair of events that exactly coincide or whatever).

I also do not know how much use it would get.

HCAWN commented 2 years ago

I would imagine this to be quite a "power user" feature. Do you have an example for the criteria a user might want to create custom matches on? I could see having a more robust matching system be more useful such as Event A called "OOO" and Event B called "Out of Office" merge as they are the same thing. In that case I would hardcode the matcher to also match on acronyms. Anything more complex and it starts to be a fun natural language processing problem but perhaps I'm missing a trick with your suggestion?

H

michaelblyons commented 2 years ago

Yeah, I don't know if I'd dare use it. 😛 This was taken from https://github.com/imightbeamy/gcal-multical-event-merge/issues/16

aspiers commented 1 year ago

Hi folks, this not yet implemented feature is probably exactly what I'm looking for!

I have authorized my personal calendar access to my work calendars, so I always look at my personal calendar for a complete view of all my commitments.

I've just started using https://reclaim.ai, which syncs events from my personal calendar to my two work calendars, so that my teams never double-book me at times where I already have personal commitments. To maintain the privacy of my personal commitments, these events get synced with titles like "Work Commitment", and with descriptions like:

This event was created by Reclaim. Adam has a work commitment and is busy at this time. Please find another time to avoid scheduling conflicts.

As a result, my personal calendar now shows 2 duplicates for all personal commitments:

Their website provides a support page suggesting several workarounds for this problem, but none of them are good solutions which solve the problem directly within the Google Calendar web UI :-(

So what I would love is for this extension / userscript to spot that events created by reclaim.ai are actually duplicates of the source event, and merge them together, using the details from the original event. Since the logic is somewhat dependent on my particular setup, a custom callback would be ideal.

I expect probably neither of you will have time to contribute towards implementing this callback feature. However I'm an experienced Javascript hacker, so I should be able to hack this myself. All I need is some pointers on which bits of the existing code (I assume it's events.user.js) I would need to modify / extend. Is there any chance either of you could provide some hints on that?

Initially I could hardcode the logic within events.user.js, and then later extract it out into a custom callback. Any thoughts on how the UI / UX for configuring this custom callback might eventually look would also be welcome.

Thanks!

aspiers commented 1 year ago

Hrm, I think I maybe answered my own question already; the event matching seems to be done on these lines:

https://github.com/HCAWN/gcal-multical-event-merge/blob/c124ffaafddb4b009762fa37ba68d8fc75c51aee/events.user.js?rgh-link-date=2022-10-30T18%3A35%3A10Z#L214-L215

HCAWN commented 1 year ago

@aspiers happy to help you help me for sure! What you've found is indeed part of the code that identifies the criteria for matching events. Conceptually I would imagine that there could be a few toggles that set the logical flow for how events are matched but without thinking about it too much can't be sure how to implement a simple UI that allows users to do something like:

But since starting somewhere is better than nowhere... I would imagine a good universal start to this would be a toggle to change from simple text matching to RegEx String.prototype.match() ?

This merging happens via the UI, so event merging can only happen based on whatever elements are rendered on the screen. From what you've described, all your duplicate events are all titled "This event was created by Reclaim" so perhaps your matching criteria would be in psudocode: match on text or if text === 'This event was created by Reclaim' then ignore text matching criteria and only focus on event time.

Could you share a screenshot of an example event of yours out of curosity?

H

aspiers commented 1 year ago

@HCAWN commented on November 8, 2022 10:24 PM:

@aspiers happy to help you help me for sure! What you've found is indeed part of the code that identifies the criteria for matching events.
Conceptually I would imagine that there could be a few toggles that set the logical flow for how events are matched but without thinking about it too much can't be sure how to implement a simple UI that allows users to do something like:

  • "match events as usual. Unless the title matches this RegEx then match then ignore the duration of the event (as my imported calendar adds 15 minutes to the start of events for travel time)"

Yeah I agree, it feels like it would be tricky to provide a UI which offers matching logic generic and flexible enough to allow this kind of thing.

But since starting somewhere is better than nowhere... I would imagine a good universal start to this would be a toggle to change from simple text matching to RegEx String.prototype.match() ?

Well currently the matching happens simply by choosing the mechanism for how to construct the key used as the index, rather than any text matching, so I think it would be more a question of making this key construction configurable.

This merging happens via the UI, so event merging can only happen based on whatever elements are rendered on the screen. From what you've described, all your duplicate events are all titled "This event was created by Reclaim" so perhaps your matching criteria would be in psudocode: match on text or if text === 'This event was created by Reclaim' then ignore text matching criteria and only focus on event time.

Yes exactly! Something along these lines would be needed, but I can't immediately see how that would be compatible with the current approach of constructing a key used to index groups of matching events.

Could you share a screenshot of an example event of yours out of curosity?

Which bit(s) / views would you like to see?

HCAWN commented 11 months ago

https://github.com/HCAWN/gcal-multical-event-merge/pull/24 in review on Chrome Web Store now

A starting point for something like this I believe. I'm keen to not make there be too many options unless there is real demand but without putting much effort into the ui a simple wildcard can probably help most out. I may look to make the textfield regex compatible at least as that is how I do the matching if that field is filled.

Unfortunately, the method for merging events means that if an event with the wildcard is "checked" before an event that it could match with, the match won't be made, for now the events populate time chronologically so it seems okay but if you have a "busy" event in your primary cal and the event it could match with in a secondary then they might not.

I will look into making the matching more robust even with a simple wildcard value but will see how this goes for now.

H

aspiers commented 10 months ago

@HCAWN The current wildcard functionality is tantalisingly close to being useful for me, but unless it's a regex I won't be able to use it, because there are multiple possible values which need to be merged. Any chance of upgrading it from a fixed string to a regex? I doubt that would break backwards-compatibility for (m)any users, but if you were worried about that I guess an extra checkbox enabling regex matching would address that concern.

HCAWN commented 10 months ago

Can you give me an example of a regex string you think you might use and a name of two events you'd want it to match and I'll have a go :) H

aspiers commented 10 months ago
aspiers commented 10 months ago

Looking at the code: https://github.com/HCAWN/gcal-multical-event-merge/blob/c65eb91a9ea455e2a069dac6b0f0b064de1f547e/events.user.js#L213-L225

it seems to me that it's probably as simple as dropping lines 214 and 215 and just directly matching against the regexp provided by the user.

HCAWN commented 10 months ago

Close but not quite that simple. The logic as it is enforces key matching with wildcards still requires time/dates to match. I've been playing and found I need another setting to get this working. Currently the wildcard allows matching events to merge with non-matching events that are at the same time. This image shows what this toggle can do differently: image I'll need to clean up the UI with explainers and also clean the code as it's a bit of a mess but I'll have it live soon

aspiers commented 10 months ago

Looks fantastic! That should work perfectly for me. I realise I probably didn't explain my use case well enough - the behaviour I want is the one with the "match all" checkbox enabled. Here's a couple of concrete examples:

  1. I enter a personal commitment in my personal Google Calendar. reclaim.ai then automatically syncs it over to one of my work calendars, but changing the name to "Personal Commitment" to allow work colleagues to see it whilst maintaining privacy. So the dates and times will match perfectly, but the two event names don't.

  2. Similarly to the above, but this time I enter a work commitment in one of my (multiple) work calendars. From there reclaim.ai automatically syncs it to another work calendar, renaming it to "Work Commitment".

From an event matching perspective, this second example is an identical scenario to the first example above, i.e. the same code would work perfectly for both. The only reason for giving both is to highlight that the duplicated event will have a different name depending on the scenario (either "Personal Commitment" or "Work Commitment"). But in both cases I want the duplicated event to be merged with the source event which it was duplicated from.

HCAWN commented 10 months ago

https://github.com/HCAWN/gcal-multical-event-merge/pull/26

Live now V 2.3.6

Closing ticket as I believe this is a nice starting point. If there are more specific questions or implementation on this please open a new ticket.

michaelblyons commented 10 months ago

Closing ticket as I believe this is a nice starting point. If there are more specific questions or implementation on this please open a new ticket.

Great work. I suspect this will cover most normal use cases. If you want to, you or I could go update https://github.com/imightbeamy/gcal-multical-event-merge/issues/16 and report that your fork supports regex matches for generically titled events.

aspiers commented 10 months ago

I have tested this and realised that unfortunately it won't work for me due to other differences in the way the eventKey strings end up being calculated for the duplicate events. I am experimenting with some changes in my own fork and will report back if I make progress.