Skip to content

Added java Actions JA_Notify_List and JA_Notify_Specific#8

Open
bsgriggs wants to merge 2 commits into
nathan-JJRplus:mainfrom
bsgriggs:main
Open

Added java Actions JA_Notify_List and JA_Notify_Specific#8
bsgriggs wants to merge 2 commits into
nathan-JJRplus:mainfrom
bsgriggs:main

Conversation

@bsgriggs

Copy link
Copy Markdown

Use-Case

I wanted to use a single, global web socket to send In-App notifications to specific users. e.g. When user X tags user Y in a comment, user Y gest a message through the global web socket (with the widget in the layout) no matter where they are in the app.

This can be done with existing logic, but requires every client of the web socket to check if the message is relevant to them. Which the easiest method for this being the sending of username(s) in the web socket data and then every client checking if they're in the list.

In Mendix

I added a dropdown to Account where the user can select the recipient(s).
Screenshot 2025-03-24 at 10 58 05 AM
In the send Microflow, I split based on the selection:
Screenshot 2025-03-24 at 10 59 07 AM.

I thought the easiest way to do this was to have Java handle it. I wanted to make separate Java actions for compatibility with existing apps and ease of use. The dev can pass either a User object to JA_Notify_Specific or a list of User objects to JA_Notify_List. You could have only 1 notify action with an optional User List, but then the user has to create a list in the Microflow if they only want to notify a single Account.

Java

I added a private User variable to SessionWrapper that compares the variable with the list passed into the Java action. If the list is empty, it does the existing logic of notifying everyone.
Screenshot 2025-03-24 at 11 02 36 AM

Purpose of PR

This PR is more of a proof-of-concept than a direct merge.

There are cleaner ways of implementing this in SessionManager, but I'll leave that to you. Namely:

  • SessionManager -> subscriptions doesn't really make sense if I need to also reconcile a list of Users
  • The Session Xpath and the User Xpath can be combined so the user is retrieved by association from the session found

@nathan-JJRplus

Copy link
Copy Markdown
Owner

Hi Benjamin, thanks for helping me improve this module!

I've checked out your PR, and I do think your idea is valid, but I also think that this can be solved within the current implementation

afbeelding

I quickly created the above diagram to help me explain my point
The notify action contains 3 pieces of info

  • The websocket server
  • The objectId
  • The action to perform

Maybe my terminology is a bit confusing, as ObjectId is more of a SubscriptionId than anything

The notify action uses the objectId to see which group of subscribers it has to notify

You can make this ObjectId anything you'd like. You can even hardcode some string

Instead of adding the logic of notifying specific users, you can instead have every user subscribe to ObjectId of their own username for example

afbeelding

And place this in your layout:

afbeelding

Within your notification flow you can then loop through the list of usernames you want to notify (if there are multiple)
Technically this could be optimized by passing a list, but as there is no communication to the DB I think the performance gain would be very minimal

afbeelding

This can all be done on a single websocket server, your session structure would look like this:

afbeelding

If you know that this will always be a group of users, you could also subscribe specific users to a groupname based on configuration or taking their userrole as a string, or if you want to send something to all users logged in to the app, you could subscribe all of them to 'global' or something similar

I would love to hear your thoughts!

@bsgriggs

Copy link
Copy Markdown
Author

Hmm, I do see that would work. I think you nailed it with me getting confused about what 'ObjectId' means.

I was thinking of the object ID as sort of a "sub-web socket". In that approach, a username as the object ID didn't make immediate sense because there would only ever be 1 in the "sub-web socket".

I still think having the additional Java action(s) or an optional list would be helpful. As an example, the user is editing Request #3. The web socket would be WebSocket "Request" / Object id "3". Then what if the server needs to notify only people with the Engineering user role? I suppose that I could make another object id "3_Engineering" or "3_{Username}". Then I need the widget on the page for every possible group and all the groups have to be decided at design time. Having the option would make the module more flexible and intuitive. The user list could be populated with a Microflow or even if the user needs to select people to notify (like a chatroom whisper).

@nathan-JJRplus

Copy link
Copy Markdown
Owner

Glad I could clear that up, the objectId is really more like a "folder" of clients as it were.

I agree that being able to cherrypick clients dynamically could potentially be interesting. I have some ideas about the implementation too 😄

Ill brainstorm a bit more and share my solution tomorrow!

@nathan-JJRplus

Copy link
Copy Markdown
Owner

How about the following:

  • Instead of each subscription belonging to only 1 "objectId", we can introduce "client properties"
  • The notify action now takes a query instead of an objectId

To ensure backwards compatibility, I think we can keep the objectId field as a string, and accept semicolon-separated properties
The notify query handler can be as simple as accepting and-clauses, or-clauses and brackets

Heres a diagram cause I like those:

afbeelding

What do you think?

@bsgriggs

Copy link
Copy Markdown
Author

I'm not sure I understand the second half of the image. But would it be more like a tag system where:

  1. The widget would register each client with a list of tags
  2. The notify Java action would allow you to specify which tag(s)

We would also need to test what the widget does if the Object Id changes. I would assume that React would disconnect the WebSocket and re-connect a new one.

@nathan-JJRplus

Copy link
Copy Markdown
Owner

You got it 😄
The second half of the diagram just shows potential example querys in the notify action and the colors represent which clients would receive the notification based on their tags

In regards to changing the objectId while the client is already connected:

In the new situation there will be no objectId anymore, but a list of tags instead

The moment the client widget renders it registers the websocketsession under these tags until the session closes so a change in which tags the session is subscribed to does warrant a dis- and reconnect which can be forced by unrendering the widget

I hope Im communicating this properly 😅

I do think this would be the least intrusive way to implement such a feature and it would be a powerful addition to its capabilities!

Ill start working on it soon but Ive been out of work for a while so acquisition is taking a lot of time 😖

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants