Skip to content

Commit ec7f54a

Browse files
committed
feat: Support Reddit searching
Reddit API is rate limited and current stats are returned in response headers.
1 parent a354f92 commit ec7f54a

File tree

4 files changed

+95
-1
lines changed

4 files changed

+95
-1
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Find opinions about given phrase (also URL) on social news websites:
66

77
- _[Lemmy](https://en.wikipedia.org/wiki/Lemmy_(social_network))_
88
- _[Lobsters](https://lobste.rs/about)_
9-
- _[Hacker News](https://en.wikipedia.org/wiki/Hacker_News)_.
9+
- _[Hacker News](https://en.wikipedia.org/wiki/Hacker_News)_
10+
- _[Reddit](https://en.wikipedia.org/wiki/Reddit)_.
1011

1112
It can be used for [including discussions on static websites/blogs](#static-site-generators).
1213

@@ -29,6 +30,8 @@ Hacker News https://news.ycombinator.com/item?id=31840331 The Grug Brained Devel
2930
Hacker News https://news.ycombinator.com/item?id=38076886 The Grug Brained Developer (2022) https://grugbrain.dev/
3031
Lobsters https://lobste.rs/s/ifaar4/grug_brained_developer The Grug Brained Developer https://grugbrain.dev/
3132
Lobsters https://lobste.rs/s/pmpc9v/grug_brained_developer The Grug Brained Developer http://grugbrain.dev
33+
Reddit https://reddit.com/r/programming/comments/16gt8w4/the_grug_brained_developer/ The grug brained developer https://grugbrain.dev
34+
Reddit https://reddit.com/r/brdev/comments/14jhm17/the_grug_brained_developer/ The Grug Brained Developer https://grugbrain.dev
3235
```
3336
3437
The result is printed to stdout as rows in format: `<service_name><tab><URL><tab><title><tab><source_domain>`.

cmd/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func main() {
4141
opinions.SearchHackerNews,
4242
opinions.SearchLemmy,
4343
opinions.SearchLobsters,
44+
opinions.SearchReddit,
4445
}
4546

4647
wg := new(sync.WaitGroup)

reddit.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package opinions
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/url"
9+
10+
"github.com/macie/opinions/http"
11+
)
12+
13+
// RedditResponse represents some interesting fields of response from Reddit API.
14+
type RedditResponse struct {
15+
Data struct {
16+
Children []struct {
17+
Data struct {
18+
ID string `json:"permalink"`
19+
Title string `json:"title"`
20+
URL string `json:"url"`
21+
NumComments int `json:"num_comments"`
22+
} `json:"data"`
23+
} `json:"children"`
24+
} `json:"data"`
25+
}
26+
27+
// SearchReddit searches Reddit for given query and returns list of discussions
28+
// sorted by relevance.
29+
//
30+
// See: https://www.reddit.com/dev/api#GET_search
31+
func SearchReddit(ctx context.Context, client http.Client, query string) ([]Discussion, error) {
32+
discussions := make([]Discussion, 0)
33+
searchURL := "https://www.reddit.com/search.json?sort=relevance&t=all&q="
34+
35+
r, err := client.Get(ctx, searchURL+url.QueryEscape(query))
36+
if err != nil {
37+
return discussions, err
38+
}
39+
defer r.Body.Close()
40+
41+
if r.StatusCode != http.StatusOK {
42+
if r.Header.Get("X-Ratelimit-Remaining") == "0" { // https://support.reddithelp.com/hc/en-us/articles/16160319875092-Reddit-Data-API-Wiki
43+
return discussions, fmt.Errorf("cannot search Reddit: too many requests. Wait %s seconds", r.Header.Get("X-Ratelimit-Reset"))
44+
}
45+
46+
return discussions, fmt.Errorf("cannot search Reddit: `GET %s` responded with status code %d", r.Request.URL, r.StatusCode)
47+
}
48+
49+
body, err := io.ReadAll(r.Body)
50+
if err != nil {
51+
return discussions, err
52+
}
53+
54+
var response RedditResponse
55+
if err := json.Unmarshal(body, &response); err != nil {
56+
return discussions, err
57+
}
58+
59+
for _, entry := range response.Data.Children {
60+
discussions = append(discussions, Discussion{
61+
Service: "Reddit",
62+
URL: "https://reddit.com" + entry.Data.ID,
63+
Title: entry.Data.Title,
64+
Source: entry.Data.URL,
65+
Comments: entry.Data.NumComments,
66+
})
67+
}
68+
69+
return discussions, nil
70+
}

reddit_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package opinions
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/macie/opinions/ensure"
8+
"github.com/macie/opinions/http"
9+
)
10+
11+
func ExampleSearchReddit() {
12+
client := http.Client{}
13+
query := "https://grugbrain.dev/"
14+
15+
opinions := ensure.MustReturn(SearchReddit(context.TODO(), client, query))
16+
17+
fmt.Println(opinions[0])
18+
// Output:
19+
// Reddit https://reddit.com/r/hypeurls/comments/17k6i1l/the_grug_brained_developer_2022/ The Grug Brained Developer (2022) https://grugbrain.dev/
20+
}

0 commit comments

Comments
 (0)