initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
config.ini
|
||||
.devcontainer/
|
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Reddit notify
|
||||
An app that periodically checks a subreddit for a keyword and will send out an SMTP message if found
|
||||
|
||||
# Config
|
||||
Configuration is done via a `config.ini` file within the same location of the application. Check the example on how to properly set up the `config.ini` file.
|
16
config.ini.example
Normal file
16
config.ini.example
Normal file
@@ -0,0 +1,16 @@
|
||||
# Subreddit to parse
|
||||
subreddit = rabbits
|
||||
|
||||
# Interval (in minutes) to check subreddit
|
||||
interval = 5
|
||||
|
||||
# Keyword to search for within title and text
|
||||
keyword = cute
|
||||
|
||||
# SMTP information
|
||||
smtp_server = localhost
|
||||
smtp_port = 25
|
||||
smtp_username = test
|
||||
smtp_password = test
|
||||
smtp_to = test@test.com
|
||||
smtp_from = test@test.com
|
10
go.mod
Normal file
10
go.mod
Normal file
@@ -0,0 +1,10 @@
|
||||
module reddit_notify
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/mail.v2 v2.3.1 // indirect
|
||||
)
|
8
go.sum
Normal file
8
go.sum
Normal file
@@ -0,0 +1,8 @@
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
|
||||
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
167
main.go
Normal file
167
main.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/buger/jsonparser"
|
||||
"gopkg.in/ini.v1"
|
||||
gomail "gopkg.in/mail.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
subreddit, keyword, smtpServer, smtpTo, smtpFrom, smtpUsername, smtpPassword string
|
||||
interval, smtpPort int
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Load config
|
||||
cfg, err := ini.Load("config.ini")
|
||||
|
||||
if err != nil {
|
||||
quitConfigParseError(err.Error())
|
||||
}
|
||||
|
||||
// Parse and check config values
|
||||
if cfg.Section("app").HasKey("subreddit") {
|
||||
subreddit = cfg.Section("app").Key("subreddit").String()
|
||||
} else {
|
||||
quitConfigParseError("Missing 'subreddit'")
|
||||
}
|
||||
|
||||
if cfg.Section("app").HasKey("interval") {
|
||||
// default to 5 minutes
|
||||
interval = cfg.Section("app").Key("interval").MustInt(5)
|
||||
} else {
|
||||
quitConfigParseError("Missing 'interval'")
|
||||
}
|
||||
|
||||
if cfg.Section("app").HasKey("keyword") {
|
||||
keyword = cfg.Section("app").Key("keyword").String()
|
||||
} else {
|
||||
quitConfigParseError("Missing 'keyword'")
|
||||
}
|
||||
|
||||
if cfg.Section("smtp").HasKey("smtp_server") {
|
||||
smtpServer = cfg.Section("smtp").Key("smtp_server").String()
|
||||
} else {
|
||||
quitConfigParseError("Missing 'smtp_server'")
|
||||
}
|
||||
|
||||
if cfg.Section("smtp").HasKey("smtp_port") {
|
||||
// default to port 25
|
||||
smtpPort = cfg.Section("smtp").Key("smtp_port").MustInt(25)
|
||||
} else {
|
||||
quitConfigParseError("Missing 'smtp_port'")
|
||||
}
|
||||
|
||||
if cfg.Section("smtp").HasKey("smtp_username") {
|
||||
smtpUsername = cfg.Section("smtp").Key("smtp_username").String()
|
||||
} else {
|
||||
quitConfigParseError("Missing 'smtp_username'")
|
||||
}
|
||||
|
||||
if cfg.Section("smtp").HasKey("smtp_password") {
|
||||
smtpPassword = cfg.Section("smtp").Key("smtp_password").String()
|
||||
} else {
|
||||
quitConfigParseError("Missing 'smtp_password'")
|
||||
}
|
||||
|
||||
if cfg.Section("smtp").HasKey("smtp_to") {
|
||||
smtpTo = cfg.Section("smtp").Key("smtp_to").String()
|
||||
} else {
|
||||
quitConfigParseError("Missing 'smtp_to'")
|
||||
}
|
||||
|
||||
if cfg.Section("smtp").HasKey("smtp_from") {
|
||||
smtpFrom = cfg.Section("smtp").Key("smtp_from").String()
|
||||
} else {
|
||||
quitConfigParseError("Missing 'smtp_from'")
|
||||
}
|
||||
|
||||
loop()
|
||||
|
||||
}
|
||||
|
||||
func loop() {
|
||||
// Setup
|
||||
subreddit_rss := "https://www.reddit.com/r/" + subreddit + "/.json"
|
||||
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", subreddit_rss, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Set a header otherwise it'll be blocked
|
||||
req.Header.Set("User-Agent", "Golang_Reddit_Notif/1.0")
|
||||
|
||||
// Continually GET subreddit for interval time
|
||||
for {
|
||||
|
||||
// Get from subreddit
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Response from subreddit
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
|
||||
// Amount of items
|
||||
limit64, _ := jsonparser.GetInt(body, "data", "dist")
|
||||
limit := int(limit64)
|
||||
|
||||
// Loop through titles and texts
|
||||
for i := 0; i < limit; i++ {
|
||||
index := strconv.Itoa(i)
|
||||
title, _ := jsonparser.GetString(body, "data", "children", "["+index+"]", "data", "title")
|
||||
text, _ := jsonparser.GetString(body, "data", "children", "["+index+"]", "data", "selftext")
|
||||
url, _ := jsonparser.GetString(body, "data", "children", "["+index+"]", "data", "url")
|
||||
alert := false
|
||||
|
||||
// Check if keyword matches
|
||||
if strings.Contains(strings.ToLower(title), keyword) {
|
||||
alert = true
|
||||
} else if strings.Contains(strings.ToLower(text), keyword) {
|
||||
alert = true
|
||||
}
|
||||
|
||||
// Send alert if keyword found
|
||||
if alert {
|
||||
sendAlert(title, text, url)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Sleep for interval time
|
||||
time.Sleep(time.Duration(interval) * time.Minute)
|
||||
}
|
||||
}
|
||||
|
||||
func quitConfigParseError(msg string) {
|
||||
fmt.Println("Error parsing config.ini: ", msg)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func sendAlert(title string, text string, url string) {
|
||||
// Setup
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", smtpFrom)
|
||||
m.SetHeader("To", smtpTo)
|
||||
m.SetHeader("Subject", "Reddit Notify: Found match ("+title+")")
|
||||
m.SetBody("text/plain", "Keyword: "+keyword+"\n\n\n"+title+"\n\n\n"+text)
|
||||
|
||||
// Send via gomail
|
||||
d := gomail.NewDialer(smtpServer, smtpPort, smtpUsername, smtpPassword)
|
||||
|
||||
if err := d.DialAndSend(m); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user