It’s easy to use categories and subcategories to allow users to view them based on ‘OR’ logic - ie. if a user is in Group X or Group Y then they can see the category or subcategory.
Is it possible to effectively use ‘AND’ logic, so that a user must be in both Group X AND Group Y to be able to see a category / subcategory?
Our use case is that we have three tiers of access. It’s easiest to think about them as Year 1 students, Year 2 students, and Year 3 students. Year 1 can only see Year 1 content, Year 2 can see Year 1 and Year 2 content, Year 3 can see all content. It works great.
We want to add in another layer, by rewarding users at Trust Level 3 with early access to certain events and resources.
I first tried doing this by using unlisted events in the various year levels, and sending a link to those events to users at Trust Level 3, however anyone with notifications set to monitor Year 1 or Year 2 or Year 3 can also instantly see those events, not limited to Trust Level 3.
Another way to do this would be to create a category called “Trust Level 3 Rewards”, and have subcategories for Year 1, Year 2, and Year 3, but it isn’t possible to restrict permissions like this; since Year 1, Year 2, and Year 3 have to have visibility over the category, again, all users in those groups (with any level of Trust) can see into the subcategories.
A very clunky way of doing it would be to export users at Trust Level 3, then export users at (for example) Year 2, merge them in Excel to find duplicates, then import those duplicates into a group called something like “Trust Level 3 and Year 2”. It would work, but take a fair bit of manual work each time, and it’s an action we want to perform regularly.
Any ideas on other ways to achieve the same outcome? Could a custom plug-in or script at least automate the export and import process?
Creating a new group that contains the target group’s users who have trust level 3 is the only way I can think of to accomplish this. Discourse doesn’t have an AND rule that can be used with category security permissions. A similar question has come up a few times about creating a category rule that excludes members of one or more groups.
If the Data Explorer plugin is available on your site, you could use a Data Explorer query that returns a list of all of the target group’s users who have trust level 3. If you are not dealing with a huge number of users, you should be able to copy/paste the usernames that are returned from the query directly into a group’s Add Users form. Discourse seems to handle adding usernames that already exist in a group into that form, so if you run the query periodically, you should be able to just keep copying the usernames that are returned into the group’s Add Users form. Note, I’m not sure what the maximum number of usernames that can be pasted into the form is. I just tested it with 80 users and that works without issue. Also, if you attempt to paste an exact duplicate list of users into the Add Users form, Discourse seems to return an error. The error can be ignored though.
Here’s the query I’ve tested this with. You need to supply the group name, for example ‘year_2’, before running the query.
--[params]
-- string :group_name
SELECT u.username
FROM group_users gu
JOIN groups g ON g.id = gu.group_id
JOIN users u ON u.id = gu.user_id
WHERE g.name = :group_name
AND u.trust_level = 3
It would be possible to automate the above process by running the Data Explorer query via the API, then using the results of the API request to update the group. Details about that are here: Run Data Explorer queries with the Discourse API. You’d then need to update the group members via the API.
It would be interesting to be able to perform some types of actions directly on the results of a Data Explorer query. For example, with a query that returns a list of usernames, add all the users to a group without having to go through the copy/paste step.
Thanks!
I haven’t played with Data Explorer, but it’s on my list of things to explore, and this sounds like a plausible way to do what I’m trying to do. I’ll have a look…
Thanks also for the query.
Just reporting back on what we wound up doing here, in case it’s of use to others. In short, we’re exporting to Excel, getting Excel to work out who fits our ‘AND’ criteria, then bulk adding those users into a group.
We had our tech assistant look into a custom plug-in to do the same thing, but it looks like it’s proving a little tricksy, so for the moment we’re staying with Excel.
More details:
Export whole user database.
Import to Excel. Use ISNUMBER and SEARCH to extract users in a specific group in the first sheet to a second sheet.
Use ISNUMBER and SEARCH again to extract users in the second specific group to a third sheet.
Bulk add those users into their appropriate groups.
I imagine there’s a cleaner way to achieve the same outcome, however now that it’s in place, it’s just a question of pasting the exported data each time, and then importing the results, without needing to think about it on the way through.
We’re using this system to reward tl3 ‘regular’ users with additional privileges and early access to things, and it’s having the desired effect of encouraging higher quality and higher quantity usage. So, success, albeit a bit clunky and un-automated. We have our ‘this group AND that group’ function.
You could use the new Automation script ‘User Group Membership through Badge’ to maybe link this up? Especially if you have Custom Triggered badges enabled.