BookStack icon indicating copy to clipboard operation
BookStack copied to clipboard

Provide the ability to push watching/notifications to users/groups

Open rseffner opened this issue 2 years ago • 4 comments

Describe the feature you'd like

Up to v.26 I used an hack (custom theme function.php) to send notifications for page changes to users/groups when an tag:value is set. So an mod/author can create content an notify specified readers.

Now (v.28) - and I really like to see notifications integrated - the users decide by themselve to which book/chapter/page they like to get notifications for.

I'ld really like to see the alternative also integrated : the content author should be able to set an update notification for specified books/chapters/pages to users/groups.

Describe the benefits this would bring to existing BookStack users

It's already describet in the feature description. The feature is more an "push" instead oft the new "pull" subscription/notification.

Can the goal of this request already be achieved via other means?

No. The mentioned hack is not compatible with v.28 (or/and I'm not able to adjusti it)

Have you searched for an existing open/closed issue?

  • [X] I have searched for existing issues and none cover my fundemental request

How long have you been using BookStack?

1 to 5 years

Additional context

No response

rseffner avatar Sep 05 '23 10:09 rseffner

Thanks for the request. From my point of view, I'm not too keen on the idea of pushing notifications options onto users, since notifications are often a personal thing. I feel like this'll start to get into acting as additional UI complexity in having controls for controls, especially this would be something that many instances would not desire so would need options for disabling. This also comes across business process/use-case specific, why I try to avoid in BookStack.

The logic of the hack should still work, but across v23.06 and v23.08, many files have moved location so likely class references just need to be updated to align with the current locations.

ssddanbrown avatar Sep 05 '23 12:09 ssddanbrown

The with v.26 working "hack" looks like folowing

<?php
use BookStack\Activity\ActivityType;
use BookStack\Activity\Models\Tag;
use BookStack\Users\Models\Role;
use BookStack\Users\Models\User;
use BookStack\Entities\Models\Page;
use BookStack\Facades\Theme;
use BookStack\Notifications\MailNotification;
use BookStack\Theming\ThemeEvents;
use Illuminate\Notifications\Messages\MailMessage;

class PageUpdatedNotification extends MailNotification {
    protected Page $page;
    protected User $updater;

    public function __construct(Page $page, User $updater)
    {
        $this->page = $page;
        $this->updater = $updater;
    }

    public function toMail($notifiable)
    {
        return (new MailMessage())
            ->subject('SuS-Wiki Seiten-Update-Benachrichtigung')
            ->line("Die Seite \"{$this->page->name}\" wurde verändert durch \"{$this->updater->name}\"")
            ->action('Link direkt zur Seite', $this->page->getUrl());
    }
}

function notifyRequiredUsers(Page $page) {
    $notifyTag = Tag::query()
        ->where('entity_type', '=', 'page')
        ->where('entity_id', '=', $page->id)
        ->where('name', '=', 'notify')
        ->first();
    if (!$notifyTag) {
        return;
    }
    $roleNames = array_filter(array_map(fn($str) => trim($str) , explode(',', $notifyTag->value)));
    $roleIds = Role::query()->whereIn('display_name', $roleNames)->pluck('id');
    if (count($roleNames) === 0 || $roleIds->isEmpty()) {
        return;
    }
    $usersToNotify = User::query()
        ->whereExists(function($query) use ($roleIds) {
             $query->select('user_id')
                 ->from('role_user')
                 ->whereColumn('users.id', '=', 'role_user.user_id')
                 ->whereIn('role_id', $roleIds);
        })
        ->where('id', '!=', $page->updated_by)
        ->get();
    $updater = User::query()->findOrFail($page->updated_by);
    foreach ($usersToNotify as $user) {
        $user->notify(new PageUpdatedNotification($page, $updater));
        usleep(100000); // Slight 0.1s delay to help rate limit abuse
    }
}

Theme::listen(ThemeEvents::ACTIVITY_LOGGED, function(string $type, $detail) {
    if (($type === ActivityType::PAGE_UPDATE || $type === ActivityType::PAGE_CREATE || $type === ActivityType::PAGE_RESTORE) && $detail instanceof Page) {
        notifyRequiredUsers($detail);
    }
});

The PHP error with v.28 is

PHP Fatal error:  Declaration of PageUpdatedNotification::toMail($notifiable) must be compatible with BookStack\\Notifications\\MailNotification::toMail(BookStack\\Users\\Models\\User $notifiable): Illuminate\\Notifications\\Messages\\MailMessage in /var/www/BookStack/themes/custom/functions.php on line 38

Maybe its only some little change in PageUpdatedNotification extends MailNotification and the toMail Part ...

rseffner avatar Sep 05 '23 13:09 rseffner

Maybe a compromise would be an option in the admin settings, to enable notifications for changes to all users only regarding the landing page, since i suppose, a lot of instances use the landing page as a general news board.

Karamelmar avatar Aug 16 '24 08:08 Karamelmar

In MediaWiki and other CMS the ability for the admin role to receive an "audit" notification when either a (subscribed) page or "category" is edited exists... this provides an over site function of the "editors". I think this is underlying desire of all of the these requests. I came here looking for this feature.

jt-telrite avatar Apr 21 '25 17:04 jt-telrite