94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
package protocol
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
neturl "net/url"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/status-im/status-go/protocol/common"
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
|
)
|
|
|
|
type OEmbedUnfurler struct {
|
|
logger *zap.Logger
|
|
httpClient *http.Client
|
|
// oembedEndpoint describes where the consumer may request representations for
|
|
// the supported URL scheme. For example, for YouTube, it is
|
|
// https://www.youtube.com/oembed.
|
|
oembedEndpoint string
|
|
// url is the actual URL to be unfurled.
|
|
url *neturl.URL
|
|
}
|
|
|
|
func NewOEmbedUnfurler(oembedEndpoint string,
|
|
url *neturl.URL,
|
|
logger *zap.Logger,
|
|
httpClient *http.Client) *OEmbedUnfurler {
|
|
return &OEmbedUnfurler{
|
|
oembedEndpoint: oembedEndpoint,
|
|
url: url,
|
|
logger: logger,
|
|
httpClient: httpClient,
|
|
}
|
|
}
|
|
|
|
type OEmbedResponse struct {
|
|
Title string `json:"title"`
|
|
ThumbnailURL string `json:"thumbnail_url"`
|
|
}
|
|
|
|
func (u *OEmbedUnfurler) newOEmbedURL() (*neturl.URL, error) {
|
|
oembedURL, err := neturl.Parse(u.oembedEndpoint)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// When format is specified, the provider MUST return data in the requested
|
|
// format, else return an error.
|
|
oembedURL.RawQuery = neturl.Values{
|
|
"url": {u.url.String()},
|
|
"format": {"json"},
|
|
}.Encode()
|
|
|
|
return oembedURL, nil
|
|
}
|
|
|
|
func (u OEmbedUnfurler) Unfurl() (*common.LinkPreview, error) {
|
|
preview := newDefaultLinkPreview(u.url)
|
|
preview.Type = protobuf.UnfurledLink_LINK
|
|
|
|
oembedURL, err := u.newOEmbedURL()
|
|
if err != nil {
|
|
return preview, err
|
|
}
|
|
|
|
headers := map[string]string{
|
|
"accept": headerAcceptJSON,
|
|
"accept-language": headerAcceptLanguage,
|
|
"user-agent": headerUserAgent,
|
|
}
|
|
oembedBytes, err := fetchBody(u.logger, u.httpClient, oembedURL.String(), headers)
|
|
if err != nil {
|
|
return preview, err
|
|
}
|
|
|
|
var oembedResponse OEmbedResponse
|
|
if err != nil {
|
|
return preview, err
|
|
}
|
|
err = json.Unmarshal(oembedBytes, &oembedResponse)
|
|
if err != nil {
|
|
return preview, err
|
|
}
|
|
|
|
if oembedResponse.Title == "" {
|
|
return preview, fmt.Errorf("missing required title in oEmbed response")
|
|
}
|
|
|
|
preview.Title = oembedResponse.Title
|
|
return preview, nil
|
|
}
|