From d4221c973fba807cc443f40ee0d7eda95a36dc2e Mon Sep 17 00:00:00 2001 From: Luca Bernstein Date: Sun, 13 Nov 2022 09:00:24 +0100 Subject: [PATCH] Encapsulate error handling on bot send Closes #195 --- bot/config.go | 126 +++++++---------------------- bot/controller.go | 175 +++++++++-------------------------------- bot/mocks_test.go | 75 +++++++++--------- bot/suggestions.go | 45 +++-------- bot/templates.go | 65 +++------------ bot/wrapper.go | 9 +++ helpers/logger.go | 5 +- helpers/logger_test.go | 2 + 8 files changed, 138 insertions(+), 364 deletions(-) diff --git a/bot/config.go b/bot/config.go index dc83ecd..c7b0726 100644 --- a/bot/config.go +++ b/bot/config.go @@ -75,20 +75,14 @@ Reset your data stored by the bot. WARNING: This action is permanent! bc.Logf(ERROR, m, "Parsing configHelp template failed: %s", err.Error()) } - _, err = bc.Bot.Send(Recipient(m), errorMsg+filledTemplate) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), errorMsg+filledTemplate) } func (bc *BotController) configHandleCurrency(m *tb.Message, params ...string) { currency := bc.Repo.UserGetCurrency(m) if len(params) == 0 { // 0 params: GET currency // Return currently set currency - _, err := bc.Bot.Send(Recipient(m), fmt.Sprintf("Your current currency is set to '%s'. To change it add the new currency to use to the command like this: '/%s currency EUR'.", currency, CMD_CONFIG)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Your current currency is set to '%s'. To change it add the new currency to use to the command like this: '/%s currency EUR'.", currency, CMD_CONFIG)) return } else if len(params) > 1 { // 2 or more params: too many bc.configHelp(m, fmt.Errorf("invalid amount of parameters specified")) @@ -98,16 +92,10 @@ func (bc *BotController) configHandleCurrency(m *tb.Message, params ...string) { newCurrency := params[0] err := bc.Repo.UserSetCurrency(m, newCurrency) if err != nil { - _, err = bc.Bot.Send(Recipient(m), "An error ocurred saving your currency preference: "+err.Error()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "An error ocurred saving your currency preference: "+err.Error()) return } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("Changed default currency for all future transactions from '%s' to '%s'.", currency, newCurrency)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Changed default currency for all future transactions from '%s' to '%s'.", currency, newCurrency)) } func (bc *BotController) configHandleTag(m *tb.Message, params ...string) { @@ -115,15 +103,9 @@ func (bc *BotController) configHandleTag(m *tb.Message, params ...string) { // GET tag tag := bc.Repo.UserGetTag(m) if tag != "" { - _, err := bc.Bot.Send(Recipient(m), fmt.Sprintf("All new transactions automatically get the tag #%s added (vacation mode enabled)", tag)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("All new transactions automatically get the tag #%s added (vacation mode enabled)", tag)) } else { - _, err := bc.Bot.Send(Recipient(m), "No tags are currently added to new transactions (vacation mode disabled).") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "No tags are currently added to new transactions (vacation mode disabled).") } return } else if len(params) > 1 { // Only 0 or 1 allowed @@ -133,26 +115,17 @@ func (bc *BotController) configHandleTag(m *tb.Message, params ...string) { if params[0] == "off" { // DELETE tag bc.Repo.UserSetTag(m, "") - _, err := bc.Bot.Send(Recipient(m), "Disabled automatically set tags on new transactions") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Disabled automatically set tags on new transactions") return } // SET tag tag := strings.TrimPrefix(params[0], "#") err := bc.Repo.UserSetTag(m, tag) if err != nil { - _, err = bc.Bot.Send(Recipient(m), "An error ocurred saving the tag: "+err.Error()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "An error ocurred saving the tag: "+err.Error()) return } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("From now on all new transactions automatically get the tag #%s added (vacation mode enabled)", tag)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("From now on all new transactions automatically get the tag #%s added (vacation mode enabled)", tag)) } func (bc *BotController) configHandleNotification(m *tb.Message, params ...string) { @@ -171,20 +144,14 @@ func (bc *BotController) configHandleNotification(m *tb.Message, params ...strin return } if daysDelay < 0 { - _, err = bc.Bot.Send(Recipient(m), "Notifications are disabled for open transactions.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Notifications are disabled for open transactions.") return } plural_s := "s" if daysDelay == 1 { plural_s = "" } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("The bot will notify you daily at hour %d (%s) if transactions are open for more than %d day%s", hour, tz, daysDelay, plural_s)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("The bot will notify you daily at hour %d (%s) if transactions are open for more than %d day%s", hour, tz, daysDelay, plural_s)) return } else if len(params) == 1 { // DELETE schedule @@ -194,10 +161,7 @@ func (bc *BotController) configHandleNotification(m *tb.Message, params ...strin bc.configHelp(m, fmt.Errorf("error setting notification schedule: %s", err.Error())) return } - _, err = bc.Bot.Send(Recipient(m), "Successfully disabled notifications for open transactions.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Successfully disabled notifications for open transactions.") return } bc.configHelp(m, fmt.Errorf("invalid parameters")) @@ -241,15 +205,12 @@ func (bc *BotController) configHandleAbout(m *tb.Message, params ...string) { if version == "" { version = "not specified" } - _, err := bc.Bot.Send(Recipient(m), escapeCharacters(fmt.Sprintf(`Version information about [LucaBernstein/beancount-bot-tg](https://github.com/LucaBernstein/beancount-bot-tg) + bc.Bot.SendSilent(bc, Recipient(m), escapeCharacters(fmt.Sprintf(`Version information about [LucaBernstein/beancount-bot-tg](https://github.com/LucaBernstein/beancount-bot-tg) Version: [%s](%s)`, version, versionLink, ), ".", "-"), tb.ModeMarkdownV2) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } } func escapeCharacters(s string, c ...string) string { @@ -262,10 +223,7 @@ func escapeCharacters(s string, c ...string) string { func (bc *BotController) configHandleTimezoneOffset(m *tb.Message, params ...string) { tz_offset := bc.Repo.UserGetTzOffset(m) if len(params) == 0 { // 0 params: GET - _, err := bc.Bot.Send(Recipient(m), fmt.Sprintf("Your current timezone offset is set to 'UTC%s'.", prettyTzOffset(tz_offset))) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Your current timezone offset is set to 'UTC%s'.", prettyTzOffset(tz_offset))) return } else if len(params) > 1 { // 2 or more params: too many bc.configHelp(m, fmt.Errorf("invalid amount of parameters specified")) @@ -275,24 +233,15 @@ func (bc *BotController) configHandleTimezoneOffset(m *tb.Message, params ...str newTzOffset := params[0] newTzParsed, err := strconv.Atoi(newTzOffset) if err != nil { - _, err = bc.Bot.Send(Recipient(m), "An error ocurred saving your timezone offset preference: "+err.Error()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "An error ocurred saving your timezone offset preference: "+err.Error()) return } err = bc.Repo.UserSetTzOffset(m, newTzParsed) if err != nil { - _, err = bc.Bot.Send(Recipient(m), "An error ocurred saving your timezone offset preference: "+err.Error()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "An error ocurred saving your timezone offset preference: "+err.Error()) return } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("Changed timezone offset for default dates for all future transactions from 'UTC%s' to 'UTC%s'.", prettyTzOffset(tz_offset), prettyTzOffset(newTzParsed))) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Changed timezone offset for default dates for all future transactions from 'UTC%s' to 'UTC%s'.", prettyTzOffset(tz_offset), prettyTzOffset(newTzParsed))) } func (bc *BotController) configHandleOmitLeadingSlash(m *tb.Message, params ...string) { @@ -300,20 +249,14 @@ func (bc *BotController) configHandleOmitLeadingSlash(m *tb.Message, params ...s if len(params) == 0 { // 0 params: GET exists, value, err := bc.Repo.GetUserSetting(helpers.USERSET_OMITCMDSLASH, m.Chat.ID) if err != nil { - bc.Bot.Send(Recipient(m), "There has been an error internally while retrieving the value currently set for the queried user setting. Please try again later.") + bc.Bot.SendSilent(bc, Recipient(m), "There has been an error internally while retrieving the value currently set for the queried user setting. Please try again later.") return } if !exists || strings.ToUpper(value) != "TRUE" { - _, err = bc.Bot.Send(Recipient(m), "Omitting leading slash support is currently turned off. Please check the help on how to turn it on.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Omitting leading slash support is currently turned off. Please check the help on how to turn it on.") return } else { - _, err = bc.Bot.Send(Recipient(m), "Omitting leading slash support is currently turned on.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Omitting leading slash support is currently turned on.") return } } else if len(params) > 1 { // 2 or more params: too many @@ -326,24 +269,18 @@ func (bc *BotController) configHandleOmitLeadingSlash(m *tb.Message, params ...s case "ON": err = bc.Repo.SetUserSetting(helpers.USERSET_OMITCMDSLASH, "true", m.Chat.ID) if err != nil { - bc.Bot.Send(Recipient(m), "There has been an error internally while setting your value. Please try again later.") + bc.Bot.SendSilent(bc, Recipient(m), "There has been an error internally while setting your value. Please try again later.") return } - _, err = bc.Bot.Send(Recipient(m), "Omitting leading slashes has successfully been turned on.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Omitting leading slashes has successfully been turned on.") return case "OFF": err = bc.Repo.SetUserSetting(helpers.USERSET_OMITCMDSLASH, "false", m.Chat.ID) if err != nil { - bc.Bot.Send(Recipient(m), "There has been an error internally while setting your value. Please try again later.") + bc.Bot.SendSilent(bc, Recipient(m), "There has been an error internally while setting your value. Please try again later.") return } - _, err = bc.Bot.Send(Recipient(m), "Omitting leading slashes has successfully been turned off.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Omitting leading slashes has successfully been turned off.") return default: bc.configHelp(m, fmt.Errorf("invalid setting value: '%s'. Not in ['ON', 'OFF']", newUserSettingValue)) @@ -365,21 +302,12 @@ func (bc *BotController) configHandleAccountDelete(m *tb.Message, params ...stri bc.deleteUserData(m) - _, err := bc.Bot.Send(Recipient(m), "I'm sad to see you go. Hopefully one day, you will come back.\n\nI have deleted all of your data stored in the bot. You can simply start over by sending me a message again. Goodbye.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } - _, err = bc.Bot.Send(Recipient(m), "============") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "I'm sad to see you go. Hopefully one day, you will come back.\n\nI have deleted all of your data stored in the bot. You can simply start over by sending me a message again. Goodbye.") + bc.Bot.SendSilent(bc, Recipient(m), "============") return } bc.Logf(INFO, m, "Reset command failed 'yes' verification. Aborting.") - _, err := bc.Bot.Send(Recipient(m), "Reset has been aborted.\n\nYou tried to permanently delete your account. Please make sure to confirm this action by adding 'yes' to the end of your command. Please check /config for usage.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Reset has been aborted.\n\nYou tried to permanently delete your account. Please make sure to confirm this action by adding 'yes' to the end of your command. Please check /config for usage.") } func (bc *BotController) deleteUserData(m *tb.Message) { diff --git a/bot/controller.go b/bot/controller.go index dbb59b5..8f29fa2 100644 --- a/bot/controller.go +++ b/bot/controller.go @@ -106,14 +106,11 @@ func (bc *BotController) commandMappings() []*CMD { func (bc *BotController) commandStart(c tb.Context) error { bc.Logf(TRACE, c.Message(), "Start command") - _, err := bc.Bot.Send(Recipient(c.Message()), "Welcome to this beancount bot!\n"+ + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Welcome to this beancount bot!\n"+ "You can find more information in the repository under "+ "https://github.com/LucaBernstein/beancount-bot-tg\n\n"+ "Please check the commands I will send to you next that are available to you. "+ "You can always reach the command help by typing /"+CMD_HELP, clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } bc.commandHelp(c) return nil } @@ -147,10 +144,7 @@ func (bc *BotController) commandHelp(c tb.Context) error { helpMsg += fmt.Sprintf("\n/%s - %s", cmd.CommandAlias[0], cmd.Help) } } - _, err := bc.Bot.Send(Recipient(c.Message()), helpMsg, clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), helpMsg, clearKeyboard()) return nil } @@ -169,10 +163,7 @@ func (bc *BotController) commandCancel(c tb.Context) error { msg = "Your currently running transaction has been cancelled." } } - _, err := bc.Bot.Send(Recipient(c.Message()), fmt.Sprintf("%s\nType /%s to get available commands.", msg, CMD_HELP), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), fmt.Sprintf("%s\nType /%s to get available commands.", msg, CMD_HELP), clearKeyboard()) return nil } @@ -193,29 +184,20 @@ func Recipient(m *tb.Message) tb.Recipient { func (bc *BotController) commandCreateSimpleTx(c tb.Context) error { state := bc.State.GetType(c.Message()) if state != ST_NONE { - _, err := bc.Bot.Send(Recipient(c.Message()), MSG_UNFINISHED_STATE) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), MSG_UNFINISHED_STATE) return nil } bc.Logf(TRACE, c.Message(), "Creating simple transaction") - _, err := bc.Bot.Send(Recipient(c.Message()), "In the following steps we will create a simple transaction. "+ + bc.Bot.SendSilent(bc, Recipient(c.Message()), "In the following steps we will create a simple transaction. "+ "I will guide you through.\n\n", clearKeyboard(), ) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } tx, err := bc.State.SimpleTx(c.Message(), bc.Repo.UserGetCurrency(c.Message())) // create new tx if err != nil { - _, err := bc.Bot.Send(Recipient(c.Message()), "Something went wrong creating your transactions ("+err.Error()+"). Please check /help for usage."+ + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong creating your transactions ("+err.Error()+"). Please check /help for usage."+ "\n\nYou can create a simple transaction using this command: /simple [date]\ne.g. /simple 2021-01-24\n"+ "The date parameter is non-mandatory, if not specified, today's date will be taken."+ "Alternatively it is also possible to send an amount directly to start a new simple transaction.", clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } return nil } if tx.IsDone() { @@ -230,10 +212,7 @@ func (bc *BotController) commandCreateSimpleTx(c tb.Context) error { func (bc *BotController) commandAddComment(c tb.Context) error { if bc.State.GetType(c.Message()) != ST_NONE { bc.Logf(INFO, c.Message(), "commandAddComment while in another transaction") - _, err := bc.Bot.Send(Recipient(c.Message()), MSG_UNFINISHED_STATE) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), MSG_UNFINISHED_STATE) return nil } base := CMD_COMMENT[0] @@ -252,16 +231,10 @@ func (bc *BotController) commandAddComment(c tb.Context) error { err := bc.Repo.RecordTransaction(c.Message().Chat.ID, comment+"\n") if err != nil { bc.Logf(ERROR, c.Message(), "Something went wrong while recording the comment: "+err.Error()) - _, err := bc.Bot.Send(Recipient(c.Message()), "Something went wrong while recording your comment: "+err.Error(), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong while recording your comment: "+err.Error(), clearKeyboard()) return nil } - _, err = bc.Bot.Send(Recipient(c.Message()), "Successfully added the comment to your transaction /list", clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Successfully added the comment to your transaction /list", clearKeyboard()) return nil } @@ -291,10 +264,7 @@ func (bc *BotController) commandList(c tb.Context) error { var err error elementNumber, err = strconv.Atoi(option) if err != nil { - _, err := bc.Bot.Send(Recipient(c.Message()), fmt.Sprintf("The option '%s' could not be recognized. Please try again with '/list', with options added to the end separated by space.", option), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), fmt.Sprintf("The option '%s' could not be recognized. Please try again with '/list', with options added to the end separated by space.", option), clearKeyboard()) return nil } continue @@ -302,18 +272,12 @@ func (bc *BotController) commandList(c tb.Context) error { } } if isDeleteCommand && (isNumbered || isDated || elementNumber <= 0) { - _, err := bc.Bot.Send(Recipient(c.Message()), "For removing a single element from the list, determine it's number by sending the command '/list numbered' and then removing an entry by sending '/list rm '.", clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "For removing a single element from the list, determine it's number by sending the command '/list numbered' and then removing an entry by sending '/list rm '.", clearKeyboard()) return nil } tx, err := bc.Repo.GetTransactions(c.Message(), isArchived) if err != nil { - _, err := bc.Bot.Send(Recipient(c.Message()), "Something went wrong retrieving your transactions: "+err.Error(), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong retrieving your transactions: "+err.Error(), clearKeyboard()) return nil } if tx == nil { @@ -329,16 +293,10 @@ func (bc *BotController) commandList(c tb.Context) error { err = fmt.Errorf("the number you specified was too high. Please use a correct number as seen from '/list [archived] numbered'") } if err != nil { - _, errSending := bc.Bot.Send(Recipient(c.Message()), "Something went wrong while trying to delete a single transaction: "+err.Error(), clearKeyboard()) - if errSending != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", errSending.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong while trying to delete a single transaction: "+err.Error(), clearKeyboard()) return nil } - _, errSending := bc.Bot.Send(Recipient(c.Message()), "Successfully deleted the list entry specified.", clearKeyboard()) - if errSending != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", errSending.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Successfully deleted the list entry specified.", clearKeyboard()) return nil } SEP := "\n" @@ -374,18 +332,12 @@ func (bc *BotController) commandList(c tb.Context) error { if !isArchived { archivedSuggestion = " archived" } - _, err := bc.Bot.Send(Recipient(c.Message()), fmt.Sprintf("Your transaction list is empty. Create some first. Check /%s for commands to create a transaction."+ + bc.Bot.SendSilent(bc, Recipient(c.Message()), fmt.Sprintf("Your transaction list is empty. Create some first. Check /%s for commands to create a transaction."+ "\nYou might also be looking for%s transactions using '/list%s'.", CMD_HELP, archivedSuggestion, archivedSuggestion), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } return nil } for _, message := range messageSplits { - _, err = bc.Bot.Send(Recipient(c.Message()), message, clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), message, clearKeyboard()) } return nil } @@ -414,40 +366,25 @@ func (bc *BotController) commandArchiveTransactions(c tb.Context) error { bc.Logf(TRACE, c.Message(), "Archiving transactions") err := bc.Repo.ArchiveTransactions(c.Message()) if err != nil { - _, err := bc.Bot.Send(Recipient(c.Message()), "Something went wrong archiving your transactions: "+err.Error()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong archiving your transactions: "+err.Error()) return nil } - _, err = bc.Bot.Send(Recipient(c.Message()), fmt.Sprintf("Archived all transactions. Your /%s is empty again.", CMD_LIST), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), fmt.Sprintf("Archived all transactions. Your /%s is empty again.", CMD_LIST), clearKeyboard()) return nil } func (bc *BotController) commandDeleteTransactions(c tb.Context) error { if !(strings.TrimSpace(strings.ToLower(c.Message().Text)) == strings.ToLower("/"+CMD_DELETE_ALL+" YES")) { - _, err := bc.Bot.Send(Recipient(c.Message()), fmt.Sprintf("Please type '/%s yes' to confirm the deletion of your transactions", CMD_DELETE_ALL)) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), fmt.Sprintf("Please type '/%s yes' to confirm the deletion of your transactions", CMD_DELETE_ALL)) return nil } bc.Logf(TRACE, c.Message(), "Deleting transactions") err := bc.Repo.DeleteTransactions(c.Message()) if err != nil { - _, err := bc.Bot.Send(Recipient(c.Message()), "Something went wrong deleting your transactions: "+err.Error()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong deleting your transactions: "+err.Error()) return nil } - _, err = bc.Bot.Send(Recipient(c.Message()), fmt.Sprintf("Permanently deleted all your transactions. Your /%s is empty again.", CMD_LIST), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), fmt.Sprintf("Permanently deleted all your transactions. Your /%s is empty again.", CMD_LIST), clearKeyboard()) return nil } @@ -503,13 +440,10 @@ func (bc *BotController) cronNotifications() { if openCount == 1 { s = "" } - _, err := bc.Bot.Send(ReceiverImpl{chatId: tgChatId}, fmt.Sprintf( + bc.Bot.SendSilent(bc, ReceiverImpl{chatId: tgChatId}, fmt.Sprintf( // TODO: Replace hard-coded command directives: " This is your reminder to inform you that you currently have %d open transaction%s (%d triggering this notification). Check '/list' to see your open transactions. If you don't need them anymore you can /archiveAll or /delete them."+ "\n\nYou are getting this message because you enabled reminder notifications for open transactions in /config.", openCount, s, overdue)) - if err != nil { - bc.Logf(ERROR, nil, "Sending bot message failed: %s", err.Error()) - } } bc.Logf(TRACE, nil, bc.cronInfo()) @@ -530,10 +464,7 @@ func (bc *BotController) commandAdminCronInfo(c tb.Context) error { bc.handleTextState(c) return nil } - _, err := bc.Bot.Send(Recipient(c.Message()), bc.cronInfo()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), bc.cronInfo()) return nil } @@ -549,10 +480,7 @@ func (bc *BotController) commandAdminNofify(c tb.Context) error { notificationMessage = text[1] } if len(text) == 0 || len(notificationMessage) == 0 { - _, err := bc.Bot.Send(Recipient(c.Message()), "Something went wrong splitting your command parameters. Did you specify a text in double quotes (\")?") - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong splitting your command parameters. Did you specify a text in double quotes (\")?") return nil } // text[0] = /command [chatId] @@ -560,10 +488,7 @@ func (bc *BotController) commandAdminNofify(c tb.Context) error { if len(command) == 0 || len(command) >= 3 { // invalid argument count - _, err := bc.Bot.Send(Recipient(c.Message()), "Please check the command syntax") - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Please check the command syntax") return nil } @@ -574,18 +499,12 @@ func (bc *BotController) commandAdminNofify(c tb.Context) error { receivers := bc.Repo.IndividualsWithNotifications(target) if len(receivers) == 0 { - _, err := bc.Bot.Send(Recipient(c.Message()), "No receivers found to send notification to (you being excluded).") - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "No receivers found to send notification to (you being excluded).") return nil } for _, recipient := range receivers { - _, err := bc.Bot.Send(ReceiverImpl{chatId: recipient}, "*** Service notification ***\n\n"+notificationMessage) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, ReceiverImpl{chatId: recipient}, "*** Service notification ***\n\n"+notificationMessage) bc.Logf(TRACE, c.Message(), "Sent notification to %s", recipient) // TODO: Add message like 'If you don't want to receive further service notifications, you can turn them off in the /settings with '/settings notif off'.' // GitHub-issue: #28 @@ -626,16 +545,10 @@ func (bc *BotController) handleTextState(c tb.Context) error { bc.Logf(DEBUG, c.Message(), "Creating new simple transaction as amount has been entered though not in tx") _, err = bc.State.SimpleTx(c.Message(), bc.Repo.UserGetCurrency(c.Message())) // create new tx if err != nil { - _, err := bc.Bot.Send(Recipient(c.Message()), "Something went wrong creating a new transaction: "+err.Error(), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Something went wrong creating a new transaction: "+err.Error(), clearKeyboard()) return nil } - _, err := bc.Bot.Send(Recipient(c.Message()), "Automatically created a new transaction for you. If you think this was a mistake you can /cancel it.", clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Automatically created a new transaction for you. If you think this was a mistake you can /cancel it.", clearKeyboard()) bc.handleTextState(c) return nil } else if handlerFunc := bc.matchesCommandWithoutLeadingSlash(c); handlerFunc != nil { @@ -651,23 +564,17 @@ func (bc *BotController) handleTextState(c tb.Context) error { } bc.Logf(WARN, c.Message(), "Received text without having any prior state and not in group chat or message starts with '/'") - _, err := bc.Bot.Send(Recipient(c.Message()), fmt.Sprintf("Please check /%s on how to use this bot. E.g. you might need to start a transaction first before sending data.", CMD_HELP), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(c.Message()), fmt.Sprintf("Please check /%s on how to use this bot. E.g. you might need to start a transaction first before sending data.", CMD_HELP), clearKeyboard()) return nil } else if state == ST_TX { tx := bc.State.GetTx(c.Message()) _, err := tx.Input(c.Message()) if err != nil { bc.Logf(WARN, c.Message(), "Invalid text state input: '%s'. Err: %s", c.Message().Text, err.Error()) - _, err := bc.Bot.Send(Recipient(c.Message()), "Your last input seems to have not worked.\n"+ + bc.Bot.SendSilent(bc, Recipient(c.Message()), "Your last input seems to have not worked.\n"+ fmt.Sprintf("(Error: %s)\n", err.Error())+ "Please try again.", ) - if err != nil { - bc.Logf(ERROR, c.Message(), "Sending bot message failed: %s", err.Error()) - } } bc.Logf(TRACE, c.Message(), "New data state is %v. (Last input was '%s')", tx.Debug(), c.Message().Text) if tx.IsDone() { @@ -691,10 +598,7 @@ func (bc *BotController) handleTextState(c tb.Context) error { func (bc *BotController) sendNextTxHint(hint *Hint, m *tb.Message) { replyKeyboard := ReplyKeyboard(hint.KeyboardOptions) bc.Logf(TRACE, m, "Sending hints for next step: %v", hint.KeyboardOptions) - _, err := bc.Bot.Send(Recipient(m), escapeCharacters(hint.Prompt, "(", ")", ".", "!"), replyKeyboard, tb.ModeMarkdownV2) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), escapeCharacters(hint.Prompt, "(", ")", ".", "!"), replyKeyboard, tb.ModeMarkdownV2) } func clearKeyboard() *tb.ReplyMarkup { @@ -708,20 +612,14 @@ func (bc *BotController) finishTransaction(m *tb.Message, tx Tx) { transaction, err := tx.FillTemplate(currency, tag, tzOffset) if err != nil { bc.Logf(ERROR, m, "Something went wrong while templating the transaction: "+err.Error()) - _, err := bc.Bot.Send(Recipient(m), "Something went wrong while templating the transaction: "+err.Error(), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Something went wrong while templating the transaction: "+err.Error(), clearKeyboard()) return } err = bc.Repo.RecordTransaction(m.Chat.ID, transaction) if err != nil { bc.Logf(ERROR, m, "Something went wrong while recording the transaction: "+err.Error()) - _, err := bc.Bot.Send(Recipient(m), "Something went wrong while recording your transaction: "+err.Error(), clearKeyboard()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Something went wrong while recording your transaction: "+err.Error(), clearKeyboard()) return } @@ -732,16 +630,13 @@ func (bc *BotController) finishTransaction(m *tb.Message, tx Tx) { // Don't return, instead continue flow (if recording was successful) } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("Successfully recorded your transaction.\n"+ + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Successfully recorded your transaction.\n"+ "You can get a list of all your transactions using /%s. "+ "With /%s you can delete all of them (e.g. once you copied them into your bookkeeping)."+ "\n\nYou can start a new transaction with /%s or type /%s to see all commands available.", CMD_LIST, CMD_ARCHIVE_ALL, CMD_SIMPLE, CMD_HELP), clearKeyboard(), ) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } bc.State.Clear(m) } diff --git a/bot/mocks_test.go b/bot/mocks_test.go index d0196ed..ec00247 100644 --- a/bot/mocks_test.go +++ b/bot/mocks_test.go @@ -24,6 +24,9 @@ func (b *MockBot) Respond(c *tb.Callback, resp ...*tb.CallbackResponse) error { func (b *MockBot) Me() *tb.User { return &tb.User{Username: "Test bot"} } +func (b *MockBot) SendSilent(bc *BotController, to tb.Recipient, what interface{}, options ...interface{}) (*tb.Message, error) { + return b.Send(to, what, options...) +} func (b *MockBot) reset() { b.AllLastSentWhat = nil } @@ -35,39 +38,39 @@ type MockContext struct { func (c *MockContext) Message() *tb.Message { return c.M } -func (c *MockContext) Bot() *tb.Bot {return nil} -func (c *MockContext) Update() tb.Update {return tb.Update{}} -func (c *MockContext) Callback() *tb.Callback {return nil} -func (c *MockContext) Query() *tb.Query {return nil} -func (c *MockContext) InlineResult() *tb.InlineResult {return nil} -func (c *MockContext) ShippingQuery() *tb.ShippingQuery {return nil} -func (c *MockContext) PreCheckoutQuery() *tb.PreCheckoutQuery {return nil} -func (c *MockContext) Poll() *tb.Poll {return nil} -func (c *MockContext) PollAnswer() *tb.PollAnswer {return nil} -func (c *MockContext) ChatMember() *tb.ChatMemberUpdate {return nil} -func (c *MockContext) ChatJoinRequest() *tb.ChatJoinRequest {return nil} -func (c *MockContext) Migration() (int64, int64) {return 0, 0} -func (c *MockContext) Sender() *tb.User {return nil} -func (c *MockContext) Chat() *tb.Chat {return nil} -func (c *MockContext) Recipient() tb.Recipient {return nil} -func (c *MockContext) Text() string {return ""} -func (c *MockContext) Data() string {return ""} -func (c *MockContext) Args() []string {return nil} -func (c *MockContext) Send(what interface{}, opts ...interface{}) error {return nil} -func (c *MockContext) SendAlbum(a tb.Album, opts ...interface{}) error {return nil} -func (c *MockContext) Reply(what interface{}, opts ...interface{}) error {return nil} -func (c *MockContext) Forward(msg tb.Editable, opts ...interface{}) error {return nil} -func (c *MockContext) ForwardTo(to tb.Recipient, opts ...interface{}) error {return nil} -func (c *MockContext) Edit(what interface{}, opts ...interface{}) error {return nil} -func (c *MockContext) EditCaption(caption string, opts ...interface{}) error {return nil} -func (c *MockContext) EditOrSend(what interface{}, opts ...interface{}) error {return nil} -func (c *MockContext) EditOrReply(what interface{}, opts ...interface{}) error {return nil} -func (c *MockContext) Delete() error {return nil} -func (c *MockContext) DeleteAfter(d time.Duration) *time.Timer {return nil} -func (c *MockContext) Notify(action tb.ChatAction) error {return nil} -func (c *MockContext) Ship(what ...interface{}) error {return nil} -func (c *MockContext) Accept(errorMessage ...string) error {return nil} -func (c *MockContext) Answer(resp *tb.QueryResponse) error {return nil} -func (c *MockContext) Respond(resp ...*tb.CallbackResponse) error {return nil} -func (c *MockContext) Get(key string) interface{} {return nil} -func (c *MockContext) Set(key string, val interface{}) {} +func (c *MockContext) Bot() *tb.Bot { return nil } +func (c *MockContext) Update() tb.Update { return tb.Update{} } +func (c *MockContext) Callback() *tb.Callback { return nil } +func (c *MockContext) Query() *tb.Query { return nil } +func (c *MockContext) InlineResult() *tb.InlineResult { return nil } +func (c *MockContext) ShippingQuery() *tb.ShippingQuery { return nil } +func (c *MockContext) PreCheckoutQuery() *tb.PreCheckoutQuery { return nil } +func (c *MockContext) Poll() *tb.Poll { return nil } +func (c *MockContext) PollAnswer() *tb.PollAnswer { return nil } +func (c *MockContext) ChatMember() *tb.ChatMemberUpdate { return nil } +func (c *MockContext) ChatJoinRequest() *tb.ChatJoinRequest { return nil } +func (c *MockContext) Migration() (int64, int64) { return 0, 0 } +func (c *MockContext) Sender() *tb.User { return nil } +func (c *MockContext) Chat() *tb.Chat { return nil } +func (c *MockContext) Recipient() tb.Recipient { return nil } +func (c *MockContext) Text() string { return "" } +func (c *MockContext) Data() string { return "" } +func (c *MockContext) Args() []string { return nil } +func (c *MockContext) Send(what interface{}, opts ...interface{}) error { return nil } +func (c *MockContext) SendAlbum(a tb.Album, opts ...interface{}) error { return nil } +func (c *MockContext) Reply(what interface{}, opts ...interface{}) error { return nil } +func (c *MockContext) Forward(msg tb.Editable, opts ...interface{}) error { return nil } +func (c *MockContext) ForwardTo(to tb.Recipient, opts ...interface{}) error { return nil } +func (c *MockContext) Edit(what interface{}, opts ...interface{}) error { return nil } +func (c *MockContext) EditCaption(caption string, opts ...interface{}) error { return nil } +func (c *MockContext) EditOrSend(what interface{}, opts ...interface{}) error { return nil } +func (c *MockContext) EditOrReply(what interface{}, opts ...interface{}) error { return nil } +func (c *MockContext) Delete() error { return nil } +func (c *MockContext) DeleteAfter(d time.Duration) *time.Timer { return nil } +func (c *MockContext) Notify(action tb.ChatAction) error { return nil } +func (c *MockContext) Ship(what ...interface{}) error { return nil } +func (c *MockContext) Accept(errorMessage ...string) error { return nil } +func (c *MockContext) Answer(resp *tb.QueryResponse) error { return nil } +func (c *MockContext) Respond(resp ...*tb.CallbackResponse) error { return nil } +func (c *MockContext) Get(key string) interface{} { return nil } +func (c *MockContext) Set(key string, val interface{}) {} diff --git a/bot/suggestions.go b/bot/suggestions.go index b4e1983..c816417 100644 --- a/bot/suggestions.go +++ b/bot/suggestions.go @@ -39,7 +39,7 @@ func (bc *BotController) suggestionsHelp(m *tb.Message, err error) { errorMsg += fmt.Sprintf("Error executing your command: %s\n\n", err.Error()) } - _, err = bc.Bot.Send(Recipient(m), errorMsg+fmt.Sprintf(`Usage help for /suggestions: + bc.Bot.SendSilent(bc, Recipient(m), errorMsg+fmt.Sprintf(`Usage help for /suggestions: /suggestions list /suggestions add [...] /suggestions rm [value] @@ -47,9 +47,6 @@ func (bc *BotController) suggestionsHelp(m *tb.Message, err error) { Parameter is one of: [%s] Adding multiple suggestions at once is supported either by space separation (with quotation marks) or using newlines.`, strings.Join(suggestionTypes, ", "))) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } } func (bc *BotController) suggestionsHandleList(m *tb.Message, params ...string) { @@ -69,24 +66,15 @@ func (bc *BotController) suggestionsHandleList(m *tb.Message, params ...string) } values, err := bc.Repo.GetCacheHints(m, p.T) if err != nil { - _, err := bc.Bot.Send(Recipient(m), fmt.Sprintf("Error encountered while retrieving suggestions list for type '%s': %s", p.T, err.Error())) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Error encountered while retrieving suggestions list for type '%s': %s", p.T, err.Error())) return } if len(values) == 0 { - _, err := bc.Bot.Send(Recipient(m), fmt.Sprintf("Your suggestions list for type '%s' is currently empty.", p.T)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Your suggestions list for type '%s' is currently empty.", p.T)) return } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("These suggestions are currently saved for type '%s':\n\n", p.T)+ + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("These suggestions are currently saved for type '%s':\n\n", p.T)+ strings.Join(values, "\n")) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } } func (bc *BotController) suggestionsHandleAdd(m *tb.Message, params ...string) { @@ -115,17 +103,11 @@ func (bc *BotController) suggestionsHandleAdd(m *tb.Message, params ...string) { for _, value := range singleValues { err := bc.Repo.PutCacheHints(m, map[string]string{suggestionType: value}) if err != nil { - _, err := bc.Bot.Send(Recipient(m), fmt.Sprintf("Error encountered while adding suggestion (%s): %s", value, err.Error())) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Error encountered while adding suggestion (%s): %s", value, err.Error())) return } } - _, err := bc.Bot.Send(Recipient(m), "Successfully added suggestion(s).") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Successfully added suggestion(s).") } func (bc *BotController) suggestionsHandleRemove(m *tb.Message, params ...string) { @@ -142,18 +124,12 @@ func (bc *BotController) suggestionsHandleRemove(m *tb.Message, params ...string bc.Logf(TRACE, m, "About to remove suggestion of type '%s' and value '%s'", p.T, p.Value) res, err := bc.Repo.DeleteCacheEntries(m, p.T, p.Value) if err != nil { - _, err := bc.Bot.Send(Recipient(m), "Error encountered while removing suggestion: "+err.Error()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Error encountered while removing suggestion: "+err.Error()) return } rowCount, err := res.RowsAffected() if err != nil { - _, err := bc.Bot.Send(Recipient(m), "Error encountered while extracting affected entries: "+err.Error()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Error encountered while extracting affected entries: "+err.Error()) return } if rowCount == 0 { @@ -161,8 +137,5 @@ func (bc *BotController) suggestionsHandleRemove(m *tb.Message, params ...string "If your value contains spaces, consider putting it in double quotes (\")")) return } - _, err = bc.Bot.Send(Recipient(m), "Successfully removed suggestion(s)") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Successfully removed suggestion(s)") } diff --git a/bot/templates.go b/bot/templates.go index c82cb84..9fc846c 100644 --- a/bot/templates.go +++ b/bot/templates.go @@ -33,7 +33,7 @@ func (bc *BotController) templatesHelp(m *tb.Message, err error) { if err != nil { errorMsg += fmt.Sprintf("Error executing your command: %s\n\n", err.Error()) } - _, err = bc.Bot.Send(Recipient(m), errorMsg+`Usage help for /template: + bc.Bot.SendSilent(bc, Recipient(m), errorMsg+`Usage help for /template: /template list [name] /template add /template rm @@ -44,9 +44,6 @@ func (bc *BotController) templatesHelp(m *tb.Message, err error) { /t [date] If omitted, date defaults to today.`) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } } func (bc *BotController) templatesHandleList(m *tb.Message, params ...string) { @@ -57,22 +54,13 @@ func (bc *BotController) templatesHandleList(m *tb.Message, params ...string) { templates, err := bc.Repo.GetTemplates(m, searchTemplate) if err != nil { bc.Logf(ERROR, m, "Error loading templates: %s", err.Error()) - _, err = bc.Bot.Send(Recipient(m), "There has been an error loading your templates.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "There has been an error loading your templates.") } if len(templates) == 0 { if searchTemplate == "" { - _, err = bc.Bot.Send(Recipient(m), "You have not created any template yet. Please see /template") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "You have not created any template yet. Please see /template") } else { - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("No template name matched your query '%s'", searchTemplate)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("No template name matched your query '%s'", searchTemplate)) } } else { templateList := []string{"These templates are currently available to you:"} @@ -81,10 +69,7 @@ func (bc *BotController) templatesHandleList(m *tb.Message, params ...string) { } messageSplits := bc.MergeMessagesHonorSendLimit(templateList, "\n\n") for _, message := range messageSplits { - _, err = bc.Bot.Send(Recipient(m), message, clearKeyboard()) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), message, clearKeyboard()) } } } @@ -92,10 +77,7 @@ func (bc *BotController) templatesHandleList(m *tb.Message, params ...string) { func (bc *BotController) templatesHandleAdd(m *tb.Message, params ...string) { state := bc.State.GetType(m) if state != ST_NONE { - _, err := bc.Bot.Send(Recipient(m), "There is another operation currently running for you. Please complete it or /cancel it before proceeding.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "There is another operation currently running for you. Please complete it or /cancel it before proceeding.") return } if len(params) != 1 { @@ -108,7 +90,7 @@ func (bc *BotController) templatesHandleAdd(m *tb.Message, params ...string) { return } bc.State.StartTpl(m, name) - _, err := bc.Bot.Send(Recipient(m), `Please provide a full transaction template. Variables are to be inserted as '${}'. The following variables can be used: + bc.Bot.SendSilent(bc, Recipient(m), `Please provide a full transaction template. Variables are to be inserted as '${}'. The following variables can be used: - ${amount}, ${-amount}, ${amount/i} (e.g. ${amount/2}) - ${date} - ${description} @@ -125,9 +107,6 @@ ${date} * "Store" "${description}" On templating out the amount will be auto-formatted. The date will either be filled with a specified value or fallback to the then current date. The amount will be inserted with the currency.`) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } } func (bc *BotController) templatesHandleRemove(m *tb.Message, params ...string) { @@ -138,39 +117,24 @@ func (bc *BotController) templatesHandleRemove(m *tb.Message, params ...string) name := params[0] wasRemoved, err := bc.Repo.RmTemplate(m.Chat.ID, string(name)) if err != nil { - _, err := bc.Bot.Send(Recipient(m), "Something went wrong while deleting your template.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Something went wrong while deleting your template.") return } if !wasRemoved { - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("There was no template called '%s' to remove. Please check '/t list'.", name)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("There was no template called '%s' to remove. Please check '/t list'.", name)) return } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("Successfully removed your template '%s'.", name)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Successfully removed your template '%s'.", name)) } func (bc *BotController) processNewTemplateResponse(m *tb.Message, name TemplateName) (clearState bool) { template := m.Text err := bc.Repo.AddTemplate(m.Chat.ID, string(name), template) if err != nil { - _, err := bc.Bot.Send(Recipient(m), "Something went wrong while saving your template. Please check whether the name already exists.") - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), "Something went wrong while saving your template. Please check whether the name already exists.") return false } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("Successfully created your template. You can use it from now on by typing '/t %s' (/t is short for /template).", name)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Successfully created your template. You can use it from now on by typing '/t %s' (/t is short for /template).", name)) return true } @@ -205,10 +169,7 @@ func (bc *BotController) templatesUse(m *tb.Message, params ...string) error { bc.Logf(ERROR, m, "Creating tx from template failed: %s", err.Error()) return fmt.Errorf("something went wrong creating a transaction from your template: %s", err.Error()) } - _, err = bc.Bot.Send(Recipient(m), fmt.Sprintf("Creating a new transaction from your template '%s'.", tpl.Name)) - if err != nil { - bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) - } + bc.Bot.SendSilent(bc, Recipient(m), fmt.Sprintf("Creating a new transaction from your template '%s'.", tpl.Name)) if tx.IsDone() { bc.finishTransaction(m, tx) return nil diff --git a/bot/wrapper.go b/bot/wrapper.go index 608a89c..cba95a2 100644 --- a/bot/wrapper.go +++ b/bot/wrapper.go @@ -12,6 +12,7 @@ type IBot interface { Respond(c *tb.Callback, resp ...*tb.CallbackResponse) error // custom by me: Me() *tb.User + SendSilent(bc *BotController, to tb.Recipient, what interface{}, options ...interface{}) (*tb.Message, error) } type Bot struct { @@ -37,3 +38,11 @@ func (b *Bot) Respond(c *tb.Callback, resp ...*tb.CallbackResponse) error { func (b *Bot) Me() *tb.User { return b.bot.Me } + +func (b *Bot) SendSilent(bc *BotController, to tb.Recipient, what interface{}, options ...interface{}) (*tb.Message, error) { + m, err := b.Send(to, what, options...) + if err != nil { + bc.Logf(ERROR, m, "Sending bot message failed: %s", err.Error()) + } + return m, err +} diff --git a/helpers/logger.go b/helpers/logger.go index 33b2d43..9192aca 100644 --- a/helpers/logger.go +++ b/helpers/logger.go @@ -47,7 +47,10 @@ func LogMessagePrefix(m *tb.Message) string { if m != nil { // Account for historical test cases without sender if m.Sender == nil { - m.Sender = &tb.User{ID: -1} + m.Sender = &tb.User{ID: 0} + } + if m.Chat == nil { + m.Chat = &tb.Chat{ID: 0} } prefix = fmt.Sprintf("C%d/U%d", m.Chat.ID, m.Sender.ID) } diff --git a/helpers/logger_test.go b/helpers/logger_test.go index 13391e7..e3a33f0 100644 --- a/helpers/logger_test.go +++ b/helpers/logger_test.go @@ -20,4 +20,6 @@ func TestLogLocal(t *testing.T) { helpers.LogLocalf(helpers.TRACE, &tb.Message{Chat: &tb.Chat{ID: 12345}, Sender: &tb.User{ID: 12345}}, "This is a test log") helpers.LogLocalf(helpers.TRACE, &tb.Message{Chat: &tb.Chat{ID: 12345}}, "This is a test log without sender (historical tests)") + helpers.LogLocalf(helpers.TRACE, &tb.Message{}, "No chat") + helpers.LogLocalf(helpers.TRACE, nil, "No message at all") }