How can I automatically grant a badge when the user visits a link within the discourse forum?
AI-generated summary
In this discussion, Sami_Syed seeks to automatically grant a badge when a user visits a specific link or topic in Discourse. JammyDodger suggests using SQL queries targeting the topic_link_clicks or topic_views tables, depending on whether the badge should trigger from clicking a link within a post or simply visiting a topic. For link-based badges, the query requires the post ID and exact URL clicked; for topic visits, use the topic ID with topic_views. Sami_Syed initially confuses post ID with topic ID, which JammyDodger clarifies â using the correct topic ID resolves the issue. Badge grants run daily by default, but can be manually triggered via /sidekiq/scheduler using Jobs::BadgeGrant JammyDodger. Sami_Syed then asks about upgrading trust levels via badges and hiding topics. JammyDodger recommends using the Automation pluginâs âUser Group Membership through Badgeâ script to assign users to a custom group tied to a specific trust level, avoiding automatic downgrades. For hiding topics, unlisting them or placing them in a new, unwatched subcategory is advised. Sami_Syed follows up on how to configure group-based trust levels, which JammyDodger explains via group settings in the admin panel and links to the Automation plugin documentation.
How about using the topic_link_clicks table?
I think I might have a manual badge that could benefit from this.
Iâll have a think.
If itâs a specific link shared in a specific post, I think this one would do it:
SELECT DISTINCT tlc.user_id, MIN(tlc.created_at) granted_at
FROM badge_posts p
LEFT JOIN topic_links tl ON tl.post_id = p.id
LEFT JOIN topic_link_clicks tlc ON tlc.topic_link_id = tl.id
WHERE tl.post_id = 1246
AND tl.url = 'https://meta.discourse.org/'
AND tlc.user_id IS NOT NULL
GROUP BY tlc.user_id
Youâd need to grab the post_id of your specific post from its post json (or run a look up through the data explorer)
I think this could work.
I only want to grant this badge to members of our course.
Is there any way to hide a topic from the general public and only make it available to those who click on it via a link.
Secondly, how can this be done using Dfata explorer plugin?
Iâm not 100% sure Iâm following the method youâre using for this? You may want to have a check that youâre not overcomplicating the setup.
If checking the json isnât your cup of tea, then a post_id lookup query would be something like this:
-- [params]
-- topic_id :topic_id
-- int :post_number
SELECT id
FROM posts
WHERE topic_id = :topic_id
AND post_number = :post_number
Then you can use the URL of the post to pull out the topic id and post number to enter into the parameter boxes. eg: https://meta.discourse.org/t/grant-badge-when-user-visits-link/276700/4 (worth noting that the OP is always post_number 1, even if itâs not in the topic link)
Actually, thereâs a magic parameter that might make looking up a post_id using the data explorer even easierâŚ
-- [params]
-- post_id :url
SELECT id
FROM posts
WHERE id = :url
Paste the relevant URL for the post into the parameter box, et voila - it pops out the post_id ![]()
The red background makes me think itâs not a full post URL. If itâs a topic URL you need to pop a /1 on the end:
https://meta.discourse.org/t/grant-badge-when-user-visits-link/276700/1
That worked!
Im assuming this needs to be replaced with the post URL including the â/1â?
That bit needs to be replaced with the link theyâre clicking on within the post.
And the post_id is the post in which the link is pasted/shared.
Oh I see, so there is no way to just grant the badge just by them visiting the post link?
I think there should be, but that would be a different query.
This one awards a badge for clicking on a specific link in a specific forum post.
If you want to award a badge for a user visiting a particular topic I think it would be:
SELECT DISTINCT tv.user_id, MIN(tv.viewed_at) granted_at
FROM topic_views tv
WHERE tv.topic_id = 728
GROUP BY tv.user_id
(Replacing â728â with the relevant topic_id)
As it needs the Update Daily trigger, it will be granted the next time the daily badge grant job runs. You can manually trigger Jobs::BadgeGrant from your /sidekiq/scheduler page if you want to speed it up to check.
How can I make it update instantly?
The only available triggers are:
- Update daily
- When a user edits or creates a post
- When a user is edited or created
- When a user acts on a post
- When a user is edited or created
- When a user changes trust level
To have a more instant badge granted, you would need to work within the confines of those actions. You can read more in this topic - Creating triggered custom badge queries
I did this but still not been granted yet.
Yes itâs enabled. Let me try on another profile. Maybe its because I am the admin.
Secondly, are you just pasting the topic link into your browser?
Being admin doesnât make a difference for this one.
You would need to visit the topic for it to register in the topic_views table this badge is based on.





