diff --git a/.env.template b/.env.template index fe54f4d..1f0b0c7 100644 --- a/.env.template +++ b/.env.template @@ -1 +1,2 @@ SN_AUTH_COOKIE= +DISCORD_WEBHOOK= diff --git a/discord.go b/discord.go new file mode 100644 index 0000000..6495b60 --- /dev/null +++ b/discord.go @@ -0,0 +1,63 @@ +package main + +import ( + "bytes" + "encoding/json" + "log" + "net/http" + + "github.com/joho/godotenv" + "github.com/namsral/flag" +) + +var ( + DiscordWebhook string +) + +type DiscordEmbedFooter struct { + Text string `json:"text"` + IconUrl string `json:"icon_url"` +} + +type DiscordEmbed struct { + Title string `json:"title"` + Url string `json:"url"` + Color int `json:"color"` + Footer DiscordEmbedFooter `json:"footer"` + Timestamp string `json:"timestamp"` +} + +type DiscordWebhookPayload struct { + Embeds []DiscordEmbed `json:"embeds"` +} + +func init() { + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + flag.StringVar(&DiscordWebhook, "DISCORD_WEBHOOK", "", "Webhook to send logs to discord") + flag.Parse() + if DiscordWebhook == "" { + log.Fatal("DISCORD_WEBHOOK not set") + } +} + +func SendEmbedToDiscord(embed DiscordEmbed) { + bodyJSON, err := json.Marshal( + DiscordWebhookPayload{ + Embeds: []DiscordEmbed{embed}, + }, + ) + if err != nil { + log.Fatal("Error during json.Marshal:", err) + } + req, err := http.NewRequest("POST", DiscordWebhook, bytes.NewBuffer(bodyJSON)) + req.Header.Set("Content-Type", "application/json") + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Println("Discord webhook error:", err) + } + defer resp.Body.Close() +} diff --git a/sn.go b/sn.go index a77f1f6..f3b624e 100644 --- a/sn.go +++ b/sn.go @@ -172,6 +172,7 @@ func PostStoryToStackerNews(story *Story) { log.Println("Created new post on SN") log.Printf("id=%d title='%s' url=%s\n", parentId, story.Title, story.Url) + SendStackerNewsEmbedToDiscord(story.Title, parentId) comment := fmt.Sprintf( "This link was posted by [%s](%s) %s on [HN](%s). It received %d points and %d comments.", @@ -184,6 +185,10 @@ func PostStoryToStackerNews(story *Story) { CommentStackerNewsPost(comment, parentId) } +func StackerNewsItemLink(id int) string { + return fmt.Sprintf("https://stacker.news/items/%d", id) +} + func CommentStackerNewsPost(text string, parentId int) { body := GraphQLPayload{ Query: ` @@ -203,3 +208,20 @@ func CommentStackerNewsPost(text string, parentId int) { log.Println("Commented post on SN") log.Printf("text='%s' parentId=%d\n", text, parentId) } + +func SendStackerNewsEmbedToDiscord(title string, id int) { + Timestamp := time.Now().Format(time.RFC3339) + url := StackerNewsItemLink(id) + color := 0xffc107 + embed := DiscordEmbed{ + Title: title, + Url: url, + Color: color, + Footer: DiscordEmbedFooter{ + Text: "Stacker News", + IconUrl: "https://stacker.news/favicon.png", + }, + Timestamp: Timestamp, + } + SendEmbedToDiscord(embed) +}