Skip to content
This repository has been archived by the owner on Feb 17, 2023. It is now read-only.

Commit

Permalink
Detect iMessage-Preview
Browse files Browse the repository at this point in the history
iMessage uses a bot to show a preview of links in the conversations. It
was wrongly seen by user_agent as Safari 9. This commit adds a hackish
way to detect it, as it impersonates both the Twitter and Facebook bots.
  • Loading branch information
nono committed Apr 15, 2020
1 parent 80733e9 commit e8f5e19
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
5 changes: 5 additions & 0 deletions all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ var uastrings = []struct {
ua: "APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)",
expected: "Browser:APIs-Google Bot:true Mobile:false",
},
{
title: "iMessage-preview",
ua: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/601.2.4 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.4 facebookexternalhit/1.1 Facebot Twitterbot/1.0",
expected: "Mozilla:5.0 Platform:Macintosh Browser:iMessage-Preview-9.0.1 Bot:true Mobile:false",
},

// Internet Explorer
{
Expand Down
20 changes: 20 additions & 0 deletions bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,26 @@ func (p *UserAgent) googleOrBingBot() bool {
return p.undecided
}

// Returns true if we think that it is iMessage-Preview. This function also
// modifies some attributes in the receiver accordingly.
func (p *UserAgent) iMessagePreview() bool {
// iMessage-Preview doesn't advertise itself. We have a to rely on a hack
// to detect it: it impersonates both facebook and twitter bots.
// See https://medium.com/@siggi/apples-imessage-impersonates-twitter-facebook-bots-when-scraping-cef85b2cbb7d
if strings.Index(p.ua, "facebookexternalhit") == -1 {
return false
}
if strings.Index(p.ua, "Twitterbot") == -1 {
return false
}
p.bot = true
p.browser.Name = "iMessage-Preview"
p.browser.Engine = ""
p.browser.EngineVersion = ""
// We don't set the mobile flag because iMessage can be on iOS (mobile) or macOS (not mobile).
return true
}

// Set the attributes of the receiver as given by the parameters. All the other
// parameters are set to empty.
func (p *UserAgent) setSimple(name, version string, bot bool) {
Expand Down
6 changes: 4 additions & 2 deletions operating_systems.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

package user_agent

import "strings"
import (
"strings"
)

// Represents full information on the operating system extracted from the user agent.
type OSInfo struct {
Expand Down Expand Up @@ -100,7 +102,7 @@ func webkit(p *UserAgent, comment []string) {
} else if len(comment) < 2 {
p.localization = comment[0]
} else if len(comment) < 3 {
if !p.googleOrBingBot() {
if !p.googleOrBingBot() && !p.iMessagePreview() {
p.os = normalizeOS(comment[1])
}
} else {
Expand Down

0 comments on commit e8f5e19

Please sign in to comment.