mirror of
https://gitea.phreedom.club/localhost_frssoft/mastodon-group-bot.git
synced 2024-12-22 09:13:33 +02:00
add notification cleaning
This commit is contained in:
parent
30b7fddf18
commit
8c6e023e51
9 changed files with 192 additions and 82 deletions
22
README.md
22
README.md
|
@ -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
63
bot.go
|
@ -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
36
cleaning.go
Normal 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")
|
||||
}
|
||||
}
|
22
config.go
22
config.go
|
@ -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 {
|
||||
|
|
22
config.json
22
config.json
|
@ -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"]
|
||||
}
|
89
limits.go
89
limits.go
|
@ -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(¬ice)
|
||||
|
||||
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(¬ice)
|
||||
|
||||
return notice
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
5
main.go
5
main.go
|
@ -1,5 +1,10 @@
|
|||
package main
|
||||
|
||||
func main() {
|
||||
LoggerInit()
|
||||
|
||||
wg.Add(1)
|
||||
|
||||
go DeleteNotices()
|
||||
RunBot()
|
||||
}
|
||||
|
|
13
utils.go
Normal file
13
utils.go
Normal 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
|
||||
}
|
Loading…
Reference in a new issue