Tracking links shared in Slack and Discord: a six-step setup that ignores preview bots
Slack and Discord clicks often carry no source, and preview bots hit your link first. Give each place its own short link and count clicks on your own server.
Muzahid Maruf, FounderUpdated
On this page
Explore with AI
Opens this article inside the chosen assistant with a ready-made prompt.
To track links shared in Slack and Discord, give each channel or server its own short link on a domain you control and count clicks at that redirect.
A click from a chat app often reaches your site with no referring page, which Google Analytics 4 reports as Direct, and both apps fetch the URL themselves within moments of the post, so your log shows a bot request before the first person clicks.
This works for links you control: ones you post, or hand to a customer or community manager to post.
Key takeaways
- Google Analytics 4 files a session as Direct when its source is exactly (direct) and its medium is (none) or (not set), which is how an untagged click from a chat app can land.
- Slackbot-LinkExpanding 1.0 and Discordbot/2.0 fetch a link the moment it is posted, and Slack ignores robots.txt and caches for about 30 minutes, so the filter has to live in your own click log.
- One short link per channel, server or workspace carries the source even when the app sends no referrer.
- Flag crawler requests and still redirect them. Then rank links by revenue per 100 clicks once the trial and confirmation time have passed: in the invented example, 86 clicks earn $181.40 per 100 and 1,190 clicks earn $9.83.
- TrackRev is affiliate software with link tracking built in: its Free plan covers 50 links and 1,000 tracked events a month, and revenue per link starts on Indie at $29 a month.
Why Slack and Discord clicks arrive without a source
Alexis Madrigal named the problem in The Atlantic on October 12, 2012. He called it dark social: visits with no referrer data, which he traced to email programs, instant messages, some mobile apps and secure-to-non-secure links.
Analytics tools file them as direct. Google Analytics 4 does so by rule.
Its default channel group defines Direct as a source of exactly (direct) with a medium of (none) or (not set), and Google's direct traffic help adds that redirects and URL shorteners can strip the details that identify a source.
Web clients can drop the referrer too: rel="noreferrer" makes the browser omit the Referer header, MDN says. Whether each Slack and Discord client sends one today is worth measuring in step 2, and an app update can change the answer.
What the preview crawlers do to your click count
Both apps request a link when someone posts it, to draw a preview card, and those requests reach your server before any reader does.
| Crawler | User agent | What it does | Source |
|---|---|---|---|
| Slackbot-LinkExpanding | Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots) | Reads oEmbed, Twitter Card and Open Graph tags with HTTP Range headers, then fetches any image, video or audio file those tags name | Slack Robots page |
| Slack-ImgProxy | Slack-ImgProxy 0.19 (+https://api.slack.com/robots) | Fetches and caches images posted to channels | Slack Robots page |
| Slackbot | Slackbot 1.0 (+https://api.slack.com/robots) | Makes every other HTTP request Slack needs, such as API calls and outgoing webhooks | Slack Robots page |
| Discordbot | Mozilla/5.0 (compatible; Discordbot/2.0; +https://discordapp.com) | Visits a link when it is shared in a message to build the preview card, and does no continuous crawling | Discord Support |
| Rule | Threshold | Source |
|---|---|---|
| Slackbot-LinkExpanding responses are cached across the service | Around 30 minutes, at most 1 request per URL | Slack Robots page |
| No preview expands for a link already shared in the same conversation | Within 1 hour | Slack Help Center |
| No preview expands in a message with | More than 5 links | Slack Help Center |
Slack preview rules that shape what reaches your log.
Slack ignores robots.txt, saying it acts for a human and does not follow links like a crawler.
Because the cache is service-wide, one link posted in 3 workspaces within half an hour can produce a single Slackbot request that no log can assign to a workspace.
Version numbers drift: Slack's page shows Slack-ImgProxy 0.19, while the crawler-user-agents list on GitHub records 0.59, 0.66, 1.106, 1.138 and 149. Discord's help article, updated October 3, 2026, says to match the word Discordbot anywhere in the string.
| Time (UTC) | Link | User agent | Counted |
|---|---|---|---|
| 14:02:09 | sl-tools | Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots) | No |
| 14:02:11 | dc-launches | Mozilla/5.0 (compatible; Discordbot/2.0; +https://discordapp.com) | No |
| 14:03:40 | dc-launches | iPhone 15, Safari 17.5 | Yes |
| 14:05:27 | sl-tools | Windows 11, Chrome 130 | Yes |
| 14:09:12 | dc-launches | Windows 10, Firefox 131 | Yes |
| 14:21:58 | sl-tools | MacBook Air, Safari 17.4 | Yes |
| 14:31:15 | dc-launches | Ubuntu 24.04, Chromium 130 | Yes |
| 14:48:30 | dc-launches | Pixel 8, Chrome 130 | Yes |
| 15:02:44 | sl-tools | iPad Air, Safari 17.5 | Yes |
| 15:20:03 | sl-tools | Galaxy S23, Chrome 129 | Yes |
Invented log for 2 links over about an hour. Counting every row reports 10 clicks for 8 visits, 25% too many.
How to track links shared in Slack and Discord
The examples below follow one page, example.com/pricing, posted in 1 Discord server, 2 Slack workspaces and a set of founder DMs, with a $39 monthly plan.
Step 1: Give every place its own short link
Create one link per place, each pointing at the same destination, and name it after the place: Discord #launches, Community Slack #tools, Acme customer Slack. Every click then belongs to that place whether or not the app sends a referrer.
In TrackRev's New campaign form, pick "A link per channel" and add a custom short link.
The channel picker offers 9 channels and neither Slack nor Discord is one, but bulk CSV import (up to 500 rows) and the REST API accept both.
A slack or discord row stamps utm_source and utm_medium=social on the destination, unless the destination already has its own tags.
url,name,channel,utm_campaign,utm_term,utm_content,tags
https://example.com/pricing,Discord #launches,discord,oct-launch,,launches,community
https://example.com/pricing,Community Slack #tools,slack,oct-launch,,tools,community
https://example.com/pricing,Acme customer Slack,slack,oct-launch,,acme,customerSkip Smart Links for these two apps. A Smart Link guesses the channel from the referrer. Slack proxies or strips the referrer, so TrackRev has no Slack mapping and those clicks land in Other or Direct.
Discord is on the recognized list, but only a click carrying a discord.com referrer gets the label.
Put the links on your own domain with one CNAME record (custom tracking domains). If you tag destination URLs by hand, the free UTM builder writes the tags, and medium social lands in Organic Social under Google's channel rules.
A redirect that forgets to forward the query string drops them, and the 5-step stripped-UTM test finds the hop that does it.
Step 2: Post a test link in each app
Post a fresh link in a private channel or test server on each client: desktop, web and phone. That is 6 test posts across the 2 apps.
Use a new link per test because of the 1-hour rule above, and one link per message because Slack expands none in a message with more than 5, then click each one from each client and read the report.
A client that sends no referrer costs you nothing, because the link's name carries the source.
| What to read | Where | What you may find |
|---|---|---|
| The preview fetch | GET /api/v1/clicks?bots=include | A row with a Slackbot-LinkExpanding or Discordbot user agent and is_bot set to true |
| The referrer | The Top referrers card on the link's page | Nothing, a chat domain, or the browser's own page, depending on the client |
| Device and browser | The breakdown cards on the same page | Whatever you clicked from, so check it against the phone or laptop in your hand |
Step 3: Flag preview fetches and still redirect them
Match crawlers on a user-agent substring (Slackbot, Discordbot), flag the request as a bot, store it, and leave it out of the counts. I would not block them, because a refused fetch leaves the post bare.
Discord publishes its public IP ranges in 2 formats, JSON and TXT, for anything that needs more than a spoofable user agent. The bot filtering guide covers prefetch headers and empty user agents.
TrackRev does this at the redirect with the isbot 5 user-agent list, which matches all 4 crawlers in the first table, plus empty user agents and prefetch headers.
A flagged request is still redirected and stored with is_bot set, and the link page, attribution and partner reports leave it out.
Step 4: Carry the click to the signup and the payment
A click becomes revenue when the visitor ID reaches the payment.
TrackRev's first-party pixel reads the ID on your first pageview, an email address binds the visitor to the customer at signup or checkout, and Stripe is read with a restricted key every hour, or by webhook for updates within seconds.
Built by hand, the shape is the same:
| Hop | Field | Limit |
|---|---|---|
| Redirect response | vid cookie, plus a _vid URL parameter in TrackRev | 1 year for the cookie |
| Stripe Payment Link | client_reference_id, returned in checkout.session.completed | 200 characters |
| Stripe objects with metadata | Metadata key-value pairs | 50 pairs, keys to 40 characters, values to 500 |
The Payment Links walkthrough has the setup.
Two gaps stay open: a click in the phone app followed by a laptop visit to your address arrives as Direct, and a signup email that differs from the payment email can slip past the join.
Step 5: Rank links by revenue per 100 clicks
Raw clicks reward the biggest audience. Divide by counted clicks to compare places of different sizes.
| Link | Counted clicks | Signups | Paid | Signups per 100 clicks | MRR | MRR per 100 clicks |
|---|---|---|---|---|---|---|
| Discord #launches | 1,190 | 14 | 3 | 1.18 | $117 | $9.83 |
| Community Slack #tools | 640 | 9 | 1 | 1.41 | $39 | $6.09 |
| Acme customer Slack | 302 | 11 | 6 | 3.64 | $234 | $77.48 |
| Founder DM shares | 86 | 6 | 4 | 6.98 | $156 | $181.40 |
Invented numbers on a $39 monthly plan. The Discord link has the most clicks and the founder DMs have the highest revenue per 100 clicks.
Discord #launches brings 53.7% of the 2,218 clicks and 21.4% of the $546 MRR. The founder DMs bring 3.9% of the clicks and 28.6% of the MRR.
Acme converts 6 of 11 signups to paid (54.5%) against 3 of 14 for Discord (21.4%).
Four paying customers from 86 clicks is too small a sample to repeat on purpose, so test the lead with a second batch of DMs.
Step 6: Wait out the trial before you judge a link
A link's revenue arrives after the click by the length of your trial plus the payment's confirmation time, and some payment methods, such as SEPA Direct Debit, confirm later.
For a 14-day trial and a click on October 1 (a 30-day trial moves the charge to October 31):
| Event | Date | Days after click |
|---|---|---|
| Click | October 1 | 0 |
| Trial ends, first card charge in Stripe | October 15 | 14 |
| Alternative: a 30-day trial ends, first card charge | October 31 | 30 |
| Earliest fair comparison | Some days after October 15, once Stripe reports the debit as paid | 15 or more |
What these links can't tell you
A redirect logs a device, a place and a time, and a name appears only when the visitor later signs up.
A Slack link copied into a DM keeps crediting its original place, and a teammate who types your domain without the link sends Direct traffic.
A signup field asking how people heard about you catches those, and the post on self-reported versus tracked attribution covers weighing the two.
What TrackRev does here, and when you don't need it
TrackRev is SaaS affiliate software with link tracking built in.
It logs each click on the server with time, country, city, device, browser, operating system and referrer, adds the link's saved UTM tags to the destination, and joins clicks to payments from Stripe, Paddle Billing, Polar, Lemon Squeezy, Creem and Dodo Payments.
Revenue per link needs a paid plan (pricing).
| Plan | Price | Links | Tracked events | Revenue per link |
|---|---|---|---|---|
| Free | $0 | 50 | 1,000 a month | Hidden |
| Indie | $29 a month | Unlimited | Unlimited | Shown |
| Growth | $299 a year | Unlimited | Unlimited | Shown |
TrackRev plans for link tracking, October 2026.
If you only need to know whether Slack sends sessions, a UTM link and Google Analytics 4 are free and enough, and any shortener with bot filtering covers plain click counts.
The Links and Analytics page lists what a link records.
Found this useful? Share it.
Frequently asked questions
- A click from a chat app often carries neither a referrer nor UTM tags. Add the 3 core tags (utm_source, utm_medium and utm_campaign) to the destination, or share a short link that adds them.
- No. A redirect records device, browser, location, time and referrer, and no member name. A name appears only after the visitor signs up or pays.
- Flag requests whose user agent contains Slackbot or Discordbot, count only the rest, and keep redirecting the flagged ones. A robots.txt Disallow rule will not help, because Slack says it ignores that file.
- Yes, when the link is yours. The count happens when someone requests your short link, so you need no access to the workspace.
- Share a short link that redirects to the invite URL. You count clicks, and a click is not a join. Discord's invite settings control how long an invite lasts and how many times it can be used.
- A tagged URL is enough for Google Analytics 4 sessions by source when the whole URL stays intact. A short link adds a server-side click log, a bot flag and, with a payment connection, revenue per link.

Written by
Founder, TrackRev.io & Contant.io
Muzahid Maruf founded TrackRev.io, SaaS affiliate software with no limit on tracked revenue, and Contant.io. He writes about affiliate programs.
Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth
Stop guessing where your revenue comes from.
Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.
Start free