Skip to content

Commit 71f2523

Browse files
authored
Merge pull request #2 from commonlispbr/feature/troll-shield-anti-ban-system
Feature: troll shield anti ban system
2 parents 8b116f5 + 7acb3b9 commit 71f2523

File tree

2 files changed

+129
-9
lines changed

2 files changed

+129
-9
lines changed

troll_shield.go

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type TrollShieldBot interface {
2020
GetChatMember(telegram.ChatConfigWithUser) (telegram.ChatMember, error)
2121
KickChatMember(telegram.KickChatMemberConfig) (telegram.APIResponse, error)
2222
Send(telegram.Chattable) (telegram.Message, error)
23+
LeaveChat(telegram.ChatConfig) (telegram.APIResponse, error)
24+
GetUpdatesChan(telegram.UpdateConfig) (telegram.UpdatesChannel, error)
2325
}
2426

2527
// blacklist groups, member from that groups will be kicked automatically
@@ -68,7 +70,7 @@ func getUserName(user telegram.User) string {
6870
return username
6971
}
7072

71-
func getUpdates(bot *telegram.BotAPI) telegram.UpdatesChannel {
73+
func getUpdates(bot TrollShieldBot) telegram.UpdatesChannel {
7274
u := telegram.NewUpdate(0)
7375
u.Timeout = 60
7476
updates, err := bot.GetUpdatesChan(u)
@@ -176,41 +178,92 @@ func setupLogging() {
176178
}
177179
}
178180

179-
func setupBot() *telegram.BotAPI {
180-
token, exists := os.LookupEnv("TELEGRAM_BOT_TOKEN")
181+
func setupBot(envVar string) (*telegram.BotAPI, error) {
182+
token, exists := os.LookupEnv(envVar)
181183
if !exists {
182-
log.Fatal("TELEGRAM_BOT_TOKEN env should be defined.")
184+
return nil, fmt.Errorf("%s env should be defined", envVar)
183185
}
184186
bot, err := telegram.NewBotAPI(token)
185187

186188
if err != nil {
187-
log.Panic(err)
189+
return nil, fmt.Errorf("Setup %v failed with: %v", envVar, err)
188190
}
189191

190192
bot.Debug = true
191193

192194
log.Printf("Authorized on account @%s", bot.Self.UserName)
193195

194-
return bot
196+
return bot, nil
197+
}
198+
199+
func setupHiddenBot(bot *telegram.BotAPI) *telegram.BotAPI {
200+
log.Println("Setup the hidden bot")
201+
botHidden, err := setupBot("TELEGRAM_BOT_HIDDEN_TOKEN")
202+
if err != nil {
203+
log.Printf("Bot setup failed: %v. Fallback to main bot.", err)
204+
botHidden = bot
205+
}
206+
207+
return botHidden
208+
209+
}
210+
211+
func setupBots() (*telegram.BotAPI, *telegram.BotAPI, error) {
212+
log.Println("Setup the main bot")
213+
bot, err := setupBot("TELEGRAM_BOT_TOKEN")
214+
if err != nil {
215+
return nil, nil, err
216+
}
217+
218+
return bot, setupHiddenBot(bot), nil
219+
}
220+
221+
func leaveChat(bot TrollShieldBot, update *telegram.Update, trollGroup string) {
222+
reply(bot, update, "Nesse grupo há trolls. Dou-me a liberdade de ir embora. Adeus.")
223+
r, err := bot.LeaveChat(telegram.ChatConfig{ChatID: update.Message.Chat.ID})
224+
if !r.Ok || err != nil {
225+
log.Printf("Bot tried to exit from %v, but failed with: %v",
226+
trollGroup, err,
227+
)
228+
}
195229
}
196230

197231
func main() {
198232
setupLogging()
199-
bot := setupBot()
233+
bot, botHidden, err := setupBots()
234+
if err != nil {
235+
log.Fatal(err.Error())
236+
}
237+
200238
for update := range getUpdates(bot) {
201239
if messageEvent(&update) {
202240
if update.Message.Text == "/lelerax" {
203241
reply(bot, &update, "Estou vivo.")
204242
}
243+
244+
// Exit automatically from group after the bot receive a message from it
245+
for _, trollGroup := range trollGroups {
246+
if fromChatEvent(&update, strings.TrimLeft(trollGroup, "@")) {
247+
leaveChat(bot, &update, trollGroup)
248+
}
249+
}
205250
}
206251

207252
if newChatMemberEvent(&update) {
208253
for _, member := range *update.Message.NewChatMembers {
209-
if trollHouse := findTrollHouses(bot, member.ID); trollHouse != "" {
254+
if trollHouse := findTrollHouses(botHidden, member.ID); trollHouse != "" {
210255
kickTroll(bot, &update, member, trollHouse)
211256
} else if fromChatEvent(&update, "commonlispbr") && !member.IsBot {
212257
welcomeMessage(bot, &update, member)
213258
}
259+
260+
// Exit automatically from groups when I'm joining it
261+
for _, trollGroup := range trollGroups {
262+
if fromChatEvent(&update, strings.TrimLeft(trollGroup, "@")) && member.UserName == bot.Self.UserName {
263+
leaveChat(bot, &update, trollGroup)
264+
}
265+
}
266+
214267
}
215268
}
216269
}

troll_shield_test.go

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"errors"
5+
"os"
56
"testing"
67

78
telegram "github.com/go-telegram-bot-api/telegram-bot-api"
@@ -25,13 +26,32 @@ func (bot *BotMockup) GetChatMember(c telegram.ChatConfigWithUser) (telegram.Cha
2526
}
2627

2728
func (bot *BotMockup) KickChatMember(c telegram.KickChatMemberConfig) (telegram.APIResponse, error) {
28-
return telegram.APIResponse{Ok: true}, nil
29+
switch c.ChatMemberConfig.UserID {
30+
case 0:
31+
return telegram.APIResponse{Ok: true}, nil
32+
default:
33+
return telegram.APIResponse{Ok: false}, errors.New("error")
34+
}
35+
2936
}
3037

3138
func (bot *BotMockup) Send(c telegram.Chattable) (telegram.Message, error) {
3239
return telegram.Message{}, nil
3340
}
3441

42+
func (bot *BotMockup) LeaveChat(c telegram.ChatConfig) (telegram.APIResponse, error) {
43+
switch c.ChatID {
44+
case 1:
45+
return telegram.APIResponse{Ok: true}, nil
46+
default:
47+
return telegram.APIResponse{Ok: false}, errors.New("user not found")
48+
}
49+
}
50+
51+
func (bot *BotMockup) GetUpdatesChan(c telegram.UpdateConfig) (telegram.UpdatesChannel, error) {
52+
return make(chan telegram.Update, 1), nil
53+
}
54+
3555
func TestGetUserName(t *testing.T) {
3656
user1 := telegram.User{
3757
FirstName: "Rolisvaldo",
@@ -123,6 +143,8 @@ func TestKickTroll(t *testing.T) {
123143
update.Message = &message
124144
user := telegram.User{}
125145
kickTroll(&botnilson, &update, user, "@trollhouse")
146+
user.ID = 1
147+
kickTroll(&botnilson, &update, user, "@trollhouse")
126148
}
127149

128150
func TestWelcomeMessage(t *testing.T) {
@@ -135,3 +157,48 @@ func TestWelcomeMessage(t *testing.T) {
135157
user := telegram.User{}
136158
welcomeMessage(&botnilson, &update, user)
137159
}
160+
161+
func TestSetupBot(t *testing.T) {
162+
envVar := "TELEGRAM_BOT_TOKEN"
163+
if err := os.Setenv(envVar, "123"); err != nil {
164+
t.Errorf("Setup env var TELEGRAM_BOT_TOKEN error: %v", err)
165+
}
166+
167+
if _, err := setupBot(envVar); err == nil {
168+
t.Errorf("Invalid token should go fail, got nil error")
169+
}
170+
171+
if _, err := setupBot("???"); err == nil {
172+
t.Errorf("Non-defined env var should go fail, got nil error.")
173+
}
174+
}
175+
176+
func TestSetupBots(t *testing.T) {
177+
bot, _, err := setupBots()
178+
if err == nil {
179+
t.Errorf("setupBots fail with invalid tokens.")
180+
}
181+
botHidden := setupHiddenBot(bot)
182+
if botHidden != bot {
183+
t.Errorf("When botHidden fails to start, use bot as fallback")
184+
}
185+
}
186+
187+
func TestSetupLogging(t *testing.T) {
188+
setupLogging()
189+
}
190+
191+
func TestLeaveChat(t *testing.T) {
192+
bot := BotMockup{}
193+
update := telegram.Update{}
194+
message := telegram.Message{}
195+
chat := telegram.Chat{}
196+
message.Chat = &chat
197+
update.Message = &message
198+
leaveChat(&bot, &update, "trolleira")
199+
}
200+
201+
func TestGetUpdates(t *testing.T) {
202+
bot := BotMockup{}
203+
getUpdates(&bot)
204+
}

0 commit comments

Comments
 (0)