From fe88a07676c479e5f51ef3e6ce65d00028537511 Mon Sep 17 00:00:00 2001 From: fade Date: Thu, 25 Aug 2022 15:23:44 -0400 Subject: [PATCH] add limits --- .gitignore | 3 +- README.md | 3 ++ bot.go | 34 +++++++++++------ config.go | 2 + config.json | 5 ++- limits.go | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 4 +- 7 files changed, 145 insertions(+), 14 deletions(-) create mode 100644 limits.go diff --git a/.gitignore b/.gitignore index 540ce7b..b865828 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ go.mod go.sum -mastodon-group-bot \ No newline at end of file +mastodon-group-bot +*.db diff --git a/README.md b/README.md index 6ffd52c..699585b 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ The bot is configured in a JSON file that looks like this: "ClientSecret": "0000000000000000000000000000000000000000000", "AccessToken": "0000000000000000000000000000000000000000000", "WelcomeMessage": "We have a new member in our group. Please love and favor" + "Max_toots": 1, + "Toots_interval": 24, + "Admins": ["admin@example.com"] } ``` diff --git a/bot.go b/bot.go index 2057e23..8e72c4d 100644 --- a/bot.go +++ b/bot.go @@ -48,36 +48,48 @@ func run_bot(Conf Config) { // New follower if notif.Type == "follow" { - var message = fmt.Sprintf("%s @%s", Conf.WelcomeMessage, notif.Account.Acct) - postToot(message, "public") + acct := notif.Account.Acct + if !followed(acct) { // Add to db and post welcome message + add_to_db(acct, Conf.Max_toots) + var message = fmt.Sprintf("%s @%s", Conf.WelcomeMessage, acct) + postToot(message, "public") + } } // Read message if notif.Type == "mention" { - for i := 0; i < len(followers); i++ { // Follow check - if notif.Status.Account.Acct == string(followers[i].Acct) { + acct := notif.Status.Account.Acct + for i := 0; i < len(followers); i++ { + if acct == string(followers[i].Acct) { // Follow check if notif.Status.Visibility == "public" { // Reblog toot - if notif.Status.InReplyToID == nil { - c.Reblog(ctx, notif.Status.ID) + if notif.Status.InReplyToID == nil { // Not boost replies + if !followed(acct) { // Add to db if needed + add_to_db(acct, Conf.Max_toots) + } + if check_ticket(acct, Conf.Max_toots, Conf.Toots_interval) > 0 { // Limit + take_ticket(acct) + c.Reblog(ctx, notif.Status.ID) + } } } else if notif.Status.Visibility == "direct" { // Admin commands for y := 0; y < len(Conf.Admins); y++ { - if notif.Status.Account.Acct == Conf.Admins[y] { + if acct == Conf.Admins[y] { text := notif.Status.Content recmd := regexp.MustCompile(`<.*?> `) command := recmd.ReplaceAllString(text, "") args := strings.Split(command, " ") + mID := mastodon.ID((args[1])) if len(args) == 2 { switch args[0] { case "unboost": - c.Unreblog(ctx, mastodon.ID((args[1]))) + c.Unreblog(ctx, mID) case "delete": - c.DeleteStatus(ctx, mastodon.ID(args[1])) + c.DeleteStatus(ctx, mID) case "block": - c.AccountBlock(ctx, mastodon.ID(args[1])) + c.AccountBlock(ctx, mID) case "unblock": - c.AccountUnblock(ctx, mastodon.ID(args[1])) + c.AccountUnblock(ctx, mID) } } } else { diff --git a/config.go b/config.go index 98beadf..1c88362 100644 --- a/config.go +++ b/config.go @@ -13,6 +13,8 @@ type Config struct { ClientSecret string `json:"ClientSecret"` AccessToken string `json:"AccessToken"` WelcomeMessage string `json:"WelcomeMessage"` + Max_toots uint16 `json:"Max_toots"` + Toots_interval uint16 `json:"Toots_interval"` Admins []string `json:"Admins"` } diff --git a/config.json b/config.json index 9b21f67..5b95271 100644 --- a/config.json +++ b/config.json @@ -3,5 +3,8 @@ "ClientID": "0000000000000000000000000000000000000000000", "ClientSecret": "0000000000000000000000000000000000000000000", "AccessToken": "0000000000000000000000000000000000000000000", - "WelcomeMessage": "We have a new member in our group. Please love and favor" + "WelcomeMessage": "We have a new member in our group. Please love and favor", + "Max_toots": 1, + "Toots_interval": 24, + "Admins": ["admin@example.com"] } \ No newline at end of file diff --git a/limits.go b/limits.go new file mode 100644 index 0000000..dd84e1b --- /dev/null +++ b/limits.go @@ -0,0 +1,108 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + "time" + + _ "github.com/mattn/go-sqlite3" +) + +// Init database +func init_limit_db() *sql.DB { + db, err := sql.Open("sqlite3", "limits.db") + if err != nil { + log.Fatal(err) + } + cmd := `CREATE TABLE IF NOT EXISTS Limits (id INTEGER PRIMARY KEY AUTOINCREMENT, acct TEXT, ticket INTEGER, time TEXT)` + stat, err := db.Prepare(cmd) + if err != nil { + log.Fatal(err) + } + stat.Exec() + + return db +} + +// Add account to database +func add_to_db(acct string, limit uint16) { + db := init_limit_db() + cmd := `INSERT INTO Limits (acct, ticket) VALUES (?, ?)` + stat, err := db.Prepare(cmd) + if err != nil { + log.Fatal(err) + } + stat.Exec(acct, limit) +} + +// Take ticket for tooting +func take_ticket(acct string) { + db := init_limit_db() + cmd1 := `SELECT ticket FROM Limits WHERE acct = ?` + cmd2 := `UPDATE Limits SET ticket = ?, time = ? WHERE acct = ?` + + var ticket uint16 + db.QueryRow(cmd1, acct).Scan(&ticket) + if ticket > 0 { + ticket = ticket - 1 + } + + stat, err := db.Prepare(cmd2) + if err != nil { + log.Fatal(err) + } + + now := time.Now() + last_toot_at := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Format("2006/01/02 15:04:05 MST") + + stat.Exec(ticket, last_toot_at, acct) +} + +// Check followed once +func followed(acct string) bool { + db := init_limit_db() + cmd := `SELECT acct FROM Limits WHERE acct = ?` + err := db.QueryRow(cmd, acct).Scan(&acct) + if err != nil { + if err != sql.ErrNoRows { + log.Fatal(err) + } + + return false + } + + return true +} + +// Check ticket availability +func check_ticket(acct string, ticket uint16, toots_interval uint16) uint16 { + db := init_limit_db() + cmd1 := `SELECT ticket FROM Limits WHERE acct = ?` + cmd2 := `SELECT time FROM Limits WHERE acct = ?` + + var tickets uint16 + var lastS string + + db.QueryRow(cmd1, acct).Scan(&tickets) + db.QueryRow(cmd2, acct).Scan(&lastS) + + lastT, _ := time.Parse("2006/01/02 15:04:05 MST", lastS) + + since := time.Since(lastT) + limit := fmt.Sprintf("%dh", toots_interval) + interval, _ := time.ParseDuration(limit) + + if since >= interval { + cmd := `UPDATE Limits SET ticket = ? WHERE acct = ?` + stat, err := db.Prepare(cmd) + if err != nil { + log.Fatal(err) + } + stat.Exec(ticket, acct) + + return ticket + } + + return tickets +} diff --git a/main.go b/main.go index f1b067f..31444bc 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,7 @@ package main func main() { - run_bot(read_conf()) + config := read_conf() + + run_bot(config) }