parent
b30baea549
commit
68acb55eee
|
@ -23,19 +23,19 @@ type RedditConfig struct {
|
||||||
type SubReddit struct {
|
type SubReddit struct {
|
||||||
Name string `toml:"name"`
|
Name string `toml:"name"`
|
||||||
IconURL string `toml:"icon_url"`
|
IconURL string `toml:"icon_url"`
|
||||||
FlairWhitelist []string `toml:"flair_whitelist"`
|
FlairAllowlist []string `toml:"flair_allowlist"`
|
||||||
FlairWhitelistRe []*regexp.Regexp `toml:"-"`
|
FlairAllowlistRe []*regexp.Regexp `toml:"-"`
|
||||||
FlairBlacklist []string `toml:"flair_blacklist"`
|
FlairBlocklist []string `toml:"flair_blocklist"`
|
||||||
FlairBlacklistRe []*regexp.Regexp `toml:"-"`
|
FlairBlocklistRe []*regexp.Regexp `toml:"-"`
|
||||||
TitleWhitelist []string `toml:"title_whitelist"`
|
TitleAllowlist []string `toml:"title_allowlist"`
|
||||||
TitleWhitelistRe []*regexp.Regexp `toml:"-"`
|
TitleAllowlistRe []*regexp.Regexp `toml:"-"`
|
||||||
TitleBlacklist []string `toml:"title_blacklist"`
|
TitleBlocklist []string `toml:"title_blocklist"`
|
||||||
TitleBlacklistRe []*regexp.Regexp `toml:"-"`
|
TitleBlocklistRe []*regexp.Regexp `toml:"-"`
|
||||||
TitleLimit int `toml:"title_limit"`
|
TitleLimit int `toml:"title_limit"`
|
||||||
BodyWhitelist []string `toml:"body_whitelist"`
|
BodyAllowlist []string `toml:"body_allowlist"`
|
||||||
BodyWhitelistRe []*regexp.Regexp `toml:"-"`
|
BodyAllowlistRe []*regexp.Regexp `toml:"-"`
|
||||||
BodyBlacklist []string `toml:"body_blacklist"`
|
BodyBlocklist []string `toml:"body_blocklist"`
|
||||||
BodyBlacklistRe []*regexp.Regexp `toml:"-"`
|
BodyBlocklistRe []*regexp.Regexp `toml:"-"`
|
||||||
BodyLimit int `toml:"body_limit"`
|
BodyLimit int `toml:"body_limit"`
|
||||||
Webhook string `toml:"webhook"`
|
Webhook string `toml:"webhook"`
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -8,4 +8,5 @@ require (
|
||||||
github.com/pelletier/go-toml v1.8.1
|
github.com/pelletier/go-toml v1.8.1
|
||||||
github.com/turnage/graw v0.0.0-20200404033202-65715eea1cd0
|
github.com/turnage/graw v0.0.0-20200404033202-65715eea1cd0
|
||||||
go.jolheiser.com/beaver v1.0.2
|
go.jolheiser.com/beaver v1.0.2
|
||||||
|
go.jolheiser.com/disco v0.0.2
|
||||||
)
|
)
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -32,6 +32,8 @@ github.com/turnage/redditproto v0.0.0-20151223012412-afedf1b6eddb h1:qR56NGRvs2h
|
||||||
github.com/turnage/redditproto v0.0.0-20151223012412-afedf1b6eddb/go.mod h1:GyqJdEoZSNoxKDb7Z2Lu/bX63jtFukwpaTP9ZIS5Ei0=
|
github.com/turnage/redditproto v0.0.0-20151223012412-afedf1b6eddb/go.mod h1:GyqJdEoZSNoxKDb7Z2Lu/bX63jtFukwpaTP9ZIS5Ei0=
|
||||||
go.jolheiser.com/beaver v1.0.2 h1:KA2D6iO8MQhZi1nZYi/Chak/f1Cxfrs6b1XO623+Khk=
|
go.jolheiser.com/beaver v1.0.2 h1:KA2D6iO8MQhZi1nZYi/Chak/f1Cxfrs6b1XO623+Khk=
|
||||||
go.jolheiser.com/beaver v1.0.2/go.mod h1:7X4F5+XOGSC3LejTShoBdqtRCnPWcnRgmYGmG3EKW8g=
|
go.jolheiser.com/beaver v1.0.2/go.mod h1:7X4F5+XOGSC3LejTShoBdqtRCnPWcnRgmYGmG3EKW8g=
|
||||||
|
go.jolheiser.com/disco v0.0.2 h1:UGYNqO7NQSBGB/OoS9WE5o/jYvmx1G0Bq3qQRM42Bkw=
|
||||||
|
go.jolheiser.com/disco v0.0.2/go.mod h1:tY3HkJmMrzXH/bPgDWKHn1DUzDxkemD80OHLgHSA5uQ=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -13,30 +12,11 @@ import (
|
||||||
|
|
||||||
"github.com/turnage/graw/reddit"
|
"github.com/turnage/graw/reddit"
|
||||||
"go.jolheiser.com/beaver"
|
"go.jolheiser.com/beaver"
|
||||||
|
"go.jolheiser.com/disco"
|
||||||
)
|
)
|
||||||
|
|
||||||
var httpClient = &http.Client{Timeout: time.Minute}
|
var httpClient = &http.Client{Timeout: time.Minute}
|
||||||
|
|
||||||
type Webhook struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
AvatarURL string `json:"avatar_url"`
|
|
||||||
Embeds []Embed `json:"embeds"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Embed struct {
|
|
||||||
Title string `json:"title"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Color int64 `json:"color"`
|
|
||||||
Timestamp time.Time `json:"timestamp"`
|
|
||||||
Author Author `json:"author"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Author struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Reddit struct {
|
type Reddit struct {
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
}
|
}
|
||||||
|
@ -58,37 +38,36 @@ func (r *Reddit) Post(p *reddit.Post) error {
|
||||||
description = description[:sub.BodyLimit] + "..."
|
description = description[:sub.BodyLimit] + "..."
|
||||||
}
|
}
|
||||||
|
|
||||||
e := Webhook{
|
e := disco.Webhook{
|
||||||
Username: "/r/" + p.Subreddit,
|
Username: "/r/" + p.Subreddit,
|
||||||
AvatarURL: sub.IconURL,
|
AvatarURL: sub.IconURL,
|
||||||
Embeds: []Embed{
|
Embeds: []*disco.Embed{
|
||||||
{
|
{
|
||||||
Title: title,
|
Title: title,
|
||||||
URL: p.URL,
|
URL: p.URL,
|
||||||
Description: description,
|
Description: description,
|
||||||
Color: 16312092, // Yellow
|
Color: 16312092, // Yellow
|
||||||
Timestamp: time.Now(),
|
Timestamp: disco.Now(),
|
||||||
Author: Author{
|
Author: &disco.Author{
|
||||||
Name: "/u/" + p.Author,
|
Name: "/u/" + p.Author,
|
||||||
URL: fmt.Sprintf("https://reddit.com/user/%s", p.Author),
|
URL: fmt.Sprintf("https://reddit.com/user/%s", p.Author),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
data, err := json.Marshal(e)
|
|
||||||
if err != nil {
|
|
||||||
beaver.Error(err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
beaver.Debug(string(data))
|
|
||||||
|
|
||||||
if sub.Webhook == "" {
|
if sub.Webhook == "" {
|
||||||
beaver.Errorf("no webhook for %s", p.Subreddit)
|
beaver.Errorf("no webhook for %s", p.Subreddit)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
payload := bytes.NewBuffer(data)
|
req, err := e.Request(context.Background(), sub.Webhook)
|
||||||
resp, err := httpClient.Post(sub.Webhook, "application/json", payload)
|
if err != nil {
|
||||||
|
beaver.Error(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
beaver.Error(err)
|
beaver.Error(err)
|
||||||
return nil
|
return nil
|
||||||
|
@ -105,29 +84,29 @@ func (r *Reddit) Post(p *reddit.Post) error {
|
||||||
func checkPost(c *config.Config, p *reddit.Post) error {
|
func checkPost(c *config.Config, p *reddit.Post) error {
|
||||||
sub := c.Reddit.Map[strings.ToLower(p.Subreddit)]
|
sub := c.Reddit.Map[strings.ToLower(p.Subreddit)]
|
||||||
|
|
||||||
// Check blacklist first
|
// Check blocklist first
|
||||||
// Any match means we ignore
|
// Any match means we ignore
|
||||||
if matchesAny(p.LinkFlairText, sub.FlairBlacklistRe) {
|
if matchesAny(p.LinkFlairText, sub.FlairBlocklistRe) {
|
||||||
return fmt.Errorf("flair matched blacklisted regex: %s", p.LinkFlairText)
|
return fmt.Errorf("flair matched blocklisted regex: %s", p.LinkFlairText)
|
||||||
}
|
}
|
||||||
if matchesAny(p.Title, sub.TitleBlacklistRe) {
|
if matchesAny(p.Title, sub.TitleBlocklistRe) {
|
||||||
return fmt.Errorf("title matched blacklisted regex: %s", p.Title)
|
return fmt.Errorf("title matched blocklisted regex: %s", p.Title)
|
||||||
}
|
}
|
||||||
if matchesAny(p.SelfText, sub.BodyBlacklistRe) {
|
if matchesAny(p.SelfText, sub.BodyBlocklistRe) {
|
||||||
return fmt.Errorf("body matched blacklisted regex: %s", p.SelfText)
|
return fmt.Errorf("body matched blocklisted regex: %s", p.SelfText)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whitelist
|
// Check allowlist
|
||||||
// Any match means we pass
|
// Any match means we pass
|
||||||
// If no whitelist, pass
|
// If no allowlist, pass
|
||||||
if len(sub.FlairWhitelistRe) > 0 && !matchesAny(p.LinkFlairText, sub.FlairWhitelistRe) {
|
if len(sub.FlairAllowlistRe) > 0 && !matchesAny(p.LinkFlairText, sub.FlairAllowlistRe) {
|
||||||
return fmt.Errorf("flair didn't match any whitelisted regex: %s", p.LinkFlairText)
|
return fmt.Errorf("flair didn't match any allowlisted regex: %s", p.LinkFlairText)
|
||||||
}
|
}
|
||||||
if len(sub.TitleWhitelistRe) > 0 && !matchesAny(p.Title, sub.TitleWhitelistRe) {
|
if len(sub.TitleAllowlistRe) > 0 && !matchesAny(p.Title, sub.TitleAllowlistRe) {
|
||||||
return fmt.Errorf("title didn't match any whitelisted regex: %s", p.Title)
|
return fmt.Errorf("title didn't match any allowlisted regex: %s", p.Title)
|
||||||
}
|
}
|
||||||
if len(sub.BodyWhitelistRe) > 0 && !matchesAny(p.SelfText, sub.BodyWhitelistRe) {
|
if len(sub.BodyAllowlistRe) > 0 && !matchesAny(p.SelfText, sub.BodyAllowlistRe) {
|
||||||
return fmt.Errorf("body didn't match any whitelisted regex: %s", p.SelfText)
|
return fmt.Errorf("body didn't match any allowlisted regex: %s", p.SelfText)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -23,6 +23,10 @@ func (t *Twitter) Run() {
|
||||||
demux.Tweet = func(tweet *twitter.Tweet) {
|
demux.Tweet = func(tweet *twitter.Tweet) {
|
||||||
beaver.Debugf("new tweet for %v", t.Filter)
|
beaver.Debugf("new tweet for %v", t.Filter)
|
||||||
if t.Filter.FollowStrict {
|
if t.Filter.FollowStrict {
|
||||||
|
if tweet.InReplyToStatusIDStr != "" {
|
||||||
|
beaver.Debug("tweet is a reply")
|
||||||
|
return
|
||||||
|
}
|
||||||
var match bool
|
var match bool
|
||||||
for _, id := range t.Filter.Follows {
|
for _, id := range t.Filter.Follows {
|
||||||
if id == tweet.User.IDStr {
|
if id == tweet.User.IDStr {
|
||||||
|
|
|
@ -13,17 +13,17 @@
|
||||||
password = ""
|
password = ""
|
||||||
|
|
||||||
# A list of subreddites to monitor
|
# A list of subreddites to monitor
|
||||||
# white/blacklist can be omitted in real config if empty
|
# allow/blocklist can be omitted in real config if empty
|
||||||
[[reddit.sub]]
|
[[reddit.sub]]
|
||||||
name = ""
|
name = ""
|
||||||
icon_url = ""
|
icon_url = ""
|
||||||
flair_whitelist = []
|
flair_allowlist = []
|
||||||
flair_blacklist = []
|
flair_blocklist = []
|
||||||
title_whitelist = []
|
title_allowlist = []
|
||||||
title_blacklist = []
|
title_blocklist = []
|
||||||
title_limit = 0
|
title_limit = 0
|
||||||
body_whitelist = []
|
body_allowlist = []
|
||||||
body_blacklist = []
|
body_blocklist = []
|
||||||
body_limit = 0
|
body_limit = 0
|
||||||
webhook = ""
|
webhook = ""
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue