alfredapp / banner-be-gone-workflow

Close notification alerts
BSD 3-Clause "New" or "Revised" License
5 stars 1 forks source link

Slack notifications don't clear #3

Closed thanosd closed 4 months ago

thanosd commented 4 months ago

Workflow version

2024.1

Alfred version

5.5 2257

macOS version

Sonoma 14.5

Debugger output

[09:01:10.107] Banner Be Gone[Keyword] Processing complete
[09:01:10.121] Banner Be Gone[Keyword] Passing output '' to Run Script

More details

When I try to clear Slack notifications, instead of clearing them, I get the "reply to" option.

image

My guess is that "banner.perform()" does the default action somehow, which for Slack is reply. That said, I don't know enough about OSA Javascript to figure out what the right action is, but if you can point me in the right direction, I'd be happy to test and create a PR.

vitorgalvao commented 4 months ago

You’re quite right and this has been noticed before. The problem is the tradeoff isn’t worth it:

Due to the nature of the operation, the alternative would be to check all possible actions on every banner then perform on the one whose name indicates it closes the notification. However, that is considerably slower and it would require getting the names of the Close and Clear All operations in every language, which either requires configuration or becoming even slower. I spent a ton of time on that.

In other words, there’s always a trade-off. I picked the least annoying one. Maybe you can change Slack’s notification type to be different?

So, yeah, ideally I’d like to solve this but in practice it doesn’t seem feasible to have it (and not suck in other areas; AppleScript is quite slow). Ideally ideally, Apple would have some official API to dismiss all notifications, but alas that isn’t a thing.

thanosd commented 4 months ago

Thanks for the explanation, and I appreciate you not wanting to make this more complex. Just in case this is helpful for anyone else, I ended up solving it by changing it to this:

// Main
Application("System Events")
  .applicationProcesses.byName("NotificationCenter")
  .windows[0]
  .groups[0]
  .scrollAreas[0]
  .uiElements[0]
  .groups()
  .map(banner => { 
    const action = banner.actions().filter(action => action.name().includes("Clear All"));
    return action[0];
   })
  .forEach(banner => {banner.perform() })

Obviously "Clear All" works in my language, so that would need adapting... but did the trick.