From e6bf12fa35eeec4c94dc975a35a0a594eaeca778 Mon Sep 17 00:00:00 2001 From: Manuel Date: Tue, 17 Oct 2023 00:10:00 +0200 Subject: [PATCH] feat: Add embeds, rework embed struct --- cmd/embed.go | 106 +++++++++++++++++++++++++++++-------------------- cmd/webhook.go | 77 ++++++++++++++++++++++++++++++----- 2 files changed, 129 insertions(+), 54 deletions(-) diff --git a/cmd/embed.go b/cmd/embed.go index b06d0d2..7740004 100644 --- a/cmd/embed.go +++ b/cmd/embed.go @@ -4,18 +4,21 @@ import ( "errors" "strconv" "strings" + "time" ) type Embed struct { - Author Author `json:"author"` - Title string `json:"title"` - URL string `json:"url"` - Description string `json:"description"` - Color int64 `json:"color"` - Fields []Field `json:"fields"` + Author Author `json:"author,omitempty"` + Title string `json:"title,omitempty"` + URL string `json:"url,omitempty"` + Description string `json:"description,omitempty"` + Timestamp string `json:"timestamp,omitempty"` + Color int64 `json:"color,omitempty"` + Fields []Field `json:"fields,omitempty"` Thumbnail Image `json:"thumbnail,omitempty"` Image Image `json:"image,omitempty"` - Footer Footer `json:"footer"` + Video Video `json:"video,omitempty"` + Footer Footer `json:"footer,omitempty"` } type Author struct { @@ -39,60 +42,75 @@ type Image struct { URL string `json:"url"` } -func (w *Webhook) NewEmbed(Title, Description, URL string) { - emb := Embed{Title: Title, Description: Description, URL: URL} +type Video struct { + URL string `json:"url"` +} + +func (w *Webhook) NewEmbedWithURL(URL string) *Embed { + emb := Embed{URL: URL} w.Embeds = append(w.Embeds, &emb) + return &emb } -func (w *Webhook) SetAuthor(Name, URL, IconURL string) { - if len(w.Embeds) == 0 { - emb := Embed{Author: Author{Name, URL, IconURL}} - w.Embeds = append(w.Embeds, &emb) - } else { - w.Embeds[0].Author = Author{Name, URL, IconURL} - } +func (w *Webhook) NewEmbed() *Embed { + emb := Embed{} + w.Embeds = append(w.Embeds, &emb) + return &emb } -func (w *Webhook) SetColor(color string) error { +func (e *Embed) SetTitle(Title string) *Embed { + e.Title = Title + return e +} + +func (e *Embed) SetText(Description string) *Embed { + e.Description = Description + return e +} + +func (e *Embed) SetAuthor(Name, URL, IconURL string) *Embed { + e.Author = Author{Name, URL, IconURL} + return e +} + +func (e *Embed) SetColor(color string) (*Embed, error) { color = strings.Replace(color, "0x", "", -1) color = strings.Replace(color, "0X", "", -1) color = strings.Replace(color, "#", "", -1) colorInt, err := strconv.ParseInt(color, 16, 64) if err != nil { - return errors.New("Invalid hex code passed") + return nil, errors.New("Invalid hex code passed") } - w.Embeds[0].Color = colorInt - return nil + e.Color = colorInt + return e, nil } -func (w *Webhook) SetThumbnail(URL string) error { - if len(w.Embeds) < 1 { - return errors.New("Invalid Embed passed in, Webhook.Embeds must have at least one Embed element") - } - w.Embeds[0].Thumbnail = Image{URL} - return nil +func (e *Embed) SetThumbnail(URL string) *Embed { + e.Thumbnail = Image{URL} + return e } -func (w *Webhook) SetImage(URL string) error { - if len(w.Embeds) < 1 { - return errors.New("Invalid Embed passed in, Webhook.Embeds must have at least one Embed element") - } - w.Embeds[0].Image = Image{URL} - return nil +func (e *Embed) SetImage(URL string) *Embed { + e.Image = Image{URL} + return e } -func (w *Webhook) SetFooter(Text, IconURL string) error { - if len(w.Embeds) < 1 { - return errors.New("Invalid Embed passed in, Webhook.Embeds must have at least one Embed element") - } - w.Embeds[0].Footer = Footer{Text, IconURL} - return nil +func (e *Embed) SetVideo(URL string) *Embed { + e.Video = Video{URL} + return e } -func (w *Webhook) AddField(Name, Value string, Inline bool) error { - if len(w.Embeds) < 1 { - return errors.New("Invalid Embed passed in, Webhook.Embeds must have at least one Embed element") - } - w.Embeds[0].Fields = append(w.Embeds[0].Fields, Field{Name, Value, Inline}) - return nil +func (e *Embed) SetFooter(Text, IconURL string) *Embed { + e.Footer = Footer{Text, IconURL} + return e +} + +func (e *Embed) SetTimestamp(timestamp time.Time) *Embed { + e.Timestamp = timestamp.Format(time.RFC3339) + return e +} + +func (e *Embed) AddField(Name, Value string, Inline bool) *Embed { + e.Fields = append(e.Fields, Field{Name, Value, Inline}) + return e } diff --git a/cmd/webhook.go b/cmd/webhook.go index 9969eab..deb9176 100644 --- a/cmd/webhook.go +++ b/cmd/webhook.go @@ -6,6 +6,13 @@ import ( ts "github.com/n0madic/twitter-scraper" "log" "net/http" + "strings" + //"strconv" +) + +const ( + BaseURL = "https://twitter.com/" + BaseIcon = "https://abs.twimg.com/icons/apple-touch-icon-192x192.png" ) type Webhook struct { @@ -25,24 +32,74 @@ type Mention struct { func sendToWebhook(webhookURL string, tweets []*ts.Tweet) { for _, tweet := range tweets { - // Temporarily hardcoded data := Webhook{ - Content: tweet.PermanentURL, + Content: "<" + tweet.PermanentURL + ">", Mention: &Mention{Parse: []string{"roles"}}, - Embeds: []*Embed{}, } - jsonData, err := json.Marshal(data) + urlsToAppend := []string{} + userUrl := BaseURL + tweet.Username + + mainEmbed := data.NewEmbedWithURL(tweet.PermanentURL) + mainEmbed.SetAuthor(tweet.Name+" (@"+tweet.Username+")", userUrl, "https://unavatar.io/twitter/"+tweet.Username) + mainEmbed.SetText(tweet.Text) + mainEmbed.SetColor("#26a7de") + mainEmbed.SetFooter("Twitter", BaseIcon) + mainEmbed.SetTimestamp(tweet.TimeParsed) + //mainEmbed.SetFooter("Twitter • ", BaseIcon) + + for i, photo := range tweet.Photos { + embed := mainEmbed + if i > 0 { + embed = data.NewEmbedWithURL(tweet.PermanentURL) + } + embed.SetImage(photo.URL) + } + for i, gif := range tweet.GIFs { + embed := mainEmbed + if i > 0 { + embed = data.NewEmbedWithURL(tweet.PermanentURL) + } + embed.SetImage(gif.Preview) + } + for i, video := range tweet.Videos { + embed := mainEmbed + if i > 0 { + embed = data.NewEmbedWithURL(tweet.PermanentURL) + } + // Video embeds are not supported right now + embed.SetImage(video.Preview) + embed.SetVideo(video.URL) // This has sadly no effect + urlsToAppend = append(urlsToAppend, strings.Replace(tweet.PermanentURL, "twitter", "fxtwitter", 1)) + } + + err := sendRequest(webhookURL, &data) if err != nil { - log.Printf("Error while generating JSON for tweet %s: %s", tweet.ID, err.Error()) + log.Println("Error while sending webhook for tweet %s: %s", tweet.ID, err.Error()) continue } - resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(jsonData)) - if err != nil { - log.Printf("Error while sending webhook for tweet %s: %s", tweet.ID, err.Error()) - continue + for _, url := range urlsToAppend { + err := sendRequest(webhookURL, &Webhook{Content: url}) + if err != nil { + log.Println("Error while sending webhook for tweet %s: %s", tweet.ID, err.Error()) + continue + } } - defer resp.Body.Close() } } + +func sendRequest(url string, data *Webhook) error { + jsonData, err := json.Marshal(data) + if err != nil { + return err + } + + resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData)) + defer resp.Body.Close() + if err != nil { + return err + } + + return nil +}