Skip to content

Commit

Permalink
Process chat_member actions to get newbies from it.
Browse files Browse the repository at this point in the history
  • Loading branch information
kak-tus committed Nov 11, 2023
1 parent e56dde8 commit 12137cb
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 94 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2023-11-11 v1.7.0
- Remove support for set ban all users for emojii.
- Process chat_member actions to get newbies from it.

2023-11-11 v1.6.6
- Support for send message to all chats.

Expand Down
31 changes: 11 additions & 20 deletions telegram/ban.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,21 @@ import (
"time"

tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/rs/zerolog"
)

const nameLimit = 100

func (hdl *InstanceObj) banLongNames(msg *tgbotapi.Message) (bool, error) {
if msg.NewChatMembers == nil {
func (hdl *InstanceObj) banLongNames(log zerolog.Logger, chatID int64, users []tgbotapi.User) (bool, error) {
if len(users) == 0 {
return false, nil
}

var toDel bool

for _, u := range msg.NewChatMembers {
if len(u.FirstName) >= nameLimit || len(u.LastName) >= nameLimit {
hdl.oldLog.Infow("Ban long name",
"User", u.FirstName,
"Chat", msg.Chat.ID,
)
for _, usr := range users {
if len(usr.FirstName) >= nameLimit || len(usr.LastName) >= nameLimit {
log.Info().Str("first_name", usr.FirstName).Str("last_name", usr.LastName).Msg("ban long name")

toDel = true

Expand All @@ -33,11 +31,11 @@ func (hdl *InstanceObj) banLongNames(msg *tgbotapi.Message) (bool, error) {
return false, nil
}

for _, u := range msg.NewChatMembers {
for _, usr := range users {
kick := tgbotapi.KickChatMemberConfig{
ChatMemberConfig: tgbotapi.ChatMemberConfig{
ChatID: msg.Chat.ID,
UserID: u.ID,
ChatID: chatID,
UserID: usr.ID,
},
UntilDate: time.Now().In(time.UTC).AddDate(0, 0, 1).Unix(),
}
Expand All @@ -48,14 +46,10 @@ func (hdl *InstanceObj) banLongNames(msg *tgbotapi.Message) (bool, error) {
}
}

if err := hdl.deleteMessage(msg.Chat.ID, msg.MessageID); err != nil {
return true, err
}

return true, nil
}

func (hdl *InstanceObj) banKickPool(ctx context.Context, msg *tgbotapi.Message) (bool, error) {
func (hdl *InstanceObj) banKickPool(ctx context.Context, log zerolog.Logger, msg *tgbotapi.Message) (bool, error) {
kicked, err := hdl.stor.IsKicked(ctx, msg.Chat.ID, int(msg.From.ID))
if err != nil {
return false, err
Expand All @@ -65,10 +59,7 @@ func (hdl *InstanceObj) banKickPool(ctx context.Context, msg *tgbotapi.Message)
return false, err
}

hdl.oldLog.Infow("User found in kick pool",
"User", msg.From.FirstName,
"Chat", msg.Chat.ID,
)
log.Info().Str("user", msg.From.FirstName).Msg("user found in kick pool")

kick := tgbotapi.KickChatMemberConfig{
ChatMemberConfig: tgbotapi.ChatMemberConfig{
Expand Down
84 changes: 46 additions & 38 deletions telegram/newbie.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,39 @@ func (hdl *InstanceObj) messageFromNewbie(ctx context.Context, log zerolog.Logge
return nil
}

func (hdl *InstanceObj) newMembers(ctx context.Context, log zerolog.Logger, msg *tgbotapi.Message) error {
func (hdl *InstanceObj) newMembersInMessage(ctx context.Context, log zerolog.Logger, msg *tgbotapi.Message) error {
isAdm, err := hdl.isAdmin(msg.Chat.ID, msg.From.ID)
if err != nil {
return err
}

if isAdm {
hdl.oldLog.Infow(
"Newbie added by admin, it is normal",
"Admin", msg.From.ID,
)

log.Info().Int64("admin", msg.From.ID).Msg("newbie added by admin, it is normal")
return nil
}

gr, err := hdl.model.Queries.GetGroup(ctx, msg.Chat.ID)
return hdl.newMembers(ctx, log, msg.Chat.ID, msg.NewChatMembers, msg.MessageID)
}

func (hdl *InstanceObj) newMembers(
ctx context.Context,
log zerolog.Logger,
chatID int64,
users []tgbotapi.User,
initialMessageID int,
) error {
gr, err := hdl.model.Queries.GetGroup(ctx, chatID)
if err != nil && err != sql.ErrNoRows {
return err
}

defaultGroup := hdl.model.GetDefaultGroup()

for _, m := range msg.NewChatMembers {
log.Info().Str("user", m.FirstName+" "+m.LastName).
Str("user_name", m.UserName).Msg("newbie found, add messages")
for _, usr := range users {
log.Info().Str("user", usr.FirstName+" "+usr.LastName).
Str("user_name", usr.UserName).Msg("newbie found, add messages")

err := hdl.stor.AddNewbieMessages(ctx, msg.Chat.ID, int(m.ID))
err := hdl.stor.AddNewbieMessages(ctx, chatID, int(usr.ID))
if err != nil {
return err
}
Expand All @@ -97,31 +103,36 @@ func (hdl *InstanceObj) newMembers(ctx context.Context, log zerolog.Logger, msg
greet = gr.Greeting.String
}

for _, newMember := range msg.NewChatMembers {
log.Info().Str("user", newMember.FirstName+" "+newMember.LastName).
Str("user_name", newMember.UserName).Msg("newbie found, send question")
banTimeout := time.Duration(defaultGroup.BanTimeout.Int32) * time.Minute
if gr.BanTimeout.Valid {
banTimeout = time.Duration(gr.BanTimeout.Int32) * time.Minute
}

for _, usr := range users {
log.Info().Str("user", usr.FirstName+" "+usr.LastName).
Str("user_name", usr.UserName).Msg("newbie found, send question")

qID := rand.Intn(len(quest))

var name string
if newMember.UserName != "" {
name = newMember.UserName
if usr.UserName != "" {
name = usr.UserName
} else {
name = newMember.FirstName
name = usr.FirstName

if newMember.LastName != "" {
name += " " + newMember.LastName
if usr.LastName != "" {
name += " " + usr.LastName
}
}

txt := fmt.Sprintf("@%s %s\n\n%s", name, greet, quest[qID].Text)

resp := tgbotapi.NewMessage(msg.Chat.ID, txt)
resp := tgbotapi.NewMessage(chatID, txt)

btns := make([][]tgbotapi.InlineKeyboardButton, len(quest[qID].Answers))

for i, a := range quest[qID].Answers {
id := fmt.Sprintf("%d_%d_%d_%d", newMember.ID, msg.Chat.ID, qID, i)
id := fmt.Sprintf("%d_%d_%d_%d", usr.ID, chatID, qID, i)
btns[i] = []tgbotapi.InlineKeyboardButton{tgbotapi.NewInlineKeyboardButtonData(a.Text, id)}
}

Expand All @@ -132,40 +143,37 @@ func (hdl *InstanceObj) newMembers(ctx context.Context, log zerolog.Logger, msg
return err
}

banTimeout := time.Duration(defaultGroup.BanTimeout.Int32) * time.Minute
if gr.BanTimeout.Valid {
banTimeout = time.Duration(gr.BanTimeout.Int32) * time.Minute
}

act := storage.Action{
ChatID: res.Chat.ID,
Type: storage.ActionTypeDelete,
MessageID: res.MessageID,
UserID: int(newMember.ID),
UserID: int(usr.ID),
}
if err := hdl.stor.AddToActionPool(ctx, act, banTimeout); err != nil {
return err
}

err = hdl.stor.SetKicked(ctx, msg.Chat.ID, int(newMember.ID), banTimeout)
err = hdl.stor.SetKicked(ctx, chatID, int(usr.ID), banTimeout)
if err != nil {
return err
}

act = storage.Action{
ChatID: msg.Chat.ID,
Type: storage.ActionTypeDelete,
MessageID: msg.MessageID,
UserID: int(newMember.ID),
}
if err := hdl.stor.AddToActionPool(ctx, act, banTimeout); err != nil {
return err
if initialMessageID != 0 {
act = storage.Action{
ChatID: chatID,
Type: storage.ActionTypeDelete,
MessageID: initialMessageID,
UserID: int(usr.ID),
}
if err := hdl.stor.AddToActionPool(ctx, act, banTimeout); err != nil {
return err
}
}

act = storage.Action{
ChatID: msg.Chat.ID,
ChatID: chatID,
Type: storage.ActionTypeKick,
UserID: int(newMember.ID),
UserID: int(usr.ID),
}
if err := hdl.stor.AddToActionPool(ctx, act, banTimeout); err != nil {
return err
Expand Down
81 changes: 45 additions & 36 deletions telegram/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"
"time"

"github.com/forPelevin/gomoji"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/kak-tus/irma_bot/storage"
)
Expand Down Expand Up @@ -39,10 +38,13 @@ const botNameTemplate = "__IRMA_BOT_NAME__"
func (hdl *InstanceObj) process(ctx context.Context, msg tgbotapi.Update) error {
hdl.log.Debug().Interface("msg", msg).Msg("got message")

if msg.Message != nil {
switch {
case msg.Message != nil:
return hdl.processMsg(ctx, msg.Message)
} else if msg.CallbackQuery != nil {
case msg.CallbackQuery != nil:
return hdl.processCallback(ctx, msg.CallbackQuery)
case msg.ChatMember != nil:
return hdl.processChatMember(ctx, msg.ChatMember)
}

return nil
Expand All @@ -51,6 +53,9 @@ func (hdl *InstanceObj) process(ctx context.Context, msg tgbotapi.Update) error
func (hdl *InstanceObj) processMsg(ctx context.Context, msg *tgbotapi.Message) error {
textWithBotName := strings.ReplaceAll(usageText, botNameTemplate, hdl.cnf.BotName)

log := hdl.log.With().Int64("chat_id", msg.Chat.ID).
Str("chat_name", msg.Chat.UserName).Str("chat_title", msg.Chat.Title).Logger()

if msg.Chat.IsPrivate() {
resp := tgbotapi.NewMessage(msg.Chat.ID, textWithBotName)

Expand All @@ -64,16 +69,20 @@ func (hdl *InstanceObj) processMsg(ctx context.Context, msg *tgbotapi.Message) e

// Ban users with extra long names
// It's probably "name spammers"
banned, err := hdl.banLongNames(msg)
banned, err := hdl.banLongNames(log, msg.Chat.ID, msg.NewChatMembers)
if err != nil {
return err
}

if banned {
if err := hdl.deleteMessage(msg.Chat.ID, msg.MessageID); err != nil {
return err
}

return nil
}

banned, err = hdl.banKickPool(ctx, msg)
banned, err = hdl.banKickPool(ctx, log, msg)
if err != nil {
return err
}
Expand Down Expand Up @@ -114,43 +123,13 @@ func (hdl *InstanceObj) processMsg(ctx context.Context, msg *tgbotapi.Message) e
return err
}

log := hdl.log.With().Int64("chat_id", msg.Chat.ID).
Str("chat_name", msg.Chat.UserName).Str("chat_title", msg.Chat.Title).Logger()

// In case of newbie we got count >0, for ordinary user count=0
if cnt > 0 && cnt <= 4 {
return hdl.messageFromNewbie(ctx, log, msg)
}

if msg.NewChatMembers != nil {
return hdl.newMembers(ctx, log, msg)
}

group, err := hdl.model.Queries.GetGroup(ctx, msg.Chat.ID)
if err != nil && err != sql.ErrNoRows {
return err
}

if group.BanEmojiiCount.Valid && group.BanEmojiiCount.Int32 > 0 &&
len(gomoji.CollectAll(msg.Text)) >= int(group.BanEmojiiCount.Int32) {
log.Info().Msg("ban for emojii not newbie")

if err := hdl.deleteMessage(msg.Chat.ID, msg.MessageID); err != nil {
return err
}

kick := tgbotapi.KickChatMemberConfig{
ChatMemberConfig: tgbotapi.ChatMemberConfig{
ChatID: msg.Chat.ID,
UserID: msg.From.ID,
},
UntilDate: time.Now().In(time.UTC).AddDate(0, 0, 1).Unix(),
}

_, err = hdl.bot.Request(kick)
if err != nil {
return err
}
return hdl.newMembersInMessage(ctx, log, msg)
}

name := fmt.Sprintf("@%s", hdl.cnf.BotName)
Expand Down Expand Up @@ -226,3 +205,33 @@ func (hdl *InstanceObj) processCallback(ctx context.Context, msg *tgbotapi.Callb

return nil
}

func (hdl *InstanceObj) processChatMember(ctx context.Context, msg *tgbotapi.ChatMemberUpdated) error {
if msg.NewChatMember.IsMember {
return nil
}

if msg.NewChatMember.Status != "member" {
return nil
}

if msg.NewChatMember.User == nil {
return nil
}

log := hdl.log.With().Int64("chat_id", msg.Chat.ID).
Str("chat_name", msg.Chat.UserName).Str("chat_title", msg.Chat.Title).Logger()

// Ban users with extra long names
// It's probably "name spammers"
banned, err := hdl.banLongNames(log, msg.Chat.ID, []tgbotapi.User{*msg.NewChatMember.User})
if err != nil {
return err
}

if banned {
return nil
}

return hdl.newMembers(ctx, log, msg.Chat.ID, []tgbotapi.User{*msg.NewChatMember.User}, 0)
}

0 comments on commit 12137cb

Please sign in to comment.