DEV: improve creation of custom notifications (PR #8077)

It now allows to write this:

    Notification.create!(
      notification_type: Notification.types[:custom],
      user_id: 3,
      data: {
        customMessage: 'This is going well',
        customTranslatedTitle: 'Status of the day', // could also be customTitle which would be wrapped in an I18n.t call
        customIcon: 'heart',
        customUrl: 'https://www.google.fr',
        display_username: "joffreyjaffeux"
      }.to_json
    )

GitHub

You’ve signed the CLA, jjaffeux. Thank you! This pull request is ready for review.

@danielwaterworth @SamSaffron how do you feel about this ?

@jjaffeux, I think it’s an improvement, but I have two reservations:

  • I’m not keen on customTranslatedTitle since it bypasses translation,
  • I also wonder if it would be better to make it easier for plugins to create their own notification types rather than to improve custom notifications. Notifications often need to be changed after the fact and so plugins need to know which notifications they created. They can do this in an ad-hoc way by adding a field to data, but I’d prefer to see this information in the notification_type itself.

:wave:t2:

  • we use this translatedXxx pattern at many places in discourse and this is very useful, what do you do if all you have is an already translated string?
  • I agree on the general idea but how do you deal with plugins adding types, when types are an enum? how do you avoid collision? (Dont have code at hand right now, but I think this is an enum).
1 Like

we use this translatedXxx pattern at many places in discourse

ok, good to know.

I agree on the general idea but how do you deal with plugins adding types, when types are an enum? how do you avoid collision? (Dont have code at hand right now, but I think this is an enum).

You are correct. I see two possible ways forward:

  1. Create a table for notification_types and give plugins a way to create a seed,
  2. Remove integer notification type ids entirely and use strings instead. Performing that migration might be prohibitive though,
1 Like

I would personnaly go with 1

1 Like

Unsure though, I think this is a lot of code and a new table… to solve almost nothing my few lines of js could solve? what do you think @eviltrout ?

If a plugin seeded a notification type, they’d have to reserve an ID, competing with every other plugin or piece of code in the future.

Changing the ID to a string is also a huge amount of work to get right.

What about adding a new column, custom_notification_type which is a string and would be present if the type is custom?

Not if they leave the ID unspecified and seed based on the name. This really doesn’t have to be complicated. Most of the machinery is already in place with notification_types being sent to the client via the SiteSerializer. I’ve implemented it here.

Your implementation has a LRU Cache and mutexes where previously it was a plain ruby object, so I think we have different interpretations of complicated.

And my implementation is only js … so I think … :grin::grin::grin: Seriously though, what would having this in plugin will actually bring over the js implementation? Do we have any real use case this couldnt solve?

On the contrary, I would love to get rid of threading from discourse.

1 Like

My call here is that I would far prefer to kill Notification.types[:custom] and require every plugin explicitly commit a change to core reserving the number they need.

These :custom things are a huge pain API wish, you can’t easily ask for custom of type X.

I think requiring every single plugin to make a commit to discourse core saying notification 24 == “do frob notification” is bigger win for discourse, it ensures our apis are cleaner and simpler to reason about.

Are we ok to close this :frowning:

1 Like

I don’t like the idea of plugins having to make PRs to core to reserve ids. It means every plugin depends on us being quick to merge in their requests. Any solution that allows plugins to do their own thing without ever contacting us is a win.

I do think we should close this and discuss elsewhere though.

1 Like

I don’t like the idea of plugins having to make PRs to core to reserve ids.

It is sadly a game of huge tradeoffs :frowning:

If we do not reserve ids then when I do select * from notifications and I see id = 22 on a row it is anyone’s guess what this means, so we need a whole new interface and API etc to figure out what site specific id 22 means.

From a pure platform perspective I get the desire to remove core from this decision, but it means we need new apis to provide the mappings, dynamic translations on the client are harder and so on.

Agree 100% we should take this elsewhere for discussion.

1 Like