diff --git a/src/barandaBot.go b/src/barandaBot.go index a50027d..f30fac1 100644 --- a/src/barandaBot.go +++ b/src/barandaBot.go @@ -19,8 +19,8 @@ func main() { if cmdFlags.interactive { mainMenu() - } else if cmdFlags.tokens != nil { - err = addBotTokens(cmdFlags.tokens) + } else if cmdFlags.token != "" { + err = setBotToken(cmdFlags.token) if err == ErrAddToken { log.Printf("Error in adding bot tokens: %v", err) } diff --git a/src/manageAdmin.go b/src/manageAdmin.go new file mode 100644 index 0000000..f23fa56 --- /dev/null +++ b/src/manageAdmin.go @@ -0,0 +1,164 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" + "regexp" + "strconv" + "strings" + + "github.com/dixonwille/wmenu" + tb "gopkg.in/tucnak/telebot.v2" +) + +func addBotAdmins(newAdminIDs []string) error { + if redisClient == nil { + return ErrNilPointer + } + errNum := 0 + if newAdminIDs == nil && cmdFlags.interactive { + fmt.Println("Add the new admin IDs, comma-separated:") + reader := bufio.NewReader(os.Stdin) + line, err := reader.ReadString('\n') + if err != nil { + log.Printf("Error in reading new admin IDs: %v", err) + return ErrStdRead + } + newAdminIDs = strings.Split(line, ",") + } + for _, newAdminID := range newAdminIDs { + err := addBotAdmin(newAdminID) + if err != nil { + errNum++ + log.Printf("Error in adding new admin ID %s: %v", newAdminID, err) + } + } + if errNum == len(newAdminIDs) { + return ErrAddAdmin + } + return nil +} + +func removeBotAdmins() error { + if redisClient == nil { + return ErrNilPointer + } + botAdmins, err := redisClient.SMembers(adminSet).Result() + if err != nil { + log.Printf("Couldn't retrieve admins: %v", err) + return ErrRedisRetrieveSet + } + menu := wmenu.NewMenu("Select the admin(s) you want to remove:") + menu.AllowMultiple() + menu.LoopOnInvalid() + menu.Action(func(opts []wmenu.Opt) error { + var returnErr error + for _, opt := range opts { + if opt.Value == nil { + log.Println("Couldn't remove admin: nil token") + returnErr = ErrNilPointer + } else { + err := removeBotAdmin(opt.Value.(int)) + if err != nil { + log.Printf("Couldn't remove bot admin: %v", err) + } + } + } + return returnErr + }) + //for _, token := range tokens { + for _, botAdmin := range botAdmins { + adminID, err := strconv.Atoi(botAdmin) + if err != nil { + log.Printf("Error converting adminID from string to int: %v", err) + return ErrAtoiConv + } + adminInfo, err := getUserInfo(adminID) + menu.Option(adminInfo.Username+": "+adminInfo.FirstName+" "+adminInfo.LastName, adminID, false, nil) + } + err = menu.Run() + if err != nil { + log.Printf("Error in removeToken menu: %v", err) + return ErrRemoveAdmin + } + return nil +} + +func addBotAdmin(newAdminID string) error { + if redisClient == nil { + return ErrNilPointer + } + adminID := strings.TrimSpace(newAdminID) + matched, err := regexp.MatchString("^\\d+$", adminID) + if err != nil { + log.Printf("Error in parsing admin ID: %v", err) + return ErrIDParsing + } + if !matched { + return ErrIDInvalid + } + + ID, err := strconv.Atoi(adminID) + if err != nil { + log.Printf("Error converting user ID: %v", err) + return ErrAtoiConv + } + chat, err := bot.ChatByID(adminID) + if err != nil { + log.Printf("Error retriving chat by id: %v", err) + return ErrChatRetrieve + } + if chat.Type != tb.ChatPrivate { + log.Printf("Admin must be a user!") + return ErrAddAdmin + } + isUser, err := isUser(ID) + if err != nil { + log.Printf("Error checking if ID is bot user: %v", err) + return ErrAddAdmin + } + if !isUser { + err = addUser(&tb.User{int(chat.ID), chat.FirstName, chat.LastName, chat.Username}) + if err != nil { + log.Printf("Error adding user: %v", err) + return ErrAddUser + } + } + err = redisClient.SAdd(adminSet, adminID).Err() + if err != nil { + log.Printf("Error in adding new admin ID: %v", err) + return ErrRedisAddSet + } + + err = authorizeUser(ID, true) + if err != nil { + log.Printf("Error in adding new admin ID in authorized users: %v", err) + return ErrAddAuthUser + } + user, err := getUserInfo(ID) + if err != nil { + log.Printf("Error getting user info: %v", err) + return ErrGetUser + } + err = sendMessage(user, "Sei stato aggiunto come amministratore del BarandaBot") + if err != nil { + log.Printf("Error sending message to new admin: %v", err) + return ErrSendMsg + } + + return nil +} + +func removeBotAdmin(adminID int) error { + if redisClient == nil { + return ErrNilPointer + } + err := redisClient.SRem(adminSet, strconv.Itoa(adminID)).Err() + if err != nil { + log.Printf("Error removing admin from set: %v", err) + return ErrRedisRemSet + } + return nil +} diff --git a/src/manageBot.go b/src/manageBot.go new file mode 100644 index 0000000..aa359a4 --- /dev/null +++ b/src/manageBot.go @@ -0,0 +1,97 @@ +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "log" + "os" + "regexp" + "strings" + + tb "gopkg.in/tucnak/telebot.v2" +) + +func setBotToken(newToken string) error { + var err error + if redisClient == nil { + return ErrNilPointer + } + if newToken == "" && cmdFlags.interactive { + fmt.Println("Add the new token:") + reader := bufio.NewReader(os.Stdin) + newToken, err = reader.ReadString('\n') + if err != nil { + log.Printf("Error in reading new bot token: %v", err) + return ErrStdRead + } + } + token := strings.TrimSpace(newToken) + matched, err := regexp.MatchString("^\\d+\\:([0-9]|[A-z]|\\_|\\-)+", token) + if err != nil { + log.Printf("Error in parsing bot token: %v", err) + return ErrTokenParsing + } + if !matched { + return ErrTokenInvalid + } + + err = redisClient.Set(botToken, token, 0).Err() + if err != nil { + log.Printf("Error in adding new bot token: %v", err) + return ErrRedisAddSet + } + + return nil +} + +func getBotToken() (string, error) { + if redisClient == nil { + return "", ErrNilPointer + } + token, err := redisClient.Get(botToken).Result() + if err != nil { + log.Printf("Couldn't retrieve bot token: %v", err) + return "", ErrRedisRetrieveSet + } + if token == "" { + fmt.Println("No bot token found.") + err := setBotToken("") + if err != nil { + log.Printf("Couldn't add new bot tokens: %v", err) + return "", ErrAddToken + } + } + + return token, nil +} + +func addBotInfo(botToken string, bot *tb.Bot) error { + if redisClient == nil { + return ErrNilPointer + } + jsonBot, err := json.Marshal(&bot) + if err != nil { + log.Printf("Error marshalling bot info: %v", err) + return ErrJSONMarshall + } + err = redisClient.HSet(botHash, botToken, string(jsonBot)).Err() + if err != nil { + log.Printf("Error in adding bot info: %v", err) + return ErrRedisAddHash + } + + return nil +} + +func removeBotInfo(botToken string) error { + if redisClient == nil { + return ErrNilPointer + } + err := redisClient.HDel(botHash, botToken).Err() + if err != nil { + log.Printf("Error in removing bot info: %v", err) + return ErrRedisDelHash + } + return nil +} diff --git a/src/manageUser.go b/src/manageUser.go new file mode 100644 index 0000000..99614e7 --- /dev/null +++ b/src/manageUser.go @@ -0,0 +1,94 @@ +package main + +import ( + "encoding/json" + "log" + "strconv" + + tb "gopkg.in/tucnak/telebot.v2" +) + +func addUser(user *tb.User) error { + if redisClient == nil { + return ErrNilPointer + } + err := redisClient.SAdd(userSet, user.ID).Err() + if err != nil { + log.Printf("Error in adding user ID: %v", err) + return ErrRedisAddSet + } + jsonUser, err := json.Marshal(&user) + if err != nil { + log.Printf("Error in marshalling user to json: %v", err) + return ErrJSONMarshall + } + err = redisClient.HSet(userHash, strconv.Itoa(user.ID), jsonUser).Err() + if err != nil { + log.Printf("Error adding user info in hash: %v", err) + return ErrRedisAddHash + } + + return nil +} + +func isUser(userID int) (bool, error) { + if redisClient == nil { + return false, ErrNilPointer + } + user, err := redisClient.SIsMember(userSet, strconv.Itoa(userID)).Result() + if err != nil { + log.Printf("Error checking if ID is bot user: %v", err) + return false, ErrRedisCheckSet + } + return user, nil +} + +func getUserInfo(userID int) (*tb.User, error) { + if redisClient == nil { + return nil, ErrNilPointer + } + user, err := redisClient.HGet(userHash, strconv.Itoa(userID)).Result() + if err != nil { + log.Printf("Error retriving user info from hash: %v", err) + return nil, ErrRedisRetrieveHash + } + jsonUser := &tb.User{} + err = json.Unmarshal([]byte(user), jsonUser) + if err != nil { + log.Printf("Error unmarshalling user info: %v", err) + return nil, ErrJSONUnmarshall + } + return jsonUser, nil +} + +func isAuthrizedUser(userID int) (bool, error) { + if redisClient == nil { + return false, ErrNilPointer + } + auth, err := redisClient.SIsMember(authUserSet, strconv.Itoa(userID)).Result() + if err != nil { + log.Printf("Error checking if user is authorized: %v", err) + return false, ErrRedisCheckSet + } + return auth, nil +} + +func authorizeUser(userID int, authorized bool) error { + if redisClient == nil { + return ErrNilPointer + } + if authorized { + err := redisClient.SAdd(authUserSet, strconv.Itoa(userID)).Err() + if err != nil { + log.Printf("Error adding token to set: %v", err) + return ErrRedisAddSet + } + } else { + err := redisClient.SRem(authUserSet, strconv.Itoa(userID)).Err() + if err != nil { + log.Printf("Error removing token from set: %v", err) + return ErrRedisRemSet + } + } + return nil +} diff --git a/src/redisAPI.go b/src/redisAPI.go index ff10c18..fe427e3 100644 --- a/src/redisAPI.go +++ b/src/redisAPI.go @@ -1,27 +1,19 @@ package main import ( - "bufio" - "encoding/json" "errors" - "fmt" "log" - "os" - "regexp" - "strconv" - "strings" - "github.com/dixonwille/wmenu" "github.com/go-redis/redis" - tb "gopkg.in/tucnak/telebot.v2" ) const ( - tkSet = "botToken" + botToken = "botToken" botHash = "botInfo" userSet = "userID" userHash = "userInfo" authUserSet = "authUser" + adminSet = "adminID" ) var redisClient *redis.Client @@ -33,24 +25,34 @@ var ( ErrRedisAddSet = errors.New("redis: couldn't add key in set") //ErrRedisRemSet is thrown when it's not possible to remove a key from a given set ErrRedisRemSet = errors.New("redis: couldn't remove key from set") - //ErrRedisRetriveSet is thrown when it's not possible to retrive keys from a set - ErrRedisRetriveSet = errors.New("redis: couldn't retrive keys from set") + //ErrRedisRetrieveSet is thrown when it's not possible to retrieve keys from a set + ErrRedisRetrieveSet = errors.New("redis: couldn't retrieve keys from set") //ErrRedisCheckSet is thrown when it's not possible to check if a key is in a given set ErrRedisCheckSet = errors.New("redis: couldn't check if key is in set") //ErrRedisAddHash is thrown when it's not possible to add a key in a hash ErrRedisAddHash = errors.New("redis: couldn't add key in hash") //ErrRedisDelHash is thrown when it's not possible to remove a key from a hash ErrRedisDelHash = errors.New("redis: couldn't remove key from hash") + //ErrRedisRetrieveHash is thrown when it's not possible to retrieve a key from a hash + ErrRedisRetrieveHash = errors.New("redis: couldn't retrieve key from hash") //ErrTokenParsing is thrown when it's not possible to parse the bot token ErrTokenParsing = errors.New("botToken: cannot parse token") //ErrTokenInvalid is thrown when the string parsed isn't a valid telegram bot token ErrTokenInvalid = errors.New("botToken: string isn't a valid telegram bot token") + //ErrIDParsing is thrown when it's not possible to parse the user ID + ErrIDParsing = errors.New("userID: cannot parse ID") + //ErrIDInvalid is thrown when the string parsed isn't a valid telegram user ID + ErrIDInvalid = errors.New("userID: string isn't a valid telegram user ID") //ErrAddToken is thrown when one or more bot token hasn't been added ErrAddToken = errors.New("couldn't add one or more tokens") - //ErrRemoveToken is thrown when one or more bot tokens hasn't been removed - ErrRemoveToken = errors.New("couldn't remove one or more tokens") - //ErrJSONMarshall is thrown when it's impossible to marshall a given struct - ErrJSONMarshall = errors.New("json: couldn't marshall struct") + //ErrAddUser is thrown when one or more user hasn't been added + ErrAddUser = errors.New("couldn't add one or more users") + //ErrAddAdmin is thrown when one or more admin IDs hasn't been added + ErrAddAdmin = errors.New("couldn't add one or more admins") + //ErrAddAuthUser is thrown when one or more users cannot be authorized + ErrAddAuthUser = errors.New("couldn't authorize one or more users") + //ErrGetUser is thrown when user info couldn't be retrieven + ErrGetUser = errors.New("couldn't retrieve user info") ) func redisInit(addr string, pwd string, db int) error { @@ -66,224 +68,3 @@ func redisInit(addr string, pwd string, db int) error { } return nil } - -func addBotToken(newToken string) error { - if redisClient == nil { - return ErrNilPointer - } - token := strings.TrimSpace(newToken) - matched, err := regexp.MatchString("^\\d+\\:([0-9]|[A-z]|\\_|\\-)+", token) - if err != nil { - log.Printf("Error in parsing bot token: %v", err) - return ErrTokenParsing - } - if !matched { - return ErrTokenInvalid - } - - err = redisClient.SAdd(tkSet, token).Err() - if err != nil { - log.Printf("Error in adding new bot token: %v", err) - return ErrRedisAddSet - } - - return nil -} - -func addBotTokens(newTokens []string) error { - if redisClient == nil { - return ErrNilPointer - } - errNum := 0 - if newTokens == nil && cmdFlags.interactive { - fmt.Println("Add the new tokens, comma-separated:") - reader := bufio.NewReader(os.Stdin) - line, err := reader.ReadString('\n') - if err != nil { - log.Printf("Error in reading new bot tokens: %v", err) - return ErrStdRead - } - newTokens = strings.Split(line, ",") - } - for _, newToken := range newTokens { - err := addBotToken(newToken) - if err != nil { - errNum++ - log.Printf("Error in adding new bot token %s: %v", newToken, err) - } - } - if errNum == len(newTokens) { - return ErrAddToken - } - return nil -} - -func removeBotToken(token string) error { - if redisClient == nil { - return ErrNilPointer - } - err := redisClient.SRem(tkSet, token).Err() - if err != nil { - log.Printf("Error in removing bot token %s: %v", token, err) - return ErrRemoveToken - } - return nil -} - -func removeBotTokens() error { - if redisClient == nil { - return ErrNilPointer - } - //tokens, err := redisClient.SMembers(tkSet).Result() - botsInfo, err := redisClient.HGetAll(botHash).Result() - if err != nil { - log.Printf("Couldn't retrive bot info: %v", err) - return ErrRedisRetriveSet - } - menu := wmenu.NewMenu("Select the token(s) you want to remove:") - menu.AllowMultiple() - menu.LoopOnInvalid() - menu.Action(func(opts []wmenu.Opt) error { - var returnErr error - for _, opt := range opts { - if opt.Value == nil { - log.Println("Couldn't remove bot: nil token") - returnErr = ErrNilPointer - } else { - err := removeBotToken(opt.Value.(string)) - if err != nil { - log.Printf("Couldn't remove bot token: %v", err) - } - err = removeBotInfo(opt.Value.(string)) - if err != nil { - log.Printf("Couldn't remove bot info: %v", err) - } - } - } - return returnErr - }) - //for _, token := range tokens { - for token, jsonBotInfo := range botsInfo { - botInfo := &tb.Bot{} - json.Unmarshal([]byte(jsonBotInfo), &botInfo) - menu.Option(botInfo.Me.Username, token, false, nil) - } - err = menu.Run() - if err != nil { - log.Printf("Error in removeToken menu: %v", err) - return ErrRemoveToken - } - return nil -} - -func getBotTokens() ([]string, error) { - if redisClient == nil { - return nil, ErrNilPointer - } - tkNum, err := redisClient.SCard(tkSet).Result() - if err != nil { - log.Printf("Couldn't retrive number of bot tokens: %v", err) - return nil, ErrRedisRetriveSet - } - if tkNum == 0 { - fmt.Println("No bot token found.") - err := addBotTokens(nil) - if err != nil { - log.Printf("Couldn't add new bot tokens: %v", err) - return nil, ErrAddToken - } - } - - tokens, err := redisClient.SMembers(tkSet).Result() - if err != nil { - log.Printf("Couldn't retrive bot tokens: %v", err) - return nil, ErrRedisRetriveSet - } - - return tokens, nil -} - -func addBotInfo(botToken string, bot *tb.Bot) error { - if redisClient == nil { - return ErrNilPointer - } - jsonBot, err := json.Marshal(&bot) - if err != nil { - log.Printf("Error marshalling bot info: %v", err) - return ErrJSONMarshall - } - err = redisClient.HSet(botHash, botToken, string(jsonBot)).Err() - if err != nil { - log.Printf("Error in adding bot info: %v", err) - return ErrRedisAddHash - } - - return nil -} - -func removeBotInfo(botToken string) error { - if redisClient == nil { - return ErrNilPointer - } - err := redisClient.HDel(botHash, botToken).Err() - if err != nil { - log.Printf("Error in removing bot info: %v", err) - return ErrRedisDelHash - } - return nil -} - -func addUser(user *tb.User) error { - if redisClient == nil { - return ErrNilPointer - } - err := redisClient.SAdd(userSet, user.ID).Err() - if err != nil { - log.Printf("Error in adding user ID: %v", err) - return ErrRedisAddSet - } - jsonUser, err := json.Marshal(&user) - if err != nil { - log.Printf("Error in marshalling user to json: %v", err) - return ErrJSONMarshall - } - err = redisClient.HSet(userHash, strconv.Itoa(user.ID), jsonUser).Err() - if err != nil { - log.Printf("Error adding user info in hash: %v", err) - return ErrRedisAddHash - } - - return nil -} - -func isAuthrizedUser(userID int) (bool, error) { - if redisClient == nil { - return false, ErrNilPointer - } - auth, err := redisClient.SIsMember(authUserSet, strconv.Itoa(userID)).Result() - if err != nil { - log.Printf("Error checking if user is authorized: %v", err) - return false, ErrRedisCheckSet - } - return auth, nil -} - -func authorizeUser(userID int, authorized bool) error { - if redisClient == nil { - return ErrNilPointer - } - if authorized { - err := redisClient.SAdd(authUserSet, strconv.Itoa(userID)).Err() - if err != nil { - log.Printf("Error adding token to set: %v", err) - return ErrRedisAddSet - } - } else { - err := redisClient.SRem(authUserSet, strconv.Itoa(userID)).Err() - if err != nil { - log.Printf("Error removing token from set: %v", err) - return ErrRedisRemSet - } - } - return nil -} diff --git a/src/sys.go b/src/sys.go index e086ba7..eb2226c 100644 --- a/src/sys.go +++ b/src/sys.go @@ -17,7 +17,7 @@ type flags struct { redisAddr string redisPwd string redisDB int - tokens stringSlice + token string } var cmdFlags flags @@ -28,6 +28,14 @@ var ( ErrStdRead = errors.New("stdin: couldn't read string from stdin") //ErrMainMenu is thrown when a menu couldn't be started ErrMainMenu = errors.New("menu: couldn't start menu") + //ErrAtoiConv is thrown when a string couldn't be converted to int + ErrAtoiConv = errors.New("atoi: couldn't convert string to int") + //ErrJSONMarshall is thrown when it's impossible to marshall a given struct + ErrJSONMarshall = errors.New("json: couldn't marshall struct") + //ErrJSONUnmarshall is thworn when it's impossible to unmarshall a given struct + ErrJSONUnmarshall = errors.New("json: couldn't unmarshall struct") + //ErrRemoveAdmin is thrown when it's impossible to remove an admin + ErrRemoveAdmin = errors.New("menu: cannot remove admin") ) func (i *stringSlice) String() string { @@ -52,6 +60,7 @@ func getFlags() error { pwdUsage = "The password of the redis instance" defaultDB = 0 dbUsage = "The database to be selected after connecting to redis instance" + defaultToken = "" tokenUsage = "A bot token to be added to the set of tokens" ) @@ -63,8 +72,8 @@ func getFlags() error { flag.StringVar(&(cmdFlags.redisPwd), "p", defaultPwd, pwdUsage+"(shorthand)") flag.IntVar(&(cmdFlags.redisDB), "redisDB", defaultDB, dbUsage) flag.IntVar(&(cmdFlags.redisDB), "d", defaultDB, dbUsage+"(shorthand)") - flag.Var(&(cmdFlags.tokens), "token", tokenUsage) - flag.Var(&(cmdFlags.tokens), "t", tokenUsage+"(shorthand") + flag.StringVar(&(cmdFlags.token), "token", defaultToken, tokenUsage) + flag.StringVar(&(cmdFlags.token), "t", defaultToken, tokenUsage+"(shorthand") flag.Parse() @@ -75,14 +84,17 @@ func mainMenu() error { fmt.Println(welcomeMessage) menu := wmenu.NewMenu("What do you want to do?") menu.LoopOnInvalid() - menu.Option("Start Bot(s)", nil, true, func(opt wmenu.Opt) error { - return botsStart() + menu.Option("Start Bot", nil, true, func(opt wmenu.Opt) error { + return botStart() }) - menu.Option("Add bot token(s)", nil, false, func(opt wmenu.Opt) error { - return addBotTokens(nil) + menu.Option("Set bot token", nil, false, func(opt wmenu.Opt) error { + return setBotToken("") }) - menu.Option("Remove bot token(s)", nil, false, func(opt wmenu.Opt) error { - return removeBotTokens() + menu.Option("Add bot admin(s)", nil, false, func(opt wmenu.Opt) error { + return addBotAdmins(nil) + }) + menu.Option("Remove bot admin(s)", nil, false, func(opt wmenu.Opt) error { + return removeBotAdmins() }) var returnErr error diff --git a/src/telegramAPI.go b/src/telegramAPI.go index 17c3ca4..dc91318 100644 --- a/src/telegramAPI.go +++ b/src/telegramAPI.go @@ -4,104 +4,85 @@ import ( "errors" "log" "strconv" - "sync" "time" tb "gopkg.in/tucnak/telebot.v2" ) -var bots []*tb.Bot +var bot *tb.Bot var ( //ErrNilPointer is thrown when a pointer is nil ErrNilPointer = errors.New("pointer is nil") //ErrIDFromMsg is thrown when the message doesn't contain user infos - ErrIDFromMsg = errors.New("telegram: couldn't retrive user ID from message") + ErrIDFromMsg = errors.New("telegram: couldn't retrieve user ID from message") + //ErrSendMsg is thrown when the message couldn't be send + ErrSendMsg = errors.New("telegram: cannot send message") + //ErrChatRetrive is thrown when the chat cannot be retrieved + ErrChatRetrieve = errors.New("telegram: cannot retrieve chat") ) -func botsInit() error { - tokens, err := getBotTokens() +func botInit() error { + token, err := getBotToken() if err != nil { - log.Printf("Error in retriving bot tokens: %v. Cannot start telebot without tokens.", err) + log.Printf("Error in retriving bot token: %v. Cannot start telebot without token.", err) return err } - if tokens == nil { - log.Println("Error: pointer is nil") - return ErrNilPointer - } - - for _, token := range tokens { - poller := &tb.LongPoller{Timeout: 15 * time.Second} - middlePoller := tb.NewMiddlewarePoller(poller, func(upd *tb.Update) bool { - if upd.Message == nil { - return true - } - if upd.Message.Sender != nil { - err := addUser(upd.Message.Sender) - if err != nil { - log.Printf("Error in adding user info: %v", err) - } - err = authorizeUser(upd.Message.Sender.ID, true) - if err != nil { - log.Printf("Error in authorizing user: %v", err) - } - } else { - log.Printf("%v", ErrIDFromMsg) - } - auth, err := isAuthrizedUser(upd.Message.Sender.ID) - if err != nil { - log.Printf("Error checking if user is authorized: %v", err) - } - if !auth { - return false - } - + poller := &tb.LongPoller{Timeout: 15 * time.Second} + middlePoller := tb.NewMiddlewarePoller(poller, func(upd *tb.Update) bool { + if upd.Message == nil { return true - }) - - bot, err := tb.NewBot(tb.Settings{ - Token: token, - Poller: middlePoller, - }) - - if err != nil { - log.Printf("Error in enstablishing connection for bot %s: %v", bot.Me.Username, err) - } else { - bots = append(bots, bot) - err = addBotInfo(token, bot) + } + if upd.Message.Sender != nil { + err := addUser(upd.Message.Sender) if err != nil { - log.Printf("Error: bot %s info couldn't be added: %v", bot.Me.Username, err) + log.Printf("Error in adding user info: %v", err) } + err = authorizeUser(upd.Message.Sender.ID, true) + if err != nil { + log.Printf("Error in authorizing user: %v", err) + } + } else { + log.Printf("%v", ErrIDFromMsg) + } + auth, err := isAuthrizedUser(upd.Message.Sender.ID) + if err != nil { + log.Printf("Error checking if user is authorized: %v", err) + } + if !auth { + return false } - } - return nil -} -func botsStart() error { - err := botsInit() + return true + }) + + bot, err = tb.NewBot(tb.Settings{ + Token: token, + Poller: middlePoller, + }) + if err != nil { - log.Fatalf("Error in initializing bots: %v", err) - } - - for _, bot := range bots { - defer bot.Stop() - } - - var wg sync.WaitGroup - for i := range bots { - if bots[i] != nil { - wg.Add(1) - go botStart(bots[i], &wg) + log.Printf("Error in enstablishing connection for bot %s: %v", bot.Me.Username, err) + } else { + err = addBotInfo(token, bot) + if err != nil { + log.Printf("Error: bot %s info couldn't be added: %v", bot.Me.Username, err) } } - wg.Wait() - return nil } -func botStart(bot *tb.Bot, wg *sync.WaitGroup) error { - defer wg.Done() +func sendMessage(user *tb.User, msg string) error { + _, err := bot.Send(user, msg) + if err != nil { + log.Printf("Error sending message to user: %v", err) + return ErrSendMsg + } + return nil +} + +func botStart() error { if bot == nil { return ErrNilPointer }