diff --git a/channels/leaveduserchecker.go b/channels/leaveduserchecker.go new file mode 100644 index 0000000..f8c56b1 --- /dev/null +++ b/channels/leaveduserchecker.go @@ -0,0 +1,97 @@ +package channels + +import ( + "git.dragon-labs.de/alphyron/group_helper/logic" + "git.dragon-labs.de/alphyron/group_helper/models" + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" + "log" + "time" +) + +func CheckForLeavingUser(ticker *time.Ticker, quitChannel <-chan struct{}, groupHelperService logic.GroupHelperService, bot *tgbotapi.BotAPI) { + for { + select { + case <-ticker.C: + + groups, err := groupHelperService.ListGroups() + + if err != nil { + log.Println("Error while getting all groups in the LeavingChecking routine") + log.Println(err) + continue + } + + for _, group := range groups { + time.Sleep(500 * time.Millisecond) + config := tgbotapi.ChatConfig{ + ChatID: group.GroupID, + } + + teleSize, _ := bot.GetChatMembersCount(config) + teleSize -= 1 + sqlSize, err := groupHelperService.GetGroupDatabaseSize(group) + + if err != nil { + log.Println("Error while counting the user in group") + log.Println(err) + continue + } + + if teleSize == sqlSize { + continue + } + + if sqlSize < teleSize { + group.Size = teleSize + groupHelperService.UpdateGroup(group) + continue + } + + if teleSize < sqlSize { + checkGroupUser(group, groupHelperService, bot) + groupHelperService.UpdateGroup(group) + } + } + + case <-quitChannel: + ticker.Stop() + return + } + } +} + +func checkGroupUser(group *models.Group, groupHelperService logic.GroupHelperService, bot *tgbotapi.BotAPI) { + rate := time.Second / 5 + throttle := time.Tick(rate) + + users, err := groupHelperService.ListGroupUsers(group) + + if err != nil { + log.Println("Error while getting the users for group while checking for leaved user") + log.Println(err) + return + } + + for _, user := range users { + <-throttle // rate limit our Service.Method RPCs + + userConfig := tgbotapi.ChatConfigWithUser{ + ChatID: group.GroupID, + UserID: int(user.UserID), + } + + member, _ := bot.GetChatMember(userConfig) + + if !member.HasLeft() { + continue + } + + leaveMessage := group.UserLeaveMessage + //TODO Replace placeholder + + msg := tgbotapi.NewMessage(group.GroupID, leaveMessage) + msg.ParseMode = "Markdown" + bot.Send(msg) + groupHelperService.UserLeaveGroup(user, group) + } +} diff --git a/logic/grouphelperservice.go b/logic/grouphelperservice.go index f13028b..fb2b010 100644 --- a/logic/grouphelperservice.go +++ b/logic/grouphelperservice.go @@ -99,6 +99,10 @@ func (g groupHelperService) ListGroups() ([]*models.Group, error) { return g.groupHelperRepo.ListGroups() } +func (g groupHelperService) ListGroupUsers(group *models.Group) ([]*models.User, error) { + return g.groupHelperRepo.ListGroupUsers(group) +} + func (g groupHelperService) ListUsers() ([]*models.User, error) { return g.groupHelperRepo.ListUsers() } diff --git a/logic/service.go b/logic/service.go index 68d418a..7ae3057 100644 --- a/logic/service.go +++ b/logic/service.go @@ -19,5 +19,6 @@ type GroupHelperService interface { IsUserInGroup(*models.User, *models.Group) (bool, error) ListGroups() ([]*models.Group, error) + ListGroupUsers(*models.Group) ([]*models.User, error) ListUsers() ([]*models.User, error) } diff --git a/main.go b/main.go index 11ccb92..2d7910e 100644 --- a/main.go +++ b/main.go @@ -65,10 +65,12 @@ func main() { cm := InitialCommandManager(bot, service) rm := InitialRoutineManager(bot, cm, service, userData) - ticker := time.NewTicker(1 * time.Minute) + verifyTicker := time.NewTicker(1 * time.Minute) + leaveTicker := time.NewTicker(1 * time.Minute) quit := make(chan struct{}) - go channels.CheckUnverifiedUser(ticker, quit, service, bot, userData) + go channels.CheckUnverifiedUser(verifyTicker, quit, service, bot, userData) + go channels.CheckForLeavingUser(leaveTicker, quit, service, bot) rm.StartUpdates() } diff --git a/models/group.go b/models/group.go index 76a74d9..333d66e 100644 --- a/models/group.go +++ b/models/group.go @@ -14,6 +14,10 @@ type Group struct { Users []*User `gorm:"many2many:GroupUser;"` } +func (Group) TableName() string { + return "Groups" +} + func (group *Group) FillDefaultValues() { if len(group.UserKickMessage) == 0 { group.UserKickMessage = "[{{user.firstname}} {{user.lastname}}](tg://user?id={{user.id}}) did not verify!\n They are going to leave us." diff --git a/models/user.go b/models/user.go index d517522..730096b 100644 --- a/models/user.go +++ b/models/user.go @@ -5,3 +5,7 @@ type User struct { UserID int64 `json:"user_id"` Groups []*Group `json:"groups" gorm:"many2many:GroupUser;"` } + +func (User) TableName() string { + return "Users" +} diff --git a/repository/sql/grouphelprepository.go b/repository/sql/grouphelprepository.go index 65d1581..ad47e9a 100644 --- a/repository/sql/grouphelprepository.go +++ b/repository/sql/grouphelprepository.go @@ -183,6 +183,16 @@ func (g groupHelperRepository) ListGroups() ([]*models.Group, error) { return groups, nil } +func (g groupHelperRepository) ListGroupUsers(group *models.Group) ([]*models.User, error) { + var users []*models.User + err := g.Conn.Model(group).Related(&users, "GroupUser").Error + + if err != nil { + return nil, errors.New("problem while getting all users from group - " + err.Error()) + } + return users, nil +} + func (g groupHelperRepository) ListUsers() ([]*models.User, error) { var users []*models.User err := g.Conn.Find(&users).Error