diff --git a/.gitignore b/.gitignore index adeb957..9e3b8db 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ _testmain.go # ---> VisualStudioCode .settings *.code-workspace +.vscode # Redis *.rdb diff --git a/src/manageUser.go b/src/manageUser.go index b570bb2..ab5536f 100644 --- a/src/manageUser.go +++ b/src/manageUser.go @@ -309,24 +309,45 @@ func convertUserGroups(groups []userGroup) []string { func getGroupName(group userGroup) (string, error) { switch group { case ugSoprano: - return "Soprano", nil + return "Soprani", nil case ugContralto: - return "Contralto", nil + return "Contralti", nil case ugTenore: - return "Tenore", nil + return "Tenori", nil case ugBasso: - return "Basso", nil + return "Bassi", nil case ugCommissario: - return "Commissario", nil + return "Commissari", nil case ugReferente: - return "Referente", nil + return "Referenti", nil case ugPreparatore: - return "Preparatore", nil + return "Preparatori", nil default: return "", ErrGroupInvalid } } +func getUserGroupFromStr(group string) (userGroup, error) { + switch strings.ToLower(group) { + case "soprano", "soprani": + return ugSoprano, nil + case "contralto", "contralti": + return ugContralto, nil + case "tenore", "tenori": + return ugTenore, nil + case "basso", "bassi": + return ugBasso, nil + case "commissario", "commissari", "commissarii": + return ugCommissario, nil + case "referente", "referenti": + return ugReferente, nil + case "preparatore", "preparatori": + return ugPreparatore, nil + default: + return -1, ErrGroupInvalid + } +} + func getUserDescription(u *tb.User) (string, error) { userGroups, err := getUserGroups(u.ID) if err != nil { diff --git a/src/telegramAPI.go b/src/telegramAPI.go index ab891eb..1e50969 100644 --- a/src/telegramAPI.go +++ b/src/telegramAPI.go @@ -3,6 +3,7 @@ package main import ( "errors" "log" + "sort" "time" tb "gopkg.in/tucnak/telebot.v2" @@ -32,6 +33,9 @@ const ( "\n- \xF0\x9F\x90\xA6 _Piccione viaggiatore_: [Palazzo Ricci, Pisa](https://goo.gl/maps/gMUbV2eqJiL2)" + "\n- \xF0\x9F\x93\xA7 _Mail_: telebot.corounipi@gmail.com" + "\n- \xF0\x9F\x93\x82 _GitHub_: https://github.com/Noettore/barandaBot" + sendMsgHowToMsg string = "Per inviare un messaggio ad una sezione invia il comando \n`/sendMsg SEZIONE TESTO_MESSAGGIO` sostituendo `SEZIONE` con il nome della sezione a cui inviare il messaggio e `TESTO_MESSAGGIO` con il testo del messaggio che vuoi recapitare" + sendMsgErrMsg string = "Puoi inviare messaggi soltanto alle sezioni cui appartieni" + msgReceivedMsg string = "Hai ricevuto questo messaggio perché fai parte di una sezione del Coro UniPi. Se non vuoi piú riceverne fallo presente!" ) var bot *tb.Bot @@ -57,6 +61,13 @@ var ( ErrInvalidPath = errors.New("path is not valid") ) +//Dynamic messages +var ( + helpGenericMsg string + helpAuthMsg string + helpAdminMsg string +) + func botInit() error { token, err := getBotToken() if err != nil { @@ -94,6 +105,8 @@ func botInit() error { return ErrBotInit } + setBotDynamicMsg() + err = addBotInfo(bot.Me.Username) if err != nil { log.Printf("Error: bot %s info couldn't be added: %v", bot.Me.Username, err) @@ -151,15 +164,48 @@ func setBotPoller(upd *tb.Update) bool { if err != nil { log.Printf("Error checking if user is admin: %v", err) } - if isAdminCmd && admin == false { + if isAdminCmd && !admin { return false } - if isAuthCmd && auth == false { + if isAuthCmd && !auth { return false } return true } +func setBotDynamicMsg() { + cmdArray := make([]string, 0, len(genericCommands)) + for cmd, desc := range genericCommands { + cmdArray = append(cmdArray, cmd+": "+desc+"\n") + } + sort.Strings(cmdArray) + helpGenericMsg += "*Comandi del Bot*\n" + for _, cmd := range cmdArray { + helpGenericMsg += cmd + } + + cmdArray = make([]string, 0, len(authCommands)) + for cmd, desc := range authCommands { + cmdArray = append(cmdArray, cmd+": "+desc+"\n") + } + sort.Strings(cmdArray) + helpAuthMsg += "\n*Comandi Utenti Autenticati*\n" + for _, cmd := range cmdArray { + helpAuthMsg += cmd + } + + cmdArray = make([]string, 0, len(adminCommands)) + for cmd, desc := range adminCommands { + cmdArray = append(cmdArray, cmd+": "+desc+"\n") + } + sort.Strings(cmdArray) + helpAdminMsg += "\n*Comandi Amministratori*\n" + for _, cmd := range cmdArray { + helpAdminMsg += cmd + } + +} + func botStart() error { if bot == nil { return ErrNilPointer diff --git a/src/telegramCommands.go b/src/telegramCommands.go index 171cbf0..7abb961 100644 --- a/src/telegramCommands.go +++ b/src/telegramCommands.go @@ -3,31 +3,30 @@ package main import ( "log" "strconv" + "strings" tb "gopkg.in/tucnak/telebot.v2" ) -var genericCommands = map[string]bool{ - "/start": true, - "/stop": true, - "/menu": true, - "/userInfo": true, - "/config": true, - "/botInfo": true, - "/help": true, - "/prossimoEvento": true, +var genericCommands = map[string]string{ + "/start": "Far (ri)partire il bot", + "/stop": "Fermare il bot", + "/menu": "Visualizzare il menu principale", + "/userInfo": "Visualizzare le informazioni sul mio utente", + "/botInfo": "Visualizzare le informazioni sul bot", + "/help": "Visualizzare questo menu di aiuto", + "/prossimoEvento": "Visualizzare le informazioni sul prossimo evento del coro", } -var authCommands = map[string]bool{ - "/prossimaProva": true, - "/prossimaProvaSezione": true, - "/prossimaProvaInsieme": true, - "/ultimaMail": true, +var authCommands = map[string]string{ + "/prossimaProva": "Visualizzare le informazioni sulla prossima prova", + "/prossimaProvaSezione": "Visualizzare le informazioni sulla prossima prova di sezione", + "/prossimaProvaInsieme": "Visualizzare le informazioni sulla prossima prova d'insieme", + "/ultimaMail": "Visualizzare l'ultima mail inviata alla sezione o a tutto il coro", } -var adminCommands = map[string]bool{ - "/authUser": true, - "/deAuthUser": true, - "/addAdmin": true, - "/delAdmin": true, +var adminCommands = map[string]string{ + "/authUser": "Autorizzare un nuovo utente o aggiungerlo a nuovi gruppi", + "/deAuthUser": "Deautorizzare un utente o rimuoverlo da alcuni gruppi", + "/sendMsg": "Inviare un messaggio ad una o piú delle sezioni di appartenenza", } func startCmd(u *tb.User, newMsg bool) { @@ -66,10 +65,11 @@ func startCmd(u *tb.User, newMsg bool) { } } -func stopCmd(u *tb.User) { +func stopCmd(u *tb.User, newMsg bool) { admin, err := isBotAdmin(u.ID) if err != nil { log.Printf("Error checking if user is admin: %v", err) + return } if admin { //img := &tb.Photo{File: tb.FromDisk()} @@ -82,7 +82,7 @@ func stopCmd(u *tb.User) { if err != nil { log.Printf("Error starting user: %v", err) } - err := sendMsgWithSpecificMenu(u, stopMsg, startMenu, false) + err := sendMsgWithSpecificMenu(u, stopMsg, startMenu, newMsg) if err != nil { log.Printf("Error sending message to stopped user: %v", err) } @@ -265,3 +265,75 @@ func addUserGroupCmd(userID int, group userGroup, add bool) error { } return nil } + +func helpCmd(user *tb.User, newMsg bool) { + var msg string + msg += helpGenericMsg + + isAuth, err := isAuthrizedUser(user.ID) + if err != nil { + log.Printf("Error checking if user is authorized: %v", err) + } else if isAuth { + msg += helpAuthMsg + } + + isAdmin, err := isBotAdmin(user.ID) + if err != nil { + log.Printf("Error checking if user is admin: %v", err) + } else if isAdmin { + msg += helpAdminMsg + } + + err = sendMsgWithSpecificMenu(user, msg, backMenu, newMsg) + if err != nil { + log.Printf("Error sending message to started user: %v", err) + } +} + +func sendMsgCmd(sender *tb.User, payload string, newMsg bool) { + arg := strings.SplitN(payload, " ", 2) + if payload == "" || len(arg) != 2 || arg[1] == "" || arg[1] == " " { + err := sendMsgWithMenu(sender, sendMsgHowToMsg, newMsg) + if err != nil { + log.Printf("Error in sending message: %v", err) + } + } else { + group, err := getUserGroupFromStr(arg[0]) + if err != nil { + log.Printf("Error in parsing the userGroup: %v", err) + return + } + + is, err := isUserInGroup(sender.ID, group) + if err != nil { + log.Printf("Error checking if sender is in sendTo group: %v", err) + return + } + if is { + users, err := getUsersInGroup(group) + if err != nil { + log.Printf("Error retrieving users in sendTo group: %v", err) + return + } + for _, userID := range users { + user, err := getUserInfo(userID) + if err != nil { + log.Printf("Error retrieving user info from id: %v", err) + continue + } + groupName, _ := getGroupName(group) + msg := "*Messaggio inviato da " + sender.FirstName + " a tutta la sezione " + groupName + "*\n" + arg[1] + err = sendMsg(user, msg, true) + if err != nil { + log.Printf("Error sending msg to user: %v", err) + } + err = sendMsgWithMenu(user, msgReceivedMsg, true) + } + } else { + err = sendMsgWithMenu(sender, sendMsgErrMsg, true) + if err != nil { + log.Printf("Error sending msg to user: %v", err) + } + } + } +} diff --git a/src/telegramHandlers.go b/src/telegramHandlers.go index 3503a27..91a922a 100644 --- a/src/telegramHandlers.go +++ b/src/telegramHandlers.go @@ -12,24 +12,24 @@ func setBotHandlers() error { startCmd(m.Sender, true) }) bot.Handle("/stop", func(m *tb.Message) { - stopCmd(m.Sender) + stopCmd(m.Sender, true) }) bot.Handle("/menu", func(m *tb.Message) { sendMsgWithMenu(m.Sender, menuMsg, true) }) bot.Handle("/userInfo", func(m *tb.Message) { msg, _ := getUserDescription(m.Sender) - sendMsgWithSpecificMenu(m.Sender, msg, myInfoMenu, true) + sendMsgWithSpecificMenu(m.Sender, msg, backMenu, true) }) bot.Handle("/botInfo", func(m *tb.Message) { sendMsgWithSpecificMenu(m.Sender, contactMsg, botInfoMenu, true) }) bot.Handle("/help", func(m *tb.Message) { - sendMsgWithSpecificMenu(m.Sender, contactMsg, botInfoMenu, true) + helpCmd(m.Sender, true) }) bot.Handle("/config", func(m *tb.Message) { msg, _ := getUserDescription(m.Sender) - sendMsgWithSpecificMenu(m.Sender, msg, myInfoMenu, true) + sendMsgWithSpecificMenu(m.Sender, msg, backMenu, true) }) bot.Handle("/authUser", func(m *tb.Message) { authUserCmd(m.Sender, m.Payload, true) @@ -37,6 +37,9 @@ func setBotHandlers() error { bot.Handle("/deAuthUser", func(m *tb.Message) { deAuthUserCmd(m.Sender, m.Payload, true) }) + bot.Handle("/sendMsg", func(m *tb.Message) { + sendMsgCmd(m.Sender, m.Payload, true) + }) bot.Handle(tb.OnText, func(m *tb.Message) { sendMsgWithMenu(m.Sender, wrongCmdMsg, true) diff --git a/src/telegramMenus.go b/src/telegramMenus.go index b3a18fb..b238e83 100644 --- a/src/telegramMenus.go +++ b/src/telegramMenus.go @@ -14,7 +14,7 @@ var ( authInlineMenu [][]tb.InlineButton genericInlineMenu [][]tb.InlineButton startMenu [][]tb.InlineButton - myInfoMenu [][]tb.InlineButton + backMenu [][]tb.InlineButton botInfoMenu [][]tb.InlineButton authUserMenu [][]tb.InlineButton ) @@ -40,6 +40,10 @@ var ( Unique: "user_btn", Text: "\xF0\x9F\x91\xA4 My info", } + helpBtn = tb.InlineButton{ + Unique: "help_btn", + Text: "\xF0\x9F\x86\x98 Aiuto", + } authBtn = tb.InlineButton{ Unique: "auth_btn", Text: "\xE2\x9C\x85 Autorizza utente", @@ -107,8 +111,8 @@ func setBotMenus() error { superAdminInlineMenu = append(superAdminInlineMenu, []tb.InlineButton{adminBtn, deAdminBtn}) startMenu = append(startMenu, []tb.InlineButton{startBtn}) - myInfoMenu = append(myInfoMenu, []tb.InlineButton{backBtn}) - botInfoMenu = append(botInfoMenu, []tb.InlineButton{stopBtn}, []tb.InlineButton{backBtn}) + backMenu = append(backMenu, []tb.InlineButton{backBtn}) + botInfoMenu = append(botInfoMenu, []tb.InlineButton{helpBtn, stopBtn}, []tb.InlineButton{backBtn}) authUserMenu = append(authUserMenu, []tb.InlineButton{authUGSopranoBtn, authUGContraltoBtn}, []tb.InlineButton{authUGTenoreBtn, authUGBassoBtn}, @@ -182,18 +186,22 @@ func setBotCallbacks() error { bot.Handle(&stopBtn, func(c *tb.Callback) { bot.Respond(c, &tb.CallbackResponse{}) - stopCmd(c.Sender) + stopCmd(c.Sender, false) }) bot.Handle(&userBtn, func(c *tb.Callback) { bot.Respond(c, &tb.CallbackResponse{}) msg, _ := getUserDescription(c.Sender) - sendMsgWithSpecificMenu(c.Sender, msg, myInfoMenu, false) + sendMsgWithSpecificMenu(c.Sender, msg, backMenu, false) }) bot.Handle(&infoBtn, func(c *tb.Callback) { bot.Respond(c, &tb.CallbackResponse{}) sendMsgWithSpecificMenu(c.Sender, contactMsg, botInfoMenu, false) }) + bot.Handle(&helpBtn, func(c *tb.Callback) { + bot.Respond(c, &tb.CallbackResponse{}) + helpCmd(c.Sender, false) + }) bot.Handle(&backBtn, func(c *tb.Callback) { bot.Respond(c, &tb.CallbackResponse{}) sendMsgWithMenu(c.Sender, menuMsg, false) @@ -211,7 +219,7 @@ func setBotCallbacks() error { }) bot.Handle(&sendMsgBtn, func(c *tb.Callback) { bot.Respond(c, &tb.CallbackResponse{}) - + sendMsgWithMenu(c.Sender, sendMsgHowToMsg, false) }) bot.Handle(&authUGSopranoBtn, func(c *tb.Callback) { groupCallback(c, ugSoprano) diff --git a/todo b/todo index d2fb3e9..85a5d92 100644 --- a/todo +++ b/todo @@ -2,8 +2,22 @@ redis hash per bot (si puó usare la struct tb.Bot come interface?): rinnovare info ad ogni start del bot visualizzare info bot. Tipo? -SuperAdmin? Menú giá presente Controllare stoppedUser anche se comando inviato tramite menu. Dove farlo? -Help command con descrizione divisa per gruppo \ No newline at end of file + +auth e deAuth solo di utenti dei propri gruppi + +SuperAdmin +- Menú giá presente +- Invio a tutti +- auth e deAuth di tutti + +Invio ultima mail a gruppi corretti +- Trigger manuale o automatico per check mail? + +Eventi + +/sendMsg solo gruppi di appartenenza +- messaggio di conferma con menu. Alert di invio. +/searchUser solo gruppi di appartenenza \ No newline at end of file