Clear all notifications preferences for users

Last modified by Michael Hamann on 2026/06/02 17:55

cogScript to clear all the notification settings from all users, so that they inherit from wiki level.
TypeSnippet
CategoryOther
Developed by

Anca Luca

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1

Description

Until XWIKI-18509 is done and while XWIKI-19070 is still not implemented(was implemented in 15.5-rc-1), you may find yourself, in various situations (for example an upgrade or a revamp of the notifications system), wanting to reset all your user's notification settings in order to replace them with an inherited setup at wiki level.

You can use this script to do so, tested on XWiki 13.4.7. If you want to inspect in detail the notification settings of your users, use the snippet  User notification preferences listing .

Copy the following code in a page and view the page - attention, depending on the number of users on your wiki viewing this page can be very long.

{{velocity output="false"}}
#userPicker_import()
{{/velocity}}

{{velocity}}
== Reset notification settings of a single user ==

{{html wiki='false' clean='false'}}
<form method='POST' class='xform'>
  <div>
    <input type="text" name="user" placeholder="User name"" class="suggest-users"  data-xwiki-selectize='{"maxItems":1}'>
  </div>
  <div class='buttonwrapper'>
    <button type="submit" class="button primary btn btn-primary" name="action" value="reset-notifications-single-user">Show notification settings</button>
  </div>
  <input type="hidden" name="formToken" value="$!{services.csrf.getToken()}">
</form>
{{/html}}

== Reset notification settings of all users ==

{{warning}}Use this carefully for wikis with lots of users.{{/warning}}

{{html wiki='false' clean='false'}}<form method='POST' class='xform'>
  <div>
    <input type='hidden' name='allusers' value='true'>
  </div>
  <div class='buttonwrapper'>
    <button type="submit" class="button primary btn btn-primary" name="action" value="reset-notifications-all-users">Show notification settings</button>
  </div>
  <input type="hidden" name="formToken" value="$!{services.csrf.getToken()}" />
  </form>
{{/html}}

#set ($allowedActions = ['reset-notifications-single-user', 'reset-notifications-all-users'])
#if ($hasGlobalAdmin && $services.csrf.isTokenValid($request.formToken) && $allowedActions.contains("$!request.action"))
  #set ($confirmed = false)
  #if ("$!request.confirm" == 'true')
    #set($confirmed = true)
  #end
  #if ($request.action == 'reset-notifications-all-users')
    #set ($users = $services.query.xwql("from doc.object(XWiki.XWikiUsers) as user order by doc.name").execute())
  #elseif ($request.action == 'reset-notifications-single-user' && "$!request.user" != '')
    #set ($query = $services.query.xwql("from doc.object(XWiki.XWikiUsers) as user where doc.fullName = :userName order by doc.name"))
    #set ($discard = $query.bindValue('userName', $request.user))
    #set ($users = $query.execute())
  #end
  #set($usersToUpdate = 0)
  ## reset the preferences for email, autowatch, activated applications and system filters
  #if ($users.size() == 0)
    #stop()
  #end
  #if ($confirmed)

    {{info}}
    The table below displays the actions that were taken on the user profile(s).
    {{/info}}
  #else

    {{info}}
    On actual run, the following changes will be performed on the user profile(s). Review the list and confirm at the end of the page.
    {{/info}}
  #end
  #if (!$confirmed)
    |=User|=Email preferences|=Autowatch preferences|=Application events settings|=System filters settings|=Custom filters|=Comment
  #else
    |=User|=Email preferences|=Autowatch preferences|=Application events settings|=System filters settings|=Custom filters
  #end
  #foreach($u in $users)
    #set($uDoc = $xwiki.getDocument($u))
    #set($uDocNeedsSave = false)
    #set($notifEmailPreferences = $uDoc.getObjects('XWiki.Notifications.Code.NotificationEmailPreferenceClass'))
    #set($notifAutowatchPreferences = $uDoc.getObjects('XWiki.Notifications.Code.AutomaticWatchModeClass'))
    #set($appPreferences = $uDoc.getObjects('XWiki.Notifications.Code.NotificationPreferenceClass'))
    #set($systemFiltersSettings = $uDoc.getObjects('XWiki.Notifications.Code.ToggleableFilterPreferenceClass'))
    #set($customFilterIds = [])
    #set($customFilters = $services.notification.filters.getFilters($uDoc.documentReference))
    #foreach($cF in $customFilters)
      #foreach($cFP in $services.notification.filters.getFilterPreferences($cF, $uDoc.documentReference))
        #set($discard = $customFilterIds.add($cFP.id))
      #end
    #end
    #if ($confirmed)
      ## actual run
      #set ($tableRow = "|[[$u>>doc:$u]]")
      #if ($uDoc.removeObjects('XWiki.Notifications.Code.NotificationEmailPreferenceClass'))
        #set ($tableRow = "$tableRow||Removed email preferences")
        #set($uDocNeedsSave = true)
      #else
        #set ($tableRow = "$tableRow|")
      #end
      #if ($uDoc.removeObjects('XWiki.Notifications.Code.AutomaticWatchModeClass'))
        #set ($tableRow = "$tableRow|Removed autowatch preferences")
        #set($uDocNeedsSave = true)
      #else
        #set ($tableRow = "$tableRow|")
      #end
      #if ($uDoc.removeObjects('XWiki.Notifications.Code.NotificationPreferenceClass'))
        #set ($tableRow = "$tableRow|Removed application events settings")
        #set($uDocNeedsSave = true)
      #else
        #set ($tableRow = "$tableRow|")
      #end
      #if ($uDoc.removeObjects('XWiki.Notifications.Code.ToggleableFilterPreferenceClass'))
        #set ($tableRow = "$tableRow|Removed system filters settings")
        #set($uDocNeedsSave = true)
      #else
        #set ($tableRow = "$tableRow|")
      #end
      #if ($uDocNeedsSave)
        #set($discard = $uDoc.save("Reset notification preferences"))
      #else
        #set ($tableRow = "$tableRow|")
      #end
      #if ($customFilterIds.size() > 0)
        #foreach($cFPId in $customFilterIds)
          #set($discard = $services.notification.filters.deleteFilterPreference($cFPId, $uDoc.documentReference))
        #end
        #set ($tableRow = "$tableRow|Removed custom filters")
      #else
        #set ($tableRow = "$tableRow|")
      #end
      $tableRow
    #else
      ## preview
      #set($uDocNeedsSave = $notifEmailPreferences.size() > 0 || $notifAutowatchPreferences.size() > 0 || $appPreferences.size() > 0 || $systemFiltersSettings.size() > 0)
      |[[$u>>doc:$u]]|$notifEmailPreferences.size()|$notifAutowatchPreferences.size()|$appPreferences.size()|$systemFiltersSettings.size()|$customFilterIds.size()|(((
        #if ($uDocNeedsSave || $customFilterIds.size() > 0)
          (% style="color: darkred; %)On actual run, user's notification preferences will be updated.(%%)
        #set($usersToUpdate = $usersToUpdate + 1)
        #else
          The user has no notification preferences, nothing to update
        #end
      )))
    #end
  #end
  #if (!$confirmed && $usersToUpdate > 0)
    ## Confirm form

    {{html clean='false'}}
      <form action="" method="POST" class="xform" />
        <div class="buttonwrapper">
          <input name="confirm" value="true" type="hidden" />
          <button type="submit" class="btn btn-primary button" name="confirmed" value="true">Confirm notifications reset</button>
          <input type="hidden" name="user" value="$escapetool.xml($request.user)">
          <input type="hidden" name="action" value="$request.action">
          <input type="hidden" name="formToken" value="$!{services.csrf.getToken()}">
        </div>
      </form>
    {{/html}}
  #end
#end
{{/velocity}}

Following this change, the following behaviour will be in place for all your users:

  • the email frequency is set to the default of XWiki (daily)
  • the details of the changes for the email are inherited from what is set at wiki level (in Administration -> Social > Notifications)
  • the autowatch is inherited from what is set at wiki level (in Administration -> Social > Notifications)
  • the applications notifications settings are inherited from what is set at wiki level (in Administration -> Social > Notifications)
  • the system filters are set to the default of XWiki. Updating the system filters at wiki level in Administration -> Social > Notifications will have no effect on these existing users.
    • on XWiki 13.4.7, the default of XWiki is "off" for the read event filters (email and alert) and "on" for all others.
  • the custom filters are empty. Updating the custom filters at wiki level in Administration -> Social > Notifications will have no effect on these existing users.

If your objective is to workaround XWIKI-19070, you will probably also want to add an inclusive filter for each user after resetting everything, since the filters will not be inherited at all from wiki level for existing users (see XWIKI-18509), even if the rest of the preferences are inherited.

In order to do so, use the $services.notification.filters API.
For example, for adding an inclusive filter for the user's own profile , you can add the following line after line 55 in the script above:

#set ($discard = $services.notification.filters.createScopeFilterPreference("INCLUSIVE", ['alert', 'email'], [], $uDoc.documentReference, $uDoc.documentReference))

See also the Set notification filters for all users snippets for adding a filter for all existing users.

Cleaning only Notification Filters

If you just want to clean notification filters without touching any other settings, you may use or adapt the following, reduced version of the above snippet:

{{velocity output="false"}}
#userPicker_import()
{{/velocity}}

This script has been adapted from the [[clear all notifications settings for users snippet>>snippets:Extension.Clear all notifications settings for users.WebHome]] by removing the parts that clear notification preferences, thus only clearing custom filters/watched pages.

{{velocity}}
== Reset notification settings of a single user ==

{{html wiki='false' clean='false'}}
<form method='POST' class='xform'>
  <div>
    <input type="text" name="user" placeholder="User name"" class="suggest-users"  data-xwiki-selectize='{"maxItems":1}'>
  </div>
  <div class='buttonwrapper'>
    <button type="submit" class="button primary btn btn-primary" name="action" value="reset-notifications-single-user">Show notification settings</button>
  </div>
  <input type="hidden" name="formToken" value="$!{services.csrf.getToken()}">
</form>
{{/html}}

== Reset notification settings of all users ==

{{warning}}Use this carefully for wikis with lots of users.{{/warning}}

{{html wiki='false' clean='false'}}<form method='POST' class='xform'>
  <div>
    <input type='hidden' name='allusers' value='true'>
  </div>
  <div class='buttonwrapper'>
    <button type="submit" class="button primary btn btn-primary" name="action" value="reset-notifications-all-users">Show notification settings</button>
  </div>
  <input type="hidden" name="formToken" value="$!{services.csrf.getToken()}" />
  </form>
{{/html}}

#set ($allowedActions = ['reset-notifications-single-user', 'reset-notifications-all-users'])
#if ($hasGlobalAdmin && $services.csrf.isTokenValid($request.formToken) && $allowedActions.contains("$!request.action"))
  #set ($confirmed = false)
  #if ("$!request.confirm" == 'true')
    #set($confirmed = true)
  #end
  #if ($request.action == 'reset-notifications-all-users')
    #set ($users = $services.query.xwql("from doc.object(XWiki.XWikiUsers) as user order by doc.name").execute())
  #elseif ($request.action == 'reset-notifications-single-user' && "$!request.user" != '')
    #set ($query = $services.query.xwql("from doc.object(XWiki.XWikiUsers) as user where doc.fullName = :userName order by doc.name"))
    #set ($discard = $query.bindValue('userName', $request.user))
    #set ($users = $query.execute())
  #end
  #set($usersToUpdate = 0)
  ## reset the preferences for email, autowatch, activated applications and system filters
  #if ($users.size() == 0)
    #stop()
  #end
  #if ($confirmed)

    {{info}}
    The table below displays the actions that were taken on the user profile(s).
    {{/info}}
  #else

    {{info}}
    On actual run, the following changes will be performed on the user profile(s). Review the list and confirm at the end of the page.
    {{/info}}
  #end
  #if (!$confirmed)
    |=User|=Custom filters|=Comment
  #else
    |=User|=Custom filters
  #end
  #foreach($u in $users)
    #set($uDoc = $xwiki.getDocument($u))
    #set($customFilterIds = [])
    #set($customFilters = $services.notification.filters.getFilters($uDoc.documentReference))
    #foreach($cF in $customFilters)
      #foreach($cFP in $services.notification.filters.getFilterPreferences($cF, $uDoc.documentReference))
        #set($discard = $customFilterIds.add($cFP.id))
      #end
    #end
    #if ($confirmed)
      ## actual run
      #set ($tableRow = "|[[$u>>doc:$u]]")
      #if ($customFilterIds.size() > 0)
        #foreach($cFPId in $customFilterIds)
          #set($discard = $services.notification.filters.deleteFilterPreference($cFPId, $uDoc.documentReference))
        #end
        #set ($tableRow = "$tableRow|Removed custom filters")
      #else
        #set ($tableRow = "$tableRow|")
      #end
      $tableRow
    #else
      ## preview
      |[[$u>>doc:$u]]|$customFilterIds.size()|(((
        #if ($customFilterIds.size() > 0)
          (% style="color: darkred; %)On actual run, user's notification preferences will be updated.(%%)
        #set($usersToUpdate = $usersToUpdate + 1)
        #else
          The user has no notification preferences, nothing to update
        #end
      )))
    #end
  #end
  #if (!$confirmed && $usersToUpdate > 0)
    ## Confirm form

    {{html clean='false'}}
      <form action="" method="POST" class="xform" />
        <div class="buttonwrapper">
          <input name="confirm" value="true" type="hidden" />
          <button type="submit" class="btn btn-primary button" name="confirmed" value="true">Confirm notifications reset</button>
          <input type="hidden" name="user" value="$escapetool.xml($request.user)">
          <input type="hidden" name="action" value="$request.action">
          <input type="hidden" name="formToken" value="$!{services.csrf.getToken()}">
        </div>
      </form>
    {{/html}}
  #end
#end
{{/velocity}}

Get Connected