add limits

This commit is contained in:
fade 2022-08-25 15:23:44 -04:00
parent b2107583ba
commit fe88a07676
7 changed files with 145 additions and 14 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
go.mod go.mod
go.sum go.sum
mastodon-group-bot mastodon-group-bot
*.db

View file

@ -13,6 +13,9 @@ The bot is configured in a JSON file that looks like this:
"ClientSecret": "0000000000000000000000000000000000000000000", "ClientSecret": "0000000000000000000000000000000000000000000",
"AccessToken": "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"]
} }
``` ```

34
bot.go
View file

@ -48,36 +48,48 @@ func run_bot(Conf Config) {
// New follower // New follower
if notif.Type == "follow" { if notif.Type == "follow" {
var message = fmt.Sprintf("%s @%s", Conf.WelcomeMessage, notif.Account.Acct) acct := notif.Account.Acct
postToot(message, "public") 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 // Read message
if notif.Type == "mention" { if notif.Type == "mention" {
for i := 0; i < len(followers); i++ { // Follow check acct := notif.Status.Account.Acct
if notif.Status.Account.Acct == string(followers[i].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.Visibility == "public" { // Reblog toot
if notif.Status.InReplyToID == nil { if notif.Status.InReplyToID == nil { // Not boost replies
c.Reblog(ctx, notif.Status.ID) 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 } else if notif.Status.Visibility == "direct" { // Admin commands
for y := 0; y < len(Conf.Admins); y++ { 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 text := notif.Status.Content
recmd := regexp.MustCompile(`<.*?> `) recmd := regexp.MustCompile(`<.*?> `)
command := recmd.ReplaceAllString(text, "") command := recmd.ReplaceAllString(text, "")
args := strings.Split(command, " ") args := strings.Split(command, " ")
mID := mastodon.ID((args[1]))
if len(args) == 2 { if len(args) == 2 {
switch args[0] { switch args[0] {
case "unboost": case "unboost":
c.Unreblog(ctx, mastodon.ID((args[1]))) c.Unreblog(ctx, mID)
case "delete": case "delete":
c.DeleteStatus(ctx, mastodon.ID(args[1])) c.DeleteStatus(ctx, mID)
case "block": case "block":
c.AccountBlock(ctx, mastodon.ID(args[1])) c.AccountBlock(ctx, mID)
case "unblock": case "unblock":
c.AccountUnblock(ctx, mastodon.ID(args[1])) c.AccountUnblock(ctx, mID)
} }
} }
} else { } else {

View file

@ -13,6 +13,8 @@ type Config struct {
ClientSecret string `json:"ClientSecret"` ClientSecret string `json:"ClientSecret"`
AccessToken string `json:"AccessToken"` AccessToken string `json:"AccessToken"`
WelcomeMessage string `json:"WelcomeMessage"` WelcomeMessage string `json:"WelcomeMessage"`
Max_toots uint16 `json:"Max_toots"`
Toots_interval uint16 `json:"Toots_interval"`
Admins []string `json:"Admins"` Admins []string `json:"Admins"`
} }

View file

@ -3,5 +3,8 @@
"ClientID": "0000000000000000000000000000000000000000000", "ClientID": "0000000000000000000000000000000000000000000",
"ClientSecret": "0000000000000000000000000000000000000000000", "ClientSecret": "0000000000000000000000000000000000000000000",
"AccessToken": "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"]
} }

108
limits.go Normal file
View file

@ -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
}

View file

@ -1,5 +1,7 @@
package main package main
func main() { func main() {
run_bot(read_conf()) config := read_conf()
run_bot(config)
} }