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

Commit e8f5e19

Browse files
committed
Detect iMessage-Preview
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.
1 parent 80733e9 commit e8f5e19

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

all_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ var uastrings = []struct {
124124
ua: "APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)",
125125
expected: "Browser:APIs-Google Bot:true Mobile:false",
126126
},
127+
{
128+
title: "iMessage-preview",
129+
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",
130+
expected: "Mozilla:5.0 Platform:Macintosh Browser:iMessage-Preview-9.0.1 Bot:true Mobile:false",
131+
},
127132

128133
// Internet Explorer
129134
{

bot.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@ func (p *UserAgent) googleOrBingBot() bool {
5757
return p.undecided
5858
}
5959

60+
// Returns true if we think that it is iMessage-Preview. This function also
61+
// modifies some attributes in the receiver accordingly.
62+
func (p *UserAgent) iMessagePreview() bool {
63+
// iMessage-Preview doesn't advertise itself. We have a to rely on a hack
64+
// to detect it: it impersonates both facebook and twitter bots.
65+
// See https://medium.com/@siggi/apples-imessage-impersonates-twitter-facebook-bots-when-scraping-cef85b2cbb7d
66+
if strings.Index(p.ua, "facebookexternalhit") == -1 {
67+
return false
68+
}
69+
if strings.Index(p.ua, "Twitterbot") == -1 {
70+
return false
71+
}
72+
p.bot = true
73+
p.browser.Name = "iMessage-Preview"
74+
p.browser.Engine = ""
75+
p.browser.EngineVersion = ""
76+
// We don't set the mobile flag because iMessage can be on iOS (mobile) or macOS (not mobile).
77+
return true
78+
}
79+
6080
// Set the attributes of the receiver as given by the parameters. All the other
6181
// parameters are set to empty.
6282
func (p *UserAgent) setSimple(name, version string, bot bool) {

operating_systems.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
package user_agent
66

7-
import "strings"
7+
import (
8+
"strings"
9+
)
810

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

0 commit comments

Comments
 (0)