Skip to content

Commit

Permalink
Merge pull request #2 from joshuafhiggins/rich-link-fix
Browse files Browse the repository at this point in the history
Rich link fix
  • Loading branch information
joshuafhiggins authored Apr 14, 2024
2 parents 2e76135 + ee5cf0e commit b06669d
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 4 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (

require (
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/lib/pq v1.10.9 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20O
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a h1:etIrTD8BQqzColk9nKRusM9um5+1q0iOEJLqfBMIK64=
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a/go.mod h1:emQhSYTXqB0xxjLITTw4EaWZ+8IIQYw+kx9GqNUKdLg=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
Expand Down Expand Up @@ -51,13 +53,19 @@ golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
Expand Down
114 changes: 110 additions & 4 deletions imessage/bluebubbles/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"math"
"math/rand"
"mime/multipart"
"net"
"net/http"
"net/url"
"os"
Expand All @@ -19,6 +20,7 @@ import (
"time"
"unicode"

"github.com/dyatlov/go-opengraph/opengraph"
"github.com/gorilla/websocket"
"github.com/rs/zerolog"
"github.com/sahilm/fuzzy"
Expand Down Expand Up @@ -1107,6 +1109,7 @@ func (bb *blueBubbles) SendMessage(chatID, text string, replyTo string, replyToP
TempGUID: fmt.Sprintf("temp-%s", RandString(8)),
SelectedMessageGUID: replyTo,
PartIndex: replyToPart,
DDScan: bb.usingPrivateAPI,
}

var res SendTextResponse
Expand Down Expand Up @@ -1705,14 +1708,117 @@ func (bb *blueBubbles) convertBBMessageToiMessage(bbMessage Message) (*imessage.
message.GroupActionType = imessage.GroupActionType(bbMessage.GroupActionType)
message.NewGroupName = bbMessage.GroupTitle

// TODO Richlinks
// message.RichLink =

message.ThreadID = bbMessage.ThreadOriginatorGUID

// Was the text a URL, does BB have a ddScan for it, did it come with any attachements because of the scan
if IsUrl(bbMessage.Text) && bbMessage.HasDDResults && len(message.Attachments) > 0 {
var reader io.Reader
resp, err := http.Get(bbMessage.Text)
if err != nil {
bb.bridge.GetLog().Errorfln("Error while fetching url: %v", err)
return &message, nil
}
reader = resp.Body

// Fetch the data ourselves because the payloadData object is raw from the iMessage DB, from BB.
// That would require a ton of parsing that the BB app does client side to become something useable but it's written in Dart
// See https://github.com/BlueBubblesApp/bluebubbles-app/blob/d0257c9080e82140602340b48f85fa148721553c/lib/models/global/payload_data.dart
og := opengraph.NewOpenGraph()
if err := og.ProcessHTML(reader); err != nil {
bb.bridge.GetLog().Errorfln("Error processing html: %v", err)
return &message, nil
}

// Was there any OpenGraph tags? Sometimes ddScan is able to produce data without them
// But this is the compromise for not wanting to parse payloadData
if og != nil && og.SiteName != "" {
message.RichLink = &imessage.RichLink{}
message.RichLink.OriginalURL = og.URL
message.RichLink.URL = og.URL
message.RichLink.SiteName = og.SiteName
message.RichLink.Title = og.Title
if og.Description != "" {
message.RichLink.Summary = og.Description
} else {
message.RichLink.Summary = og.URL
}
if og.Profile != nil {
message.RichLink.Creator = og.Profile.Username
}

// It's always assumed that the first attachment is the icon, the second is the banenr image
var icon []byte
var err error
if len(message.Attachments) > 0 && message.Attachments[0] != nil {
icon, err = message.Attachments[0].Read()
}
if err == nil {
message.RichLink.Icon = &imessage.RichLinkAsset{}
// Don't add URLs, if the icon is empty then it wil attempt to fetch the icon with the URL
// The library used also doesn't provide anything for an icon
//message.RichLink.Icon.OriginalURL = og.URL + "/favicon.ico"
message.RichLink.Icon.Source = &imessage.RichLinkAssetSource{}
message.RichLink.Icon.Source.Data = icon
//message.RichLink.Icon.Source.URL = og.URL + "/favicon.ico"
}

if len(og.Images) > 0 {
message.RichLink.Image = &imessage.RichLinkAsset{}
message.RichLink.Image.OriginalURL = og.Images[0].URL
var image []byte
var err error
if len(message.Attachments) > 1 && message.Attachments[1] != nil {
image, err = message.Attachments[1].Read()
}
if err == nil && image != nil {
message.RichLink.Image.Source = &imessage.RichLinkAssetSource{}
message.RichLink.Image.Source.URL = og.Images[0].URL
message.RichLink.Image.Source.Data = image
}
message.RichLink.Image.MimeType = og.Images[0].Type
message.RichLink.Image.Size = &imessage.RichLinkAssetSize{}
message.RichLink.Image.Size.Height = float64(og.Images[0].Height)
message.RichLink.Image.Size.Width = float64(og.Images[0].Width)
}

if len(og.Videos) > 0 {
message.RichLink.Video = &imessage.RichLinkVideoAsset{}
message.RichLink.Video.StreamingURL = og.Videos[0].URL
message.RichLink.Video.YouTubeURL = og.Videos[0].URL
message.RichLink.Video.Asset.OriginalURL = og.Videos[0].URL
message.RichLink.Video.Asset.Source = &imessage.RichLinkAssetSource{}
message.RichLink.Video.Asset.Source.URL = og.Videos[0].URL
message.RichLink.Video.Asset.MimeType = og.Videos[0].Type
message.RichLink.Video.Asset.Size = &imessage.RichLinkAssetSize{}
message.RichLink.Video.Asset.Size.Height = float64(og.Videos[0].Height)
message.RichLink.Video.Asset.Size.Width = float64(og.Videos[0].Width)
}
}
resp.Body.Close()

// Remove the attachments iMessage sent to display the link
// We want to remove them even if we don't have OpenGraph data because ddScan probably sent attachments
message.Attachments = make([]*imessage.Attachment, 0)
}

return &message, nil
}

func IsUrl(str string) bool {
url, err := url.ParseRequestURI(str)
if err != nil {
return false
}

address := net.ParseIP(url.Host)

if address == nil {
return strings.Contains(url.Host, ".")
}

return true
}

func (bb *blueBubbles) convertBBTapbackToImessageTapback(associatedMessageType string) (tbType imessage.TapbackType) {
if strings.Contains(associatedMessageType, "love") {
tbType = imessage.TapbackLove
Expand Down Expand Up @@ -1901,7 +2007,7 @@ func (bb *blueBubbles) Capabilities() imessage.ConnectorCapabilities {
MessageStatusCheckpoints: false,
DeliveredStatus: bb.usingPrivateAPI,
ContactChatMerging: false,
RichLinks: false,
RichLinks: bb.usingPrivateAPI,
ChatBridgeResult: false,
}
}
1 change: 1 addition & 0 deletions imessage/bluebubbles/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ type SendTextRequest struct {
Subject string `json:"subject,omitempty"`
SelectedMessageGUID string `json:"selectedMessageGuid,omitempty"`
PartIndex int `json:"partIndex,omitempty"`
DDScan bool `json:"ddScan,omitempty"`
}

type UnsendMessage struct {
Expand Down

0 comments on commit b06669d

Please sign in to comment.