joomla-projects / gsoc16_recording-action-logs

Recording actions logs, accessible by super admin
https://summerofcode.withgoogle.com/projects/#4547036649095168
GNU General Public License v2.0
4 stars 4 forks source link

Feature: Admin Email Notifications #22

Closed ajwalks closed 8 years ago

ajwalks commented 8 years ago

Include ability to configure the plugin so it can notify admins (via email) of specific actions. eg: choose to notify "user A" about change in content, notify "user B" about new users who have been created, etc.

muhakh commented 8 years ago

Hi All, @Llewellynvdm suggested that I can use Joomla's internal messaging to implement this feature, but I can't get to the messaging system more than load the "MessagesModelMessage" model and send the message by using the "save" function. Is there any APIs that I can use to do so?

And I have also another question, this feature can be implemented using a cronjob, so my question is: Is it OK to add a feature that uses a cronjob to Joomla core?

yvesh commented 8 years ago

@muhakh Hmm, cronjobs can't be used on every host / provider. And probably people want to be notified directly when something is happening and not just every hour (or minute or whatever you set the cronjob time). But if you think a cronjob is better you can of course create one.

For mails i think it's not possible to use com_messages for you. You need some subscription view and save what kind of mails the user wants to get etc.

Sending mails in Joomla is pretty straight forward, see: https://docs.joomla.org/Sending_email_from_extensions

Llewellynvdm commented 8 years ago

@yvesh Hmmm, to set a superscription kind of detail for every user a profile (plugin) is what seemed most logic. Then sending messages to the user via the behavior selected would naturally follow.

To send immediately should be straight forward like you said... but storing a record of the messages in Joomla com_messages seemed most appropriate (if a user selected that option in their profile). If this feature of storing the messages on the system is beyond the scope then no need to use com_messages.

muhakh commented 8 years ago

I thought it would be as a newsletter sent every period (daily, monthly, etc.), but it appeared to be email notifications like notifications from social media or github (I should have looked at the title of the issue :D ). So, I think now there is no need for a cronjob as the notifications are per log, but this raises another question: would it be much load to store the log and send notification to the users (who has the permission to receive these message) at the same time the event is triggered?

Llewellynvdm commented 8 years ago

I would think these things should not be done at the same time. This will slow down the whole process.

Maybe @yvesh has a better way to run the two concepts in isolation. The recording of the event and then the notification to the applicable admin. It seems ideal that the normal flow have minimal load... and that the extra functionality like notifications gets triggered slightly latter, but without the user knowing or seeing the added delay, like ajax would behave.

A cronjob or a plugin would work... but then we are back with the reality of keeping record of who has already received what.

Hench my initial proposal to use com_messages... hmmm if that is not an option, then parsing the logs and sending the emails to the admin based on some stored json file could also work.

Okay so the event gets recorder and then when the cron or plugin runs the next batch of emails gets send.

So we have three concepts here: One (record event) Two (send notification via email to the admin) Three (store the id of the last log during this Notification batch)

So if the last log in the system is id 134 then this id should be stored until the next time the Notifications are send... so if it starts again either via (cron or plugin) it first checks if new events were loged if so then it starts sending notifications for id 135, then once done the new id of the last log should be stored ... and so on. The id can be stored either in the plugin... or some json file.

Anyway this will help distribute the load.

I have in the past used Ajax to startup a process that should run without effecting the user experience. Basically to sidestep the cronjob idea... and yet not effect the system visually. Almost like a queuing system (Zero MQ or rabbitmq) just on a small and simple scale.

Now on a small site this is trivial... but from experience I like to move some jobs that does not need to be done immediately into this kind of process.

@yvesh and other may know of a better way to do this in Joomla, and then I would also like to know about it :+1:

muhakh commented 8 years ago

@Llewellynvdm I'm a bit confused of what should happen. What is going to be done first? logging to the database or sending the notifications? and how can I make the delay between the logging and the notification? and do you mean by a plugin that on storing the logs in the database an event is triggered which I can build a plugin to send a notification when that event is triggered?

Llewellynvdm commented 8 years ago

@muhakh I would think it is quite simple... you already log the event to the DB, so sending the notification should follow after that.

Yet please note that my suggestions are simply what I would try and test and do when having to resolve the same kind of problem. How you would solve it is up to you. It would be ideal if more developers gave suggestions and even point to some better Joomla way of doing this.

So what do you think... would sending the notification at the same time as logging the event be that huge of a load on every event... or would it actually be okay?

What I explained previously is separation of the two concepts. I wonder what @chrisdavenport would suggest or @roland-d since they have more experience with Joomla then I do.

So the idea is simple first log the event, then after the user is no longer waiting for the execution but has moved on, then only send the notification via some Ajax request or a cronjob.

A plugin would simply add the little Ajax to the page that will in turn trigger the notification process, but would need some kind of queuing to prevent multiple execution. This is not the Joomla way, or I don't know of any thing like this in Joomla, yet I may be wrong... I have seen that there is a daemon class, but it is not able to run on all systems as far as I understand.

The simplest way would be to simply do it all at once I suppose, yet I think this will be adding a lot of load on each event... that is just my 5c

johanjanssens commented 8 years ago

@muhakh The firs thing you do is insert the event in the database, aka creating the log. When you do that you implement a proper try/catch to handle potential errors. If no error occurs the event can be passed of to additional event handlers, for example to send email notifications.

What happens after and how that is implement should be pluggable. The easiest way is to send the notifications is in sync. This will work fine if the amount of emails is limited (max 100 will work on most servers). If the load goes up you will need different mechanisms to send the mail. I would consider that problem out of scope for the GSOC.

A point of criticism

The goal of the Joomla core is not to provide features but to create flexibility that allow extension developers to hook into and extend Joomla. This allows Joomla and it's eco-system to grow. Features are developed by extension developers; not core developers.

The goal of this summer of code project should be to focus on creating an event logging API and plugin system. The email notifications, which are part of this issue could be an example plugin.

@Llewellynvdm Summer of code students are looking to their technical mentors for guidance and coaching. As a mentor you are expected to know how things should be coded, it's up to you to guide the student and help him discover this through trial and error. Confusing him is not going to make it any easier for the student. There is nothing wrong with not knowing, but then please abstain yourself from discussions in issues.

Architecture first

From a programming pattern perspective what you are implementing here is called an interception filter pattern..

Interception Filters are a subset of a larger architecture pattern called Inversion of Control. I have written an white paper about this a few year ago on the subject related to Joomla that might be worth reading: https://docs.google.com/document/d/1MsFW9GLbRv0juyqdbkD5bMBUmkk6ATnwcBklEaETQqE/edit#heading=h.4w27zfu6z93y

Further Reading

LOGman is build on top of our Joomlatools Framework activities component which is available publicaly on Github: https://github.com/joomlatools/joomlatools-framework-activities

For further research

I'm happy to help with questions, just mention me in a comment or issue and I'll try to reply.

@muhakh good luck!