297 lines
7.2 KiB
Go
297 lines
7.2 KiB
Go
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"bufio"
|
|||
|
"context"
|
|||
|
"fmt"
|
|||
|
"os"
|
|||
|
"path"
|
|||
|
"regexp"
|
|||
|
"strings"
|
|||
|
|
|||
|
"github.com/joho/godotenv"
|
|||
|
log "github.com/sirupsen/logrus"
|
|||
|
|
|||
|
"github.com/mattn/go-mastodon"
|
|||
|
"gorm.io/driver/postgres"
|
|||
|
"gorm.io/gorm"
|
|||
|
"maunium.net/go/mautrix"
|
|||
|
m_event "maunium.net/go/mautrix/event"
|
|||
|
m_id "maunium.net/go/mautrix/id"
|
|||
|
)
|
|||
|
|
|||
|
type Post struct {
|
|||
|
ID int
|
|||
|
PostId string
|
|||
|
MessageId string
|
|||
|
}
|
|||
|
|
|||
|
func parseRegexFile(path string) ([]regexp.Regexp, error) {
|
|||
|
file, err := os.Open(path)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
file_scanner := bufio.NewScanner(file)
|
|||
|
|
|||
|
file_scanner.Split(bufio.ScanLines)
|
|||
|
|
|||
|
var result []regexp.Regexp
|
|||
|
|
|||
|
for file_scanner.Scan() {
|
|||
|
text := file_scanner.Text()
|
|||
|
if strings.Trim(text, " ")[0] != '#' {
|
|||
|
regex, err := regexp.Compile(text)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
result = append(result, *regex)
|
|||
|
}
|
|||
|
}
|
|||
|
return result, nil
|
|||
|
}
|
|||
|
|
|||
|
func main() {
|
|||
|
ctx := context.Background()
|
|||
|
err := godotenv.Load()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
|
|||
|
ex, err := os.Getwd()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
|
|||
|
domainRegexes, err := parseRegexFile(path.Join(ex, "domains.txt"))
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
|
|||
|
nicknameRegexes, err := parseRegexFile(path.Join(ex, "nicknames.txt"))
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
|
|||
|
// log.Info(nicknameRegexes, domainRegexes)
|
|||
|
|
|||
|
db, err := gorm.Open(postgres.Open(fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s",
|
|||
|
os.Getenv("POSTGRES_HOST"),
|
|||
|
os.Getenv("POSTGRES_USER"),
|
|||
|
os.Getenv("POSTGRES_PASSWORD"),
|
|||
|
os.Getenv("POSTGRES_DB"),
|
|||
|
os.Getenv("POSTGRES_PORT"))), &gorm.Config{})
|
|||
|
|
|||
|
db.AutoMigrate(&Post{})
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
|
|||
|
masto_client := mastodon.NewClient(&mastodon.Config{
|
|||
|
Server: os.Getenv("MASTODON_HOMESERVER"),
|
|||
|
ClientID: os.Getenv("MASTODON_CLIENT_ID"),
|
|||
|
ClientSecret: os.Getenv("MASTODON_CLIENT_SECRET"),
|
|||
|
AccessToken: os.Getenv("MASTODON_ACCESS_TOKEN"),
|
|||
|
})
|
|||
|
masto_user, err := masto_client.GetAccountCurrentUser(ctx)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
|
|||
|
// log.Println(my_account)
|
|||
|
|
|||
|
matrix_client, err := mautrix.NewClient(os.Getenv("MATRIX_HOMESERVER"), m_id.UserID(os.Getenv("MATRIX_USERNAME")), os.Getenv("MATRIX_ACCESS_TOKEN"))
|
|||
|
matrix_client.Store = mautrix.NewAccountDataStore("ua.in.fediland.uabot", matrix_client)
|
|||
|
syncer := matrix_client.Syncer.(*mautrix.DefaultSyncer)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
log.Info("starting...")
|
|||
|
|
|||
|
syncer.OnEventType(m_event.EventReaction, func(source mautrix.EventSource, ev *m_event.Event) {
|
|||
|
log.Info("reactions")
|
|||
|
// if ev.RoomID == os.Getenv("MATRIX_ROOM_ID") && ev.Content != nil &&
|
|||
|
content := ev.Content.AsReaction()
|
|||
|
key := []rune(content.RelatesTo.Key)
|
|||
|
log.Info(content.RelatesTo.Key)
|
|||
|
if ev.RoomID.String() == os.Getenv("MATRIX_ROOM_ID") && (key[0] == '👍' || key[0] == '👎') {
|
|||
|
log.Info("reacted well")
|
|||
|
var post Post
|
|||
|
if err := db.First(&post, "message_id = ?", content.RelatesTo.EventID.String()).Error; err != nil {
|
|||
|
log.Error(err)
|
|||
|
return
|
|||
|
}
|
|||
|
status, err := masto_client.GetStatus(ctx, mastodon.ID(post.PostId))
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Error(err)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
if key[0] == '👍' {
|
|||
|
_, err = masto_client.Reblog(ctx, mastodon.ID(post.PostId))
|
|||
|
if err != nil {
|
|||
|
log.Error(err)
|
|||
|
return
|
|||
|
}
|
|||
|
// matrix_client.SendMessageEvent(os.Getenv("MATRIX_ROOM_ID"), "m.room.message", interface{})
|
|||
|
body := fmt.Sprintf(`#%d: Схвалено
|
|||
|
%s
|
|||
|
`, post.ID, status.URL)
|
|||
|
|
|||
|
_, err := matrix_client.SendMessageEvent(m_id.RoomID(os.Getenv("MATRIX_ROOM_ID")), m_event.EventMessage, &m_event.MessageEventContent{
|
|||
|
Body: body,
|
|||
|
MsgType: m_event.MsgText,
|
|||
|
NewContent: &m_event.MessageEventContent{
|
|||
|
MsgType: m_event.MsgText,
|
|||
|
Body: body},
|
|||
|
RelatesTo: &m_event.RelatesTo{
|
|||
|
Type: m_event.RelReplace,
|
|||
|
EventID: m_id.EventID(post.MessageId),
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Error(err)
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
body := fmt.Sprintf(`#%d: Відмовлено
|
|||
|
%s
|
|||
|
`, post.ID, status.URL)
|
|||
|
_, err := matrix_client.SendMessageEvent(m_id.RoomID(os.Getenv("MATRIX_ROOM_ID")), m_event.EventMessage, &m_event.MessageEventContent{
|
|||
|
Body: body,
|
|||
|
MsgType: m_event.MsgText,
|
|||
|
NewContent: &m_event.MessageEventContent{
|
|||
|
MsgType: m_event.MsgText,
|
|||
|
Body: body,
|
|||
|
},
|
|||
|
RelatesTo: &m_event.RelatesTo{
|
|||
|
Type: m_event.RelReplace,
|
|||
|
EventID: m_id.EventID(post.MessageId),
|
|||
|
},
|
|||
|
})
|
|||
|
if err != nil {
|
|||
|
log.Error(err)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
})
|
|||
|
|
|||
|
events, err := masto_client.StreamingUser(ctx)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
|
|||
|
go func() {
|
|||
|
for {
|
|||
|
if err := matrix_client.Sync(); err != nil {
|
|||
|
log.Error(fmt.Errorf("Sync() returned %s", err))
|
|||
|
}
|
|||
|
}
|
|||
|
}()
|
|||
|
|
|||
|
notif_loop:
|
|||
|
for {
|
|||
|
notif_event, ok := (<-events).(*mastodon.NotificationEvent)
|
|||
|
if !ok {
|
|||
|
continue
|
|||
|
}
|
|||
|
notif := notif_event.Notification
|
|||
|
|
|||
|
// log.Println(notif)
|
|||
|
|
|||
|
if notif.Type == "follow" {
|
|||
|
acct_parsed := strings.Split(notif.Account.Acct, "@")
|
|||
|
|
|||
|
for _, regex := range domainRegexes {
|
|||
|
if len(acct_parsed) == 2 && regex.MatchString(acct_parsed[1]) {
|
|||
|
_, err := masto_client.AccountBlock(ctx, notif.Account.ID)
|
|||
|
if err == nil {
|
|||
|
matrix_client.SendText(m_id.RoomID(os.Getenv("MATRIX_ROOM_ID")), fmt.Sprintf("%s заблокований автоматично регексом доменів: %s", notif.Account.Acct, regex.String()))
|
|||
|
}
|
|||
|
continue notif_loop
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for _, regex := range nicknameRegexes {
|
|||
|
if regex.MatchString(acct_parsed[0]) {
|
|||
|
_, err := masto_client.AccountBlock(ctx, notif.Account.ID)
|
|||
|
if err == nil {
|
|||
|
matrix_client.SendText(m_id.RoomID(os.Getenv("MATRIX_ROOM_ID")), fmt.Sprintf("%s заблокований автоматично регексом нікнеймів: %s", notif.Account.Acct, regex.String()))
|
|||
|
}
|
|||
|
continue notif_loop
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
masto_client.PostStatus(ctx, &mastodon.Toot{
|
|||
|
Status: fmt.Sprintf("Вітаємо у нашій спільноті! @%s", notif.Account.Acct),
|
|||
|
Visibility: mastodon.VisibilityUnlisted,
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
if notif.Type == "mention" && notif.Status.InReplyToID == nil && notif.Status.InReplyToAccountID == nil {
|
|||
|
subscribers, err := masto_client.GetAccountFollowers(ctx, masto_user.ID, &mastodon.Pagination{Limit: 10000})
|
|||
|
if err != nil {
|
|||
|
log.Error(err)
|
|||
|
continue
|
|||
|
}
|
|||
|
|
|||
|
ok := false
|
|||
|
|
|||
|
for _, subscriber := range subscribers {
|
|||
|
if subscriber.ID == notif.Account.ID {
|
|||
|
ok = true
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ok && notif.Status.Visibility == "public" {
|
|||
|
if err := db.Create(&Post{
|
|||
|
PostId: string(notif.Status.ID),
|
|||
|
}).Error; err != nil {
|
|||
|
log.Error(err)
|
|||
|
continue
|
|||
|
}
|
|||
|
var post Post
|
|||
|
if err := db.First(&post, "post_id = ?", string(notif.Status.ID)).Error; err != nil {
|
|||
|
log.Error(err)
|
|||
|
continue
|
|||
|
}
|
|||
|
message, err := matrix_client.SendText(m_id.RoomID(os.Getenv("MATRIX_ROOM_ID")), fmt.Sprintf(`#%d: На модерації
|
|||
|
%s
|
|||
|
👍 - Так
|
|||
|
👎 - Ні
|
|||
|
`, post.ID, notif.Status.URL))
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
db.Delete(&post, post.ID)
|
|||
|
}
|
|||
|
|
|||
|
post.MessageId = message.EventID.String()
|
|||
|
db.Save(&post)
|
|||
|
}
|
|||
|
|
|||
|
if ok && notif.Status.Visibility == "direct" && notif.Status.Content == "ping" {
|
|||
|
masto_client.PostStatus(ctx, &mastodon.Toot{
|
|||
|
Status: "meow",
|
|||
|
InReplyToID: notif.Status.ID,
|
|||
|
Visibility: "direct",
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|