Merge pull request 'extended confirmation flow handling' (#538) from tg-537 into main
All checks were successful
ci/woodpecker/push/gateway_tgsettle Pipeline was successful
ci/woodpecker/push/payments_methods Pipeline was successful
ci/woodpecker/push/payments_quotation Pipeline was successful
ci/woodpecker/push/payments_orchestrator Pipeline was successful

Reviewed-on: #538
This commit was merged in pull request #538.
This commit is contained in:
2026-02-19 20:08:41 +00:00
2 changed files with 74 additions and 17 deletions

View File

@@ -148,14 +148,23 @@ func (s *Service) onTelegramUpdate(ctx context.Context, update *model.TelegramWe
if replyToID == "" {
return nil
}
replyFields := telegramReplyLogFields(update)
pending, err := s.repo.PendingConfirmations().FindByMessageID(ctx, replyToID)
if err != nil {
return err
}
if pending == nil {
s.logger.Debug("Telegram reply ignored: no pending confirmation for message", zap.String("reply_to_message_id", replyToID), zap.Int64("update_id", update.UpdateID))
s.logger.Info("Telegram confirmation reply dropped",
append(replyFields,
zap.String("outcome", "dropped"),
zap.String("reason", "no_pending_confirmation"),
)...)
return nil
}
replyFields = append(replyFields,
zap.String("request_id", strings.TrimSpace(pending.RequestID)),
zap.String("target_chat_id", strings.TrimSpace(pending.TargetChatID)),
)
if !pending.ExpiresAt.IsZero() && time.Now().After(pending.ExpiresAt) {
result := &model.ConfirmationResult{
@@ -165,14 +174,25 @@ func (s *Service) onTelegramUpdate(ctx context.Context, update *model.TelegramWe
if err := s.publishPendingConfirmationResult(pending, result); err != nil {
return err
}
return s.clearPendingConfirmation(ctx, pending.RequestID)
if err := s.clearPendingConfirmation(ctx, pending.RequestID); err != nil {
return err
}
s.logger.Info("Telegram confirmation reply processed",
append(replyFields,
zap.String("outcome", "processed"),
zap.String("result_status", string(result.Status)),
zap.String("reason", "expired_confirmation"),
)...)
return nil
}
if strings.TrimSpace(message.ChatID) != strings.TrimSpace(pending.TargetChatID) {
s.logger.Debug("Telegram reply ignored: chat mismatch",
zap.String("request_id", pending.RequestID),
zap.String("expected_chat_id", pending.TargetChatID),
zap.String("chat_id", strings.TrimSpace(message.ChatID)))
s.logger.Info("Telegram confirmation reply dropped",
append(replyFields,
zap.String("outcome", "dropped"),
zap.String("reason", "chat_mismatch"),
zap.String("expected_chat_id", strings.TrimSpace(pending.TargetChatID)),
)...)
return nil
}
@@ -192,7 +212,16 @@ func (s *Service) onTelegramUpdate(ctx context.Context, update *model.TelegramWe
ReplyToMessageID: message.MessageID,
Text: "Only approved users can confirm this payment.",
})
return s.clearPendingConfirmation(ctx, pending.RequestID)
if err := s.clearPendingConfirmation(ctx, pending.RequestID); err != nil {
return err
}
s.logger.Info("Telegram confirmation reply processed",
append(replyFields,
zap.String("outcome", "processed"),
zap.String("result_status", string(result.Status)),
zap.String("reason", "unauthorized_user"),
)...)
return nil
}
money, reason, err := parseConfirmationReply(message.Text)
@@ -206,6 +235,12 @@ func (s *Service) onTelegramUpdate(ctx context.Context, update *model.TelegramWe
ReplyToMessageID: message.MessageID,
Text: clarificationMessage(reason),
})
s.logger.Info("Telegram confirmation reply dropped",
append(replyFields,
zap.String("outcome", "dropped"),
zap.String("reason", "invalid_reply_format"),
zap.String("parse_reason", reason),
)...)
return nil
}
@@ -222,7 +257,29 @@ func (s *Service) onTelegramUpdate(ctx context.Context, update *model.TelegramWe
if err := s.publishPendingConfirmationResult(pending, result); err != nil {
return err
}
return s.clearPendingConfirmation(ctx, pending.RequestID)
if err := s.clearPendingConfirmation(ctx, pending.RequestID); err != nil {
return err
}
s.logger.Info("Telegram confirmation reply processed",
append(replyFields,
zap.String("outcome", "processed"),
zap.String("result_status", string(result.Status)),
)...)
return nil
}
func telegramReplyLogFields(update *model.TelegramWebhookUpdate) []zap.Field {
if update == nil || update.Message == nil {
return nil
}
message := update.Message
return []zap.Field{
zap.Int64("update_id", update.UpdateID),
zap.String("message_id", strings.TrimSpace(message.MessageID)),
zap.String("reply_to_message_id", strings.TrimSpace(message.ReplyToMessageID)),
zap.String("chat_id", strings.TrimSpace(message.ChatID)),
zap.String("from_user_id", strings.TrimSpace(message.FromUserID)),
}
}
func (s *Service) publishPendingConfirmationResult(pending *storagemodel.PendingConfirmation, result *model.ConfirmationResult) error {