Fixed bot verbosity

This commit is contained in:
Stephan D
2026-03-05 11:02:30 +01:00
parent 364731a8c7
commit d1e47841cc
5 changed files with 151 additions and 47 deletions

View File

@@ -15,7 +15,9 @@ import (
)
const unauthorizedMessage = "Sorry, your Telegram account is not authorized to perform treasury operations."
const welcomeMessage = "Welcome to tgsettle treasury bot.\n\nUse /fund to credit your account and /withdraw to debit it.\nAfter entering an amount, use /confirm or /cancel."
const unauthorizedChatMessage = "Sorry, this Telegram chat is not authorized to perform treasury operations."
var welcomeMessage = "Welcome to tgsettle treasury bot.\n\nUse " + CommandFund.Slash() + " to credit your account and " + CommandWithdraw.Slash() + " to debit it.\nAfter entering an amount, use " + CommandConfirm.Slash() + " or " + CommandCancel.Slash() + "."
type SendTextFunc func(ctx context.Context, chatID string, text string) error
@@ -119,6 +121,8 @@ func (r *Router) HandleUpdate(ctx context.Context, update *model.TelegramWebhook
}
if !r.allowAnyChat {
if _, ok := r.allowedChats[chatID]; !ok {
r.logUnauthorized(update)
_ = r.sendText(ctx, chatID, unauthorizedChatMessage)
return true
}
}
@@ -132,19 +136,19 @@ func (r *Router) HandleUpdate(ctx context.Context, update *model.TelegramWebhook
command := parseCommand(text)
switch command {
case "start":
case CommandStart:
_ = r.sendText(ctx, chatID, welcomeMessage)
return true
case "fund":
case CommandFund:
r.startAmountDialog(ctx, userID, accountID, chatID, storagemodel.TreasuryOperationFund)
return true
case "withdraw":
case CommandWithdraw:
r.startAmountDialog(ctx, userID, accountID, chatID, storagemodel.TreasuryOperationWithdraw)
return true
case "confirm":
case CommandConfirm:
r.confirm(ctx, userID, accountID, chatID)
return true
case "cancel":
case CommandCancel:
r.cancel(ctx, userID, accountID, chatID)
return true
}
@@ -156,13 +160,20 @@ func (r *Router) HandleUpdate(ctx context.Context, update *model.TelegramWebhook
r.captureAmount(ctx, userID, accountID, chatID, session.OperationType, text)
return true
case DialogStateWaitingConfirmation:
_ = r.sendText(ctx, chatID, "Confirm operation?\n\n/confirm\n/cancel")
_ = r.sendText(ctx, chatID, confirmationCommandsMessage())
return true
}
}
if strings.HasPrefix(text, "/") {
_ = r.sendText(ctx, chatID, "Supported commands:\n/start\n/fund\n/withdraw\n/confirm\n/cancel")
_ = r.sendText(ctx, chatID, supportedCommandsMessage())
return true
}
if strings.TrimSpace(message.ReplyToMessageID) != "" {
return false
}
if text != "" {
_ = r.sendText(ctx, chatID, supportedCommandsMessage())
return true
}
return false
@@ -212,22 +223,22 @@ func (r *Router) captureAmount(ctx context.Context, userID, accountID, chatID st
if typed, ok := err.(limitError); ok {
switch typed.LimitKind() {
case "per_operation":
_ = r.sendText(ctx, chatID, "Amount exceeds allowed limit.\n\nMax per operation: "+typed.LimitMax()+"\n\nEnter another amount or /cancel")
_ = r.sendText(ctx, chatID, "Amount exceeds allowed limit.\n\nMax per operation: "+typed.LimitMax()+"\n\nEnter another amount or "+CommandCancel.Slash())
return
case "daily":
_ = r.sendText(ctx, chatID, "Daily amount limit exceeded.\n\nMax per day: "+typed.LimitMax()+"\n\nEnter another amount or /cancel")
_ = r.sendText(ctx, chatID, "Daily amount limit exceeded.\n\nMax per day: "+typed.LimitMax()+"\n\nEnter another amount or "+CommandCancel.Slash())
return
}
}
if errors.Is(err, merrors.ErrInvalidArg) {
_ = r.sendText(ctx, chatID, "Invalid amount.\n\nEnter another amount or /cancel")
_ = r.sendText(ctx, chatID, "Invalid amount.\n\nEnter another amount or "+CommandCancel.Slash())
return
}
_ = r.sendText(ctx, chatID, "Failed to create treasury request.\n\nEnter another amount or /cancel")
_ = r.sendText(ctx, chatID, "Failed to create treasury request.\n\nEnter another amount or "+CommandCancel.Slash())
return
}
if record == nil {
_ = r.sendText(ctx, chatID, "Failed to create treasury request.\n\nEnter another amount or /cancel")
_ = r.sendText(ctx, chatID, "Failed to create treasury request.\n\nEnter another amount or "+CommandCancel.Slash())
return
}
r.dialogs.Set(userID, DialogSession{
@@ -254,7 +265,7 @@ func (r *Router) confirm(ctx context.Context, userID string, accountID string, c
}
record, err := r.service.ConfirmRequest(ctx, requestID, userID)
if err != nil {
_ = r.sendText(ctx, chatID, "Unable to confirm treasury request.\n\nUse /cancel or create a new request with /fund or /withdraw.")
_ = r.sendText(ctx, chatID, "Unable to confirm treasury request.\n\nUse "+CommandCancel.Slash()+" or create a new request with "+CommandFund.Slash()+" or "+CommandWithdraw.Slash()+".")
return
}
if r.tracker != nil {
@@ -323,18 +334,18 @@ func (r *Router) logUnauthorized(update *model.TelegramWebhookUpdate) {
func pendingRequestMessage(record *storagemodel.TreasuryRequest) string {
if record == nil {
return "You already have a pending treasury operation.\n\n/cancel"
return "You already have a pending treasury operation.\n\n" + CommandCancel.Slash()
}
return "You already have a pending treasury operation.\n\n" +
"Request ID: " + strings.TrimSpace(record.RequestID) + "\n" +
"Status: " + strings.TrimSpace(string(record.Status)) + "\n" +
"Amount: " + strings.TrimSpace(record.Amount) + " " + strings.TrimSpace(record.Currency) + "\n\n" +
"Wait for execution or cancel it.\n\n/cancel"
"Wait for execution or cancel it.\n\n" + CommandCancel.Slash()
}
func confirmationPrompt(record *storagemodel.TreasuryRequest) string {
if record == nil {
return "Request created.\n\n/confirm\n/cancel"
return "Request created.\n\n" + CommandConfirm.Slash() + "\n" + CommandCancel.Slash()
}
title := "Funding request created."
if record.OperationType == storagemodel.TreasuryOperationWithdraw {
@@ -343,23 +354,7 @@ func confirmationPrompt(record *storagemodel.TreasuryRequest) string {
return title + "\n\n" +
"Account: " + strings.TrimSpace(record.LedgerAccountID) + "\n" +
"Amount: " + strings.TrimSpace(record.Amount) + " " + strings.TrimSpace(record.Currency) + "\n\n" +
"Confirm operation?\n\n/confirm\n/cancel"
}
func parseCommand(text string) string {
text = strings.TrimSpace(text)
if !strings.HasPrefix(text, "/") {
return ""
}
token := text
if idx := strings.IndexAny(token, " \t\n\r"); idx >= 0 {
token = token[:idx]
}
token = strings.TrimPrefix(token, "/")
if idx := strings.Index(token, "@"); idx >= 0 {
token = token[:idx]
}
return strings.ToLower(strings.TrimSpace(token))
confirmationCommandsMessage()
}
func formatSeconds(value int64) string {