Assigned a badge based on multiple badge assignment

Hi folks
I’d like to assign a badge based on how many time a user obtain a specific badge

  • Alessio obtained at least 10 times foo badge - > Cool_foo badge earned
  • Luca obtained at least 15 times foo badge → Super_foo badge earned

Is it possible with an SQL query?

1 Like

This is possible. :+1:

Are you granting them manually (using the data explorer + bulk award) or triggering them by SQL?

Both. Most of them are manual but I’m trying to automatize everything

For a custom triggered one, I think you should be able to steal the Campaigner query and tweak it to work for badges instead of invites.

This one is for having 5 ‘Badge 108’, and would be set to update daily.

SELECT u.id user_id, current_timestamp granted_at 
FROM users u 
WHERE u.id IN ( 
    SELECT ub.user_id 
    FROM user_badges ub 
    WHERE ub.badge_id = 108
    GROUP BY ub.user_id 
    HAVING COUNT(*) >= 4 
) AND u.active AND u.silenced_till IS NULL AND u.id > 0 AND 
    (:backfill OR u.id IN (:user_ids) )

I’ve tested it briefly on my test site and it seems to work okay (I trigger the Badge Grant sidekiq job to speed up the wait). But hopefully that at least gives you a starting point to build from. :slightly_smiling_face:

There are also a few different examples in here you can use for inspiration, if you’ve not found it yet, Some common badge queries idea :+1:

2 Likes

Thank you but I’ve an error in my installation

> ActiveRecord::PreparedStatementInvalid: missing value for :backfill in /*
>  * DataExplorer Query
>  * Query: /admin/plugins/explorer?id=13
>  * Started by: alefattorini
>  */
> WITH query AS (
> SELECT u.id user_id, current_timestamp granted_at 
> FROM users u 
> WHERE u.id IN ( 
>     SELECT ub.user_id 
>     FROM user_badges ub 
>     WHERE ub.badge_id = 102
>     GROUP BY ub.user_id 
>     HAVING COUNT(*) >= 1
> ) AND u.active AND u.silenced_till IS NULL AND u.id > 0 AND 
>     (:backfill OR u.id IN (:user_ids) )
> ) SELECT * FROM query
> LIMIT 1000

Looks like removing
(:backfill OR u.id IN (:user_ids) )

works well too
Is it mandatory?

It looks like you ran that in the data explorer. For the custom SQL badges you would need to turn on the hidden site setting and add the query to the badge page:

However, not everyone can do that depending on their hosting package.

But a data explorer one is more than possible too if you can’t have the custom SQL triggered ones. :+1: I think you’d have to make some choices about how often you ran it, and how the Badges would be awarded from the results (manually one by one, or through the bulk award), but it’s definitely do-able.

Something simple may be better, though you perhaps want to add a date range parameter too?

WITH foo AS (SELECT ub.user_id,count(ub.user_id), max(ub.granted_at) granted_at
FROM user_badges ub
WHERE ub.badge_id=108
GROUP BY ub.user_id) 

SELECT user_id, granted_at
FROM foo
WHERE count >4
ORDER BY granted_at DESC

I have this enabled. It woks like a charm :smiley: thank you

1 Like

That’s great. :slightly_smiling_face: I find copying the existing badge queries and having a tweak quite useful to give me an idea of where to start. I’m sure they can then be refined further as well if you encounter any issues with one. :+1:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.