53 lines
1.1 KiB
Go
53 lines
1.1 KiB
Go
package shorturl
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// botSubstrings catches the named social-platform link previewers explicitly,
|
|
// so we don't over-count human clicks from OG scraping.
|
|
var botSubstrings = []string{
|
|
"facebookexternalhit",
|
|
"facebot",
|
|
"twitterbot",
|
|
"linkedinbot",
|
|
"slackbot",
|
|
"telegrambot",
|
|
"discordbot",
|
|
"pinterest",
|
|
"whatsapp",
|
|
"applebot",
|
|
"googlebot",
|
|
"bingbot",
|
|
"yahoo! slurp",
|
|
"duckduckbot",
|
|
"baiduspider",
|
|
"yandex",
|
|
"redditbot",
|
|
"embedly",
|
|
"vkshare",
|
|
"viber",
|
|
"signal",
|
|
"skypeuripreview",
|
|
}
|
|
|
|
var botFallbackRe = regexp.MustCompile(`(?i)\b(bot|crawler|spider|preview|fetch)\b`)
|
|
|
|
// IsBot returns true if the user-agent looks like an OG scraper / search
|
|
// crawler / link previewer, rather than a real human browser. False positives
|
|
// here only affect analytics aggregation (the is_bot flag); they never change
|
|
// redirect behavior.
|
|
func IsBot(userAgent string) bool {
|
|
if userAgent == "" {
|
|
return true // missing UA is almost always a bot or curl
|
|
}
|
|
ua := strings.ToLower(userAgent)
|
|
for _, needle := range botSubstrings {
|
|
if strings.Contains(ua, needle) {
|
|
return true
|
|
}
|
|
}
|
|
return botFallbackRe.MatchString(ua)
|
|
}
|