Skip to content

Commit 875ab51

Browse files
authored
Add Reddit history deleting script (#3)
## Describe your changes Addin' a script to delete all Reddit comments and posts from a user that are over 2 years old. ## Checklist before requesting a review - [x] The code runs successfully. ```commandline michaelp@MacBook-Air-18 golang-scripting % make delete-reddit-history go run ./cmd/deleteRedditHistory/main.go ------- Pulling user posts ------- Deleting user posts: 3 ------- Pulling user comments ------- Deleting user comments: 659 michaelp@MacBook-Air-18 golang-scripting % ```
1 parent c5574cf commit 875ab51

File tree

6 files changed

+207
-3
lines changed

6 files changed

+207
-3
lines changed

.github/workflows/audit.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ on:
99
jobs:
1010

1111
audit:
12-
runs-on: ubuntu-20.04
12+
runs-on: ubuntu-latest
1313
steps:
1414
- uses: actions/checkout@v2
1515

1616
- name: Set up Go
1717
uses: actions/setup-go@v2
1818
with:
19-
go-version: 1.22
19+
go-version: 1.23
2020

2121
- name: Verify dependencies
2222
run: go mod verify

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ lint:
1111
go vet ./...
1212
staticcheck ./...
1313

14+
.PHONY: delete-reddit-history
15+
delete-reddit-history:
16+
go run ./cmd/deleteRedditHistory/main.go
17+
1418
.PHONY: parse-slack-data
1519
parse-slack-data:
1620
go run ./cmd/slackMessageParser/main.go

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,17 @@ Various scripts written in Golang.
33

44
## Scripts
55

6+
### Reddit Comment and Post Deleter
7+
This script deletes all comments for a given user that are older than 2 years old. To properly configure, please
8+
create the following environment variables: `REDDIT_USER_ID`, `REDDIT_USER_PASSWORD`, `REDDIT_APP_ID`, `REDDIT_SECRET`.
9+
10+
For information regarding the acquisition of values for the above environment variables, please
11+
check here: [Link](https://github.com/reddit-archive/reddit/wiki/OAuth2-Quick-Start-Example#first-steps).
12+
613
### Slack Message Parser
7-
This tool is used to parse the `json`-formatted data that comes from [exporting Slack workspace data](https://slack.com/help/articles/201658943-Export-your-workspace-data) into a `csv` file named: `slack_records.csv`.
14+
This script is used to parse the `json`-formatted data that comes from
15+
[exporting Slack workspace data](https://slack.com/help/articles/201658943-Export-your-workspace-data) into a `csv`
16+
file named: `slack_records.csv`.
817

918
| TimeStamp | UserID | UserName | RealName | MessageType | Text | Attachments | Files |
1019
|:---------:|:------:|:--------:|:--------:|:-----------:|:------:|:-----------:|:--------:|

cmd/deleteRedditHistory/main.go

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* Copyright (c) 2025 Michael Plunkett (https://github.com/michplunkett)
3+
* All rights reserved.
4+
* Used to delete Reddit user posts and comments older than 2-years-old.
5+
*/
6+
7+
package main
8+
9+
import (
10+
"context"
11+
"fmt"
12+
"log"
13+
"os"
14+
"time"
15+
16+
"github.com/vartanbeno/go-reddit/v2/reddit"
17+
)
18+
19+
type envVars struct {
20+
appID string
21+
appSecret string
22+
userName string
23+
userPassword string
24+
}
25+
26+
const LIMIT = 100
27+
28+
var THRESHOLD = time.Now().AddDate(-2, 0, 0)
29+
30+
func arrayHasNoEmptyStrings(envVars []string) bool {
31+
for _, value := range envVars {
32+
if value == "" {
33+
return false
34+
}
35+
}
36+
37+
return true
38+
}
39+
40+
func main() {
41+
ctx := context.Background()
42+
43+
e := envVars{
44+
os.Getenv("REDDIT_APP_ID"),
45+
os.Getenv("REDDIT_SECRET"),
46+
os.Getenv("REDDIT_USER_ID"),
47+
os.Getenv("REDDIT_USER_PASSWORD"),
48+
}
49+
50+
if !arrayHasNoEmptyStrings([]string{e.appID, e.appSecret, e.userName, e.userPassword}) {
51+
log.Fatal(fmt.Errorf("one of the last.fm environment variables is not present in your system"))
52+
}
53+
54+
credentials := reddit.Credentials{ID: e.appID, Secret: e.appSecret, Username: e.userName, Password: e.userPassword}
55+
cli, clientErr := reddit.NewClient(credentials)
56+
if clientErr != nil {
57+
log.Fatal(clientErr)
58+
}
59+
60+
// Get overview of user
61+
commentService := *cli.Comment
62+
postService := *cli.Post
63+
userService := *cli.User
64+
65+
// Get all posts
66+
fmt.Println("------- Pulling user posts")
67+
68+
lastPostID := ""
69+
postIds := make([]string, 0)
70+
postOptions := &reddit.ListUserOverviewOptions{
71+
ListOptions: reddit.ListOptions{
72+
Limit: LIMIT,
73+
},
74+
Sort: "new",
75+
Time: "all",
76+
}
77+
for {
78+
if lastPostID != "" {
79+
postOptions.ListOptions.After = lastPostID
80+
}
81+
82+
posts, _, err := userService.Posts(ctx, postOptions)
83+
if err != nil {
84+
log.Fatal(err)
85+
}
86+
87+
if len(posts) == 0 {
88+
break
89+
}
90+
91+
for _, post := range posts {
92+
if post.Created.Time.Before(THRESHOLD) ||
93+
post.Created.Time.Equal(THRESHOLD) {
94+
postIds = append(postIds, post.FullID)
95+
}
96+
}
97+
98+
lastPostID = posts[len(posts)-1].FullID
99+
}
100+
101+
// Delete all posts
102+
fmt.Println("------- Deleting user posts:", len(postIds))
103+
for _, pID := range postIds {
104+
_, err := postService.Delete(ctx, pID)
105+
if err != nil {
106+
log.Fatal(err)
107+
}
108+
}
109+
110+
// Get all comments
111+
fmt.Println("------- Pulling user comments")
112+
113+
lastCommentID := ""
114+
commentIds := make([]string, 0)
115+
commentOptions := &reddit.ListUserOverviewOptions{
116+
ListOptions: reddit.ListOptions{
117+
Limit: LIMIT,
118+
},
119+
Sort: "new",
120+
Time: "all",
121+
}
122+
for {
123+
if lastCommentID != "" {
124+
commentOptions.ListOptions.After = lastCommentID
125+
}
126+
127+
comments, _, err := userService.Comments(ctx, commentOptions)
128+
if err != nil {
129+
log.Fatal(err)
130+
}
131+
132+
if len(comments) == 0 {
133+
break
134+
}
135+
136+
for _, c := range comments {
137+
if c.Created.Time.Before(THRESHOLD) ||
138+
c.Created.Time.Equal(THRESHOLD) {
139+
commentIds = append(commentIds, c.FullID)
140+
}
141+
}
142+
143+
lastCommentID = comments[len(comments)-1].FullID
144+
}
145+
146+
// Delete all comments
147+
fmt.Println("------- Deleting user comments:", len(commentIds))
148+
149+
for _, cID := range commentIds {
150+
_, err := commentService.Delete(ctx, cID)
151+
if err != nil {
152+
log.Fatal(err)
153+
}
154+
}
155+
}

go.mod

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,12 @@ module github.com/michplunkett/golang-scripting
33
go 1.22.4
44

55
require github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1
6+
7+
require (
8+
github.com/golang/protobuf v1.2.0 // indirect
9+
github.com/google/go-querystring v1.0.0 // indirect
10+
github.com/vartanbeno/go-reddit/v2 v2.0.1
11+
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e // indirect
12+
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
13+
google.golang.org/appengine v1.4.0 // indirect
14+
)

go.sum

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,29 @@
1+
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
3+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
14
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40yHE5UO3RUdSNPaBC+j3PokzA6OQ=
25
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
6+
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
7+
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
8+
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
9+
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
10+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
11+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
12+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
13+
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
14+
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
15+
github.com/vartanbeno/go-reddit/v2 v2.0.1 h1:P6ITpf5YHjdy7DHZIbUIDn/iNAoGcEoDQnMa+L4vutw=
16+
github.com/vartanbeno/go-reddit/v2 v2.0.1/go.mod h1:758/S10hwZSLm43NPtwoNQdZFSg3sjB5745Mwjb0ANI=
17+
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
18+
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
19+
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
20+
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
21+
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
22+
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
23+
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
24+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
25+
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
26+
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
27+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
28+
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
29+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

0 commit comments

Comments
 (0)