add notification cleaning

This commit is contained in:
fade 2022-09-08 08:26:25 -04:00
parent 30b7fddf18
commit 8c6e023e51
9 changed files with 192 additions and 82 deletions

View File

@ -17,16 +17,18 @@ This is a bot which implements group functionality in Mastodon.
The bot is configured in a JSON file that looks like this:
```
{
"Server": "https://example.com",
"ClientID": "0000000000000000000000000000000000000000000",
"ClientSecret": "0000000000000000000000000000000000000000000",
"AccessToken": "0000000000000000000000000000000000000000000",
"WelcomeMessage": "We have a new member in our group. Please love and favor"
"Max_toots": 2,
"Toots_interval": 12,
"Duplicate_buf": 10,
"Order_limit": 1,
"Admins": ["admin@example.com"]
"Server": "https://example.com",
"ClientID": "0000000000000000000000000000000000000000000",
"ClientSecret": "0000000000000000000000000000000000000000000",
"AccessToken": "0000000000000000000000000000000000000000000",
"WelcomeMessage": "We have a new member in our group. Please love and favor",
"NotFollowedMessage": "you are not followed",
"Max_toots": 2,
"Toots_interval": 12,
"Duplicate_buf": 10,
"Order_limit": 1,
"Del_notices_interval": 30,
"Admins": ["admin@example.com"]
}
```

63
bot.go
View File

@ -10,26 +10,25 @@ import (
"github.com/mattn/go-mastodon"
)
func RunBot() {
logger_init()
c := mastodon.NewClient(&mastodon.Config{
var (
c = mastodon.NewClient(&mastodon.Config{
Server: Conf.Server,
ClientID: Conf.ClientID,
ClientSecret: Conf.ClientSecret,
AccessToken: Conf.AccessToken,
})
ctx := context.Background()
ctx = context.Background()
my_account, _ = c.GetAccountCurrentUser(ctx)
)
func RunBot() {
events, err := c.StreamingUser(ctx)
if err != nil {
ErrorLogger.Println("Streaming")
}
my_account, err := c.GetAccountCurrentUser(ctx)
if err != nil {
ErrorLogger.Println("Fetch account info")
}
followers, err := c.GetAccountFollowers(ctx, my_account.ID, &mastodon.Pagination{Limit: 60})
if err != nil {
ErrorLogger.Println("Fetch followers")
@ -43,28 +42,30 @@ func RunBot() {
}
notif := notifEvent.Notification
ntype := notif.Type
acct := notif.Status.Account.Acct
content := notif.Status.Content
tooturl := notif.Status.URL
// Posting function
postToot := func(toot string, vis string) error {
/*postToot := func(toot string, vis string) (*mastodon.Status, error) {
conToot := mastodon.Toot{
Status: toot,
Visibility: vis,
}
_, err := c.PostStatus(ctx, &conToot)
return err
}
status, err := c.PostStatus(ctx, &conToot)
return status, err
}*/
// New follower
if notif.Type == "follow" {
acct := notif.Account.Acct
if !followed(acct) { // Add to db and post welcome message
if ntype == "follow" {
if !exist_in_database(acct) { // Add to db and post welcome message
InfoLogger.Printf("%s followed", acct)
add_to_db(acct)
InfoLogger.Printf("%s added to database", acct)
message := fmt.Sprintf("%s @%s", Conf.WelcomeMessage, acct)
err := postToot(message, "public")
_, err := postToot(message, "public")
if err != nil {
ErrorLogger.Println("Post welcome message")
}
@ -73,11 +74,7 @@ func RunBot() {
}
// Read message
if notif.Type == "mention" {
acct := notif.Status.Account.Acct
content := notif.Status.Content
tooturl := notif.Status.URL
if ntype == "mention" {
for i := 0; i < len(followers); i++ {
if acct == string(followers[i].Acct) { // Follow check
if notif.Status.Visibility == "public" { // Reblog toot
@ -96,7 +93,7 @@ func RunBot() {
}
// Add to db if needed
if !followed(acct) {
if !exist_in_database(acct) {
add_to_db(acct)
InfoLogger.Printf("%s added to database", acct)
}
@ -148,6 +145,24 @@ func RunBot() {
break
}
}
if i == len(followers)-1 { // Notify user
if got_notice(acct) == 0 {
if !exist_in_database(acct) {
add_to_db(acct)
InfoLogger.Printf("%s added to database", acct)
}
message := fmt.Sprintf("@%s %s", acct, Conf.NotFollowedMessage)
_, err := postToot(message, "direct")
if err != nil {
ErrorLogger.Printf("Notify %s", acct)
}
InfoLogger.Printf("%s has been notified", acct)
mark_notice(acct)
InfoLogger.Printf("%s marked notification in database", acct)
}
}
}
}
}

36
cleaning.go Normal file
View File

@ -0,0 +1,36 @@
package main
import (
"sync"
"time"
"github.com/mattn/go-mastodon"
)
var (
wg sync.WaitGroup
)
// Delete notices
func DeleteNotices() {
wg.Done()
for {
statuses, err := c.GetAccountStatuses(ctx, my_account.ID, &mastodon.Pagination{Limit: 60})
if err != nil {
ErrorLogger.Println("Get account statuses")
}
time.Sleep(time.Duration(Conf.Del_notices_interval) * time.Second)
for i := range statuses {
if statuses[i].Visibility == "direct" {
c.DeleteStatus(ctx, statuses[i].ID)
}
}
InfoLogger.Println("Cleaning notices")
reset_notice_counter()
InfoLogger.Println("Reset notice counter")
}
}

View File

@ -16,16 +16,18 @@ var (
)
type Config struct {
Server string `json:"Server"`
ClientID string `json:"ClientID"`
ClientSecret string `json:"ClientSecret"`
AccessToken string `json:"AccessToken"`
WelcomeMessage string `json:"WelcomeMessage"`
Max_toots uint16 `json:"Max_toots"`
Toots_interval uint16 `json:"Toots_interval"`
Duplicate_buf uint16 `json:"Duplicate_buf"`
Order_limit uint16 `json:"Order_limit"`
Admins []string `json:"Admins"`
Server string `json:"Server"`
ClientID string `json:"ClientID"`
ClientSecret string `json:"ClientSecret"`
AccessToken string `json:"AccessToken"`
WelcomeMessage string `json:"WelcomeMessage"`
NotFollowedMessage string `json:"NotFollowedMessage"`
Max_toots uint `json:"Max_toots"`
Toots_interval uint `json:"Toots_interval"`
Duplicate_buf uint `json:"Duplicate_buf"`
Order_limit uint `json:"Order_limit"`
Del_notices_interval uint `json:"Del_notices_interval"`
Admins []string `json:"Admins"`
}
func ReadConfig() Config {

View File

@ -1,12 +1,14 @@
{
"Server": "https://example.com",
"ClientID": "0000000000000000000000000000000000000000000",
"ClientSecret": "0000000000000000000000000000000000000000000",
"AccessToken": "0000000000000000000000000000000000000000000",
"WelcomeMessage": "We have a new member in our group. Please love and favor",
"Max_toots": 2,
"Toots_interval": 12,
"Duplicate_buf": 10,
"Order_limit": 1,
"Admins": ["admin@example.com"]
"Server": "https://example.com",
"ClientID": "0000000000000000000000000000000000000000000",
"ClientSecret": "0000000000000000000000000000000000000000000",
"AccessToken": "0000000000000000000000000000000000000000000",
"WelcomeMessage": "We have a new member in our group. Please love and favor",
"NotFollowedMessage": "you are not followed",
"Max_toots": 2,
"Toots_interval": 12,
"Duplicate_buf": 10,
"Order_limit": 1,
"Del_notices_interval": 30,
"Admins": ["admin@example.com"]
}

View File

@ -9,6 +9,10 @@ import (
_ "github.com/mattn/go-sqlite3"
)
var (
db = init_limit_db()
)
// Init database
func init_limit_db() *sql.DB {
db, err := sql.Open("sqlite3", *DBPath)
@ -16,7 +20,7 @@ func init_limit_db() *sql.DB {
ErrorLogger.Println("Open database")
}
cmd1 := `CREATE TABLE IF NOT EXISTS Limits (id INTEGER PRIMARY KEY AUTOINCREMENT, acct TEXT, ticket INTEGER, order_msg INTEGER, time TEXT)`
cmd1 := `CREATE TABLE IF NOT EXISTS Limits (id INTEGER PRIMARY KEY AUTOINCREMENT, acct TEXT, ticket INTEGER, order_msg INTEGER, got_notice INTEGER, posted TEXT)`
cmd2 := `CREATE TABLE IF NOT EXISTS MsgHashs (message_hash TEXT)`
stat1, err := db.Prepare(cmd1)
@ -36,18 +40,16 @@ func init_limit_db() *sql.DB {
// Add account to database
func add_to_db(acct string) {
db := init_limit_db()
cmd := `INSERT INTO Limits (acct, ticket, order_msg) VALUES (?, ?, ?)`
cmd := `INSERT INTO Limits (acct, ticket, order_msg, got_notice) VALUES (?, ?, ?, ?)`
stat, err := db.Prepare(cmd)
if err != nil {
ErrorLogger.Println("Add account to databse")
ErrorLogger.Println("Add account to database")
}
stat.Exec(acct, Conf.Max_toots, 0)
stat.Exec(acct, Conf.Max_toots, 0, 0)
}
// Check followed once
func followed(acct string) bool {
db := init_limit_db()
func exist_in_database(acct string) bool {
cmd := `SELECT acct FROM Limits WHERE acct = ?`
err := db.QueryRow(cmd, acct).Scan(&acct)
if err != nil {
@ -63,34 +65,32 @@ func followed(acct string) bool {
// 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 = ?`
cmd2 := `UPDATE Limits SET ticket = ?, posted = ? WHERE acct = ?`
var ticket uint16
var ticket uint
db.QueryRow(cmd1, acct).Scan(&ticket)
if ticket > 0 {
ticket = ticket - 1
}
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, err := db.Prepare(cmd2)
if err != nil {
ErrorLogger.Println("Take ticket")
}
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 ticket availability
func check_ticket(acct string) uint16 {
db := init_limit_db()
func check_ticket(acct string) uint {
cmd1 := `SELECT ticket FROM Limits WHERE acct = ?`
cmd2 := `SELECT time FROM Limits WHERE acct = ?`
cmd2 := `SELECT posted FROM Limits WHERE acct = ?`
var tickets uint16
var tickets uint
var lastS string
db.QueryRow(cmd1, acct).Scan(&tickets)
@ -118,20 +118,18 @@ func check_ticket(acct string) uint16 {
// Save message hash
func save_msg_hash(hash string) {
db := init_limit_db()
cmd1 := `SELECT COUNT(*) FROM MsgHashs`
cmd2 := `DELETE FROM MsgHashs WHERE ROWID IN (SELECT ROWID FROM MsgHashs LIMIT 1)`
cmd3 := `INSERT INTO MsgHashs (message_hash) VALUES (?)`
var rows uint16
var rows uint
db.QueryRow(cmd1).Scan(&rows)
if rows >= Conf.Duplicate_buf {
superfluous := rows - Conf.Duplicate_buf
for i := uint16(0); i <= superfluous; i++ {
for i := uint(0); i <= superfluous; i++ {
stat2, err := db.Prepare(cmd2)
if err != nil {
ErrorLogger.Println("Delete message hash from database")
@ -149,7 +147,6 @@ func save_msg_hash(hash string) {
// Check message hash
func check_msg_hash(hash string) bool {
db := init_limit_db()
cmd := `SELECT message_hash FROM MsgHashs WHERE message_hash = ?`
err := db.QueryRow(cmd, hash).Scan(&hash)
if err != nil {
@ -165,7 +162,6 @@ func check_msg_hash(hash string) bool {
// Count order
func count_order(acct string) {
db := init_limit_db()
cmd1 := `UPDATE Limits SET order_msg = ? WHERE acct != ?`
cmd2 := `SELECT order_msg FROM Limits WHERE acct = ?`
cmd3 := `UPDATE Limits SET order_msg = ? WHERE acct = ?`
@ -177,7 +173,7 @@ func count_order(acct string) {
stat1.Exec(0, acct)
var order uint16
var order uint
db.QueryRow(cmd2, acct).Scan(&order)
if order < Conf.Order_limit {
order = order + 1
@ -192,12 +188,51 @@ func count_order(acct string) {
}
// Check order
func check_order(acct string) uint16 {
db := init_limit_db()
func check_order(acct string) uint {
cmd := `SELECT order_msg FROM Limits WHERE acct = ?`
var order uint16
var order uint
db.QueryRow(cmd, acct).Scan(&order)
return order
}
// Mark notice
func mark_notice(acct string) {
cmd1 := `SELECT got_notice FROM Limits WHERE acct = ?`
cmd2 := `UPDATE Limits SET got_notice = ? WHERE acct = ?`
var notice uint
db.QueryRow(cmd1, acct).Scan(&notice)
if notice == 0 {
notice = notice + 1
}
stat, err := db.Prepare(cmd2)
if err != nil {
ErrorLogger.Println("Mark notice")
}
stat.Exec(notice, acct)
}
// Reset notice counter
func reset_notice_counter() {
cmd := `UPDATE Limits SET got_notice = ?`
stat, err := db.Prepare(cmd)
if err != nil {
ErrorLogger.Println("Reset notice counter")
}
stat.Exec(0)
}
// Check if got notification
func got_notice(acct string) uint {
cmd := `SELECT got_notice FROM Limits WHERE acct = ?`
var notice uint
db.QueryRow(cmd, acct).Scan(&notice)
return notice
}

View File

@ -11,7 +11,7 @@ var (
ErrorLogger *log.Logger
)
func logger_init() {
func LoggerInit() {
file, err := os.OpenFile(*LogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
log.Fatal("Failed to read log file")

View File

@ -1,5 +1,10 @@
package main
func main() {
LoggerInit()
wg.Add(1)
go DeleteNotices()
RunBot()
}

13
utils.go Normal file
View File

@ -0,0 +1,13 @@
package main
import "github.com/mattn/go-mastodon"
// Posting function
func postToot(toot string, vis string) (*mastodon.Status, error) {
conToot := mastodon.Toot{
Status: toot,
Visibility: vis,
}
status, err := c.PostStatus(ctx, &conToot)
return status, err
}