• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Civil / tg-simple-regex-antispam / 13070263183

31 Jan 2025 09:45AM UTC coverage: 0.0%. Remained the same
13070263183

Pull #5

github

Civil
Refactor and improve bot

 * Fixed small bug in forward action
 * package statefulFilters renamed to chains
 * generic badgerdb interface
 * add filter that counts repeated messages
 * add filter that checks if message is a story
 * add filter that checks if message was marked as spam
Pull Request #5: some improvements

0 of 1422 new or added lines in 20 files covered. (0.0%)

21 existing lines in 3 files now uncovered.

0 of 3756 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/tg/tg.go
1
package tg
2

3
import (
4
        "bytes"
5
        "errors"
6
        "fmt"
7
        "strings"
8

9
        "github.com/mymmrac/telego"
10
        th "github.com/mymmrac/telego/telegohandler"
11
        "go.uber.org/zap"
12

13
        "github.com/Civil/tg-simple-regex-antispam/bannedDB"
14
        "github.com/Civil/tg-simple-regex-antispam/filters/interfaces"
15
        "github.com/Civil/tg-simple-regex-antispam/helper/logs"
16
        "github.com/Civil/tg-simple-regex-antispam/helper/tg"
17
)
18

19
type TgAPI interface {
20
        Start()
21
        Stop()
22
        GetBot() *telego.Bot
23
        UpdatePrefixes()
24
}
25

26
type Telego struct {
27
        token  string
28
        logger *zap.Logger
29

30
        bot            *telego.Bot
31
        filters        *[]interfaces.StatefulFilter
32
        adminIDs       map[int64]struct{}
33
        adminUsernames map[string]struct{}
34
        banDB          bannedDB.BanDB
35
        allowedChats   map[int64]struct{}
36

37
        handlers map[string]tg.AdminCMDHandlerFunc
38
}
39

40
func New(logger *zap.Logger, token string, filters *[]interfaces.StatefulFilter, adminIDs []int64, allowedChats []int64, adminUsernames []string, banDB bannedDB.BanDB) (TgAPI,
41
        error) {
×
42
        if token == "" || token == "your_telegram_bot_token" {
×
43
                logger.Error("no token provided")
×
44
                return nil, errors.New("no token provided")
×
45
        }
×
46

47
        allowedChatsMap := make(map[int64]struct{})
×
48
        for _, chat := range allowedChats {
×
49
                allowedChatsMap[chat] = struct{}{}
×
50
        }
×
51

52
        adminIDsMap := make(map[int64]struct{})
×
53
        for _, id := range adminIDs {
×
54
                adminIDsMap[id] = struct{}{}
×
55
        }
×
56

57
        adminUsernamesMap := make(map[string]struct{})
×
58
        for _, user := range adminUsernames {
×
59
                adminUsernamesMap[user] = struct{}{}
×
60
        }
×
61

62
        t := &Telego{
×
63
                banDB:          banDB,
×
64
                logger:         logger,
×
65
                token:          token,
×
66
                filters:        filters,
×
67
                adminIDs:       adminIDsMap,
×
68
                adminUsernames: adminUsernamesMap,
×
69
                allowedChats:   allowedChatsMap,
×
70
                handlers:       make(map[string]tg.AdminCMDHandlerFunc),
×
71
        }
×
72

×
73
        for _, filter := range *filters {
×
74
                logger.Info("registering filter", zap.String("filter", filter.GetFilterName()), zap.String("chain_name", filter.TGAdminPrefix()))
×
75
                prefix := filter.TGAdminPrefix()
×
76
                if prefix != "" {
×
77
                        t.handlers[prefix] = filter.HandleTGCommands
×
78
                }
×
79
        }
80
        t.handlers[t.banDB.TGAdminPrefix()] = t.banDB.HandleTGCommands
×
81
        t.handlers["listCmds"] = t.listAdminPrefixes
×
82

×
83
        bot, err := telego.NewBot(t.token, telego.WithLogger(logs.New(t.logger)))
×
84
        if err != nil {
×
85
                return nil, err
×
86
        }
×
87
        t.bot = bot
×
88

×
89
        return t, nil
×
90
}
91

92
func (t *Telego) UpdatePrefixes() {
×
93
        for _, filter := range *t.filters {
×
94
                prefix := filter.TGAdminPrefix()
×
95
                keys := make([]string, 0)
×
96
                for k := range t.handlers {
×
97
                        if strings.HasPrefix(k, prefix) {
×
98
                                keys = append(keys, k)
×
99
                        }
×
100
                }
101
                t.logger.Debug("checking filter",
×
102
                        zap.String("filter", filter.GetFilterName()),
×
103
                        zap.String("filter_type", filter.GetName()),
×
104
                        zap.String("chain_name", prefix),
×
105
                        zap.Any("handlers", keys),
×
106
                )
×
107

×
108
                if prefix != "" {
×
109
                        t.logger.Debug("checking if filter was registered")
×
110
                        if _, ok := t.handlers[prefix]; !ok {
×
111
                                t.logger.Debug("registering filter", zap.String("filter", filter.GetFilterName()))
×
112
                                t.handlers[prefix] = filter.HandleTGCommands
×
113
                        }
×
114
                }
115
        }
116
}
117

118
func (t *Telego) listAdminPrefixes(logger *zap.Logger, bot *telego.Bot, message *telego.Message, _ []string) error {
×
119
        buf := bytes.NewBuffer([]byte{})
×
120
        buf.WriteString("Available subcommands:\n\n")
×
121
        for prefix := range t.handlers {
×
122
                buf.WriteString("   " + prefix + "\n")
×
123
        }
×
124

125
        err := tg.SendMessage(bot, message.Chat.ChatID(), &message.MessageID, buf.String())
×
126
        if err != nil {
×
127
                logger.Error("failed to send message", zap.Error(err))
×
128
        }
×
129
        return err
×
130
}
131

132
func (t *Telego) HandleAdminMessages(logger *zap.Logger, bot *telego.Bot, message *telego.Message) {
×
133
        logger.Debug("admin command", zap.String("command", message.Text))
×
134
        tokens := strings.Split(message.Text, " ")
×
135
        if len(tokens) < 2 {
×
136
                err := t.listAdminPrefixes(logger, bot, message, nil)
×
137
                if err != nil {
×
138
                        logger.Error("failed to send message", zap.Error(err))
×
139
                }
×
140
                return
×
141
        }
142

143
        if h, ok := t.handlers[tokens[1]]; ok {
×
NEW
144
                logger.Debug("handling tg admin command",
×
NEW
145
                        zap.String("command", tokens[1]),
×
NEW
146
                        zap.Strings("tokens", tokens),
×
NEW
147
                )
×
148
                var err error
×
149
                if len(tokens) > 2 {
×
150
                        err = h(logger, bot, message, tokens[2:])
×
151
                } else {
×
152
                        err = h(logger, bot, message, nil)
×
153
                }
×
154
                if err != nil {
×
155
                        logger.Error("failed to handle command", zap.Error(err))
×
156
                }
×
157
                return
×
158
        }
159

160
        logger.Warn("unsupported command", zap.Any("message", message))
×
161
        err := tg.SendMessage(bot, message.Chat.ChatID(), &message.MessageID,
×
162
                fmt.Sprintf("unsupported command: %v", message.Text))
×
163
        if err != nil {
×
164
                logger.Error("failed to send message", zap.Error(err))
×
165
        }
×
166
}
167

168
func (t *Telego) isAdmin(userID int64, username string) bool {
×
169
        if _, ok := t.adminIDs[userID]; ok {
×
170
                return true
×
171
        }
×
172

173
        if _, ok := t.adminUsernames[username]; ok {
×
174
                return true
×
175
        }
×
176
        return false
×
177
}
178

179
func (t *Telego) HandleMessages(bot *telego.Bot, message telego.Message) {
×
180
        userID := message.From.ID
×
181
        username := message.From.Username
×
182
        logger := t.logger.With(
×
183
                zap.Int64("chat_id", message.Chat.ID),
×
184
                zap.Int64("from_user_id", userID),
×
185
        )
×
186
        logger.Debug("got message", zap.Any("message", message))
×
187
        if message.Text == "/admin" || strings.HasPrefix(message.Text, "/admin ") {
×
188
                if !t.isAdmin(userID, username) {
×
189
                        logger.Debug("user is not in list of extra super users, checking chat admins")
×
190
                        params := &telego.GetChatAdministratorsParams{
×
191
                                ChatID: message.Chat.ChatID(),
×
192
                        }
×
193
                        chatAdmins, err := bot.GetChatAdministrators(params)
×
194
                        if err != nil {
×
195
                                logger.Error("failed to get chat administrators", zap.Error(err))
×
196
                        }
×
197
                        ok := false
×
198
                        for _, admin := range chatAdmins {
×
199
                                if admin.MemberUser().ID == userID {
×
200
                                        ok = true
×
201
                                        logger.Debug("user is chat admin", zap.Any("user_id", userID))
×
202
                                        break
×
203
                                }
204
                        }
205
                        if !ok {
×
206
                                logger.Warn("user is not admin or chat admin", zap.Any("user_id", userID), zap.Any("message", message))
×
207
                                return
×
208
                        }
×
209
                }
210
                t.HandleAdminMessages(logger, bot, &message)
×
211
                return
×
212
        }
213
        if _, ok := t.allowedChats[message.Chat.ID]; !ok {
×
214
                logger.Error("message doesn't come from allowed chat list", zap.Any("chat_id", message.Chat.ID), zap.Any("message", message))
×
215
                return
×
216
        }
×
217
        for _, f := range *t.filters {
×
218
                logger.Debug("applying filter",
×
219
                        zap.String("filter_name", f.GetFilterName()),
×
220
                        zap.String("filter_type", f.GetName()),
×
221
                )
×
222
                score := f.Score(t.bot, &message)
×
223
                if score.Score > 0 {
×
224
                        logger.Info("message got scored",
×
225
                                zap.Int32("score", score.Score),
×
226
                                zap.String("score_reason", score.Reason),
×
227
                                zap.Any("message", message),
×
228
                        )
×
229
                        if score.Score >= 100 && f.IsFinal() {
×
230
                                logger.Info("stop scoring")
×
231
                                break
×
232
                        }
233
                }
234
        }
235
}
236

237
func (t *Telego) Start() {
×
238
        t.logger.Info("starting telego...")
×
239
        botUser, err := t.bot.GetMe()
×
240
        if err != nil {
×
241
                t.logger.Error("bot cannot identify itself", zap.Error(err))
×
242
                return
×
243
        }
×
244
        t.logger.Info("bot user info", zap.Any("bot_user", botUser))
×
245

×
246
        updates, _ := t.bot.UpdatesViaLongPolling(nil)
×
247
        defer t.bot.StopLongPolling()
×
248

×
249
        bh, _ := th.NewBotHandler(t.bot, updates)
×
250
        defer bh.Stop()
×
251

×
252
        bh.HandleMessage(t.HandleMessages)
×
253
        bh.HandleEditedMessage(t.HandleMessages)
×
254

×
255
        t.logger.Info("telego initialized")
×
256
        bh.Start()
×
257
}
258

259
func (t *Telego) Stop() {
×
260
        t.bot.StopLongPolling()
×
261
}
×
262

263
func (t *Telego) GetBot() *telego.Bot {
×
264
        return t.bot
×
265
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc