Skip to content

Commit

Permalink
prepare for admin chat reporting banned users
Browse files Browse the repository at this point in the history
  • Loading branch information
umputun committed Dec 6, 2023
1 parent bc18d12 commit 9bb0e39
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
3 changes: 2 additions & 1 deletion app/bot/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package bot
import (
"fmt"
"net/http"
"strings"
"time"
)

Expand Down Expand Up @@ -92,5 +93,5 @@ func DisplayName(msg Message) string {
if displayUsername == "" {
displayUsername = fmt.Sprintf("%d", msg.From.ID)
}
return displayUsername
return strings.TrimSpace(displayUsername)
}
3 changes: 2 additions & 1 deletion app/bot/spam.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ func (s *SpamFilter) OnMessage(msg Message) (response Response) {
return Response{}
}

displayUsername := strings.TrimSpace(DisplayName(msg))
displayUsername := DisplayName(msg)

isEmojiSpam, _ := s.tooManyEmojis(msg.Text, s.MaxAllowedEmoji)
stopWordsSpam := s.hasStopWords(msg.Text)
similaritySpam := s.isSpamSimilarityHigh(msg.Text)
Expand Down
29 changes: 27 additions & 2 deletions app/events/telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package events

import (
"context"
"crypto/sha1"

Check failure on line 5 in app/events/telegram.go

View workflow job for this annotation

GitHub Actions / build

G505: Blocklisted import crypto/sha1: weak cryptographic primitive (gosec)
"encoding/json"
"fmt"
"log"
Expand All @@ -28,10 +29,16 @@ type TelegramListener struct {
SpamLogger SpamLogger
Bot Bot
Group string // can be int64 or public group username (without "@" prefix)
AdminGroup string // can be int64 or public group username (without "@" prefix)
IdleDuration time.Duration
SuperUsers SuperUser
StartupMsg string
chatID int64

AdminURL string
AdminSecret string

chatID int64
adminChatID int64

msgs struct {
once sync.Once
Expand Down Expand Up @@ -74,6 +81,13 @@ func (l *TelegramListener) Do(ctx context.Context) error {
return fmt.Errorf("failed to get chat ID for group %q: %w", l.Group, getChatErr)
}

if l.AdminGroup != "" {
if l.adminChatID, getChatErr = l.getChatID(l.AdminGroup); getChatErr != nil {
return fmt.Errorf("failed to get chat ID for admin group %q: %w", l.AdminGroup, getChatErr)
}
log.Printf("[INFO] admin chat ID: %d", l.adminChatID)
}

l.msgs.once.Do(func() {
l.msgs.ch = make(chan bot.Response, 100)
if l.IdleDuration == 0 {
Expand Down Expand Up @@ -159,6 +173,11 @@ func (l *TelegramListener) procEvents(update tbapi.Update) error {
errors = multierror.Append(errors, fmt.Errorf("failed to ban %s: %w", banUserStr, err))
} else {
log.Print(banSuccessMessage)
if l.adminChatID != 0 && msg.From.ID != 0 {
forwardMsg := fmt.Sprintf("**permanently banned [%s](tg://user?id=%d)**\n[unban](%s) if it was a mistake\n\n%s\n----",
banUserStr, msg.From.ID, l.unbanURL(msg.From.ID), strings.ReplaceAll(msg.Text, "\n", " "))
l.sendBotResponse(bot.Response{Send: true, Text: forwardMsg, ParseMode: tbapi.ModeMarkdown}, l.adminChatID)

Check failure on line 179 in app/events/telegram.go

View workflow job for this annotation

GitHub Actions / build

G104: Errors unhandled. (gosec)
}
}
}

Expand Down Expand Up @@ -237,7 +256,7 @@ func (l *TelegramListener) SubmitHTML(ctx context.Context, text string) error {
}

func (l *TelegramListener) getChatID(group string) (int64, error) {
chatID, err := strconv.ParseInt(l.Group, 10, 64)
chatID, err := strconv.ParseInt(group, 10, 64)
if err == nil {
return chatID, nil
}
Expand Down Expand Up @@ -398,3 +417,9 @@ func (l *TelegramListener) transformEntities(entities []tbapi.MessageEntity) *[]

return &result
}

func (l *TelegramListener) unbanURL(userID int64) string {
// key is SHA1 of user ID + secret
key := fmt.Sprintf("%x", sha1.Sum([]byte(fmt.Sprintf("%d%s", userID, l.AdminSecret))))

Check failure on line 423 in app/events/telegram.go

View workflow job for this annotation

GitHub Actions / build

G401: Use of weak cryptographic primitive (gosec)
return fmt.Sprintf("%s/%d?key=%s", l.AdminURL, userID, key)
}
8 changes: 6 additions & 2 deletions app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ import (

var opts struct {
Telegram struct {
Token string `long:"token" env:"TOKEN" description:"telegram bot token" default:"test"`
Group string `long:"group" env:"GROUP" description:"group name/id" default:"test"`
Token string `long:"token" env:"TOKEN" description:"telegram bot token" required:"true"`
Group string `long:"group" env:"GROUP" description:"group name/id" required:"true"`
AdminGroup string `long:"admin-group" env:"ADMIN_GROUP" description:"admin group name/id"`
Timeout time.Duration `long:"timeout" env:"TIMEOUT" default:"30s" description:"http client timeout for telegram" `
IdleDuration time.Duration `long:"idle" env:"IDLE" default:"30s" description:"idle duration"`
} `group:"telegram" namespace:"telegram" env-namespace:"TELEGRAM"`

AdminURL string `long:"admin-url" env:"ADMIN_URL" description:"admin root url"`

LogsPath string `short:"l" long:"logs" env:"TELEGRAM_LOGS" default:"logs" description:"path to logs"`
SuperUsers events.SuperUser `long:"super" description:"super-users"`

Expand Down Expand Up @@ -122,6 +125,7 @@ func execute(ctx context.Context) error {
tgListener := events.TelegramListener{
TbAPI: tbAPI,
Group: opts.Telegram.Group,
AdminGroup: opts.Telegram.AdminGroup,
IdleDuration: opts.Telegram.IdleDuration,
SuperUsers: opts.SuperUsers,
Bot: spamBot,
Expand Down

0 comments on commit 9bb0e39

Please sign in to comment.