mirror of
https://github.com/BEARlogin/max-telegram-bridge-bot.git
synced 2026-04-28 03:39:46 +00:00
Simplify upload error hints — user-facing, no config details
Some checks are pending
Build / build (push) Waiting to run
Some checks are pending
Build / build (push) Waiting to run
Previous hints mentioned bot config (e.g. "20 MB limit without local server") which is useless to a regular group member who can't administer the bot. Drop technical detail: - "файл слишком большой" (no parenthetical) - "файл не найден" - "попробуйте ещё раз" (for transient MAX CDN) - unknown error → no suffix, just the generic "Не удалось отправить X в MAX." New helper uploadErrMsg(base, err) builds the final string, appending ": hint." only when uploadErrHint returns a non-empty known hint. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
825bfee473
commit
9b7e3cd165
3 changed files with 32 additions and 30 deletions
28
bridge.go
28
bridge.go
|
|
@ -204,8 +204,9 @@ func (b *Bridge) isSelfTgBot(from *UserInfo) bool {
|
|||
return from != nil && from.IsBot && from.UserName == b.tg.BotUsername()
|
||||
}
|
||||
|
||||
// uploadErrHint превращает техническую ошибку загрузки в короткий русский текст
|
||||
// для отправки в чат. Для неизвестных ошибок отдаёт усечённое сырое сообщение.
|
||||
// uploadErrHint превращает техническую ошибку загрузки в короткий текст для юзера.
|
||||
// Возвращает пустую строку для неизвестных ошибок — вызывающий код тогда
|
||||
// отправит только generic-сообщение без технической мути.
|
||||
func uploadErrHint(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
|
|
@ -213,21 +214,22 @@ func uploadErrHint(err error) string {
|
|||
s := err.Error()
|
||||
switch {
|
||||
case strings.Contains(s, "file is too big"):
|
||||
return "файл слишком большой для Telegram Bot API (лимит без локального сервера — 20 МБ)"
|
||||
return "файл слишком большой"
|
||||
case strings.Contains(s, "file is not found") || strings.Contains(s, "FILE_REFERENCE_EXPIRED"):
|
||||
return "Telegram не нашёл файл (возможно, он удалён или ссылка протухла)"
|
||||
case strings.Contains(s, "wrong file id") || strings.Contains(s, "Wrong file"):
|
||||
return "некорректный file_id"
|
||||
return "файл не найден"
|
||||
case strings.Contains(s, "attachment.not.ready"):
|
||||
return "MAX CDN не успел обработать файл — попробуйте ещё раз"
|
||||
case strings.Contains(s, "chat.denied"):
|
||||
return "MAX отклонил отправку: бот не добавлен в чат или не имеет прав"
|
||||
return "попробуйте ещё раз"
|
||||
}
|
||||
const maxLen = 180
|
||||
if len(s) > maxLen {
|
||||
s = s[:maxLen] + "…"
|
||||
return ""
|
||||
}
|
||||
|
||||
// uploadErrMsg собирает user-facing сообщение: base + ": hint" если подсказка известна,
|
||||
// иначе просто "base." (без технической ошибки).
|
||||
func uploadErrMsg(base string, err error) string {
|
||||
if hint := uploadErrHint(err); hint != "" {
|
||||
return base + ": " + hint + "."
|
||||
}
|
||||
return s
|
||||
return base + "."
|
||||
}
|
||||
|
||||
func (b *Bridge) tgWebhookPath() string {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ func (b *Bridge) flushMediaGroup(ctx context.Context, groupID string) {
|
|||
}
|
||||
if photoFailErr != nil && photosSent == 0 {
|
||||
b.tg.SendMessage(ctx, items[0].msg.Chat.ID,
|
||||
fmt.Sprintf("Не удалось отправить альбом в MAX: %s", uploadErrHint(photoFailErr)), nil)
|
||||
uploadErrMsg("Не удалось отправить альбом в MAX", photoFailErr), nil)
|
||||
}
|
||||
|
||||
// Загружаем видео из альбома через direct API
|
||||
|
|
|
|||
32
telegram.go
32
telegram.go
|
|
@ -620,7 +620,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
m.AddPhoto(uploaded)
|
||||
} else {
|
||||
slog.Error("TG→MAX photo upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить фото в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить фото в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else if fileURL, err := b.tgFileURL(ctx, photo.FileID); err == nil {
|
||||
|
|
@ -628,12 +628,12 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
m.AddPhoto(uploaded)
|
||||
} else {
|
||||
slog.Error("TG→MAX photo upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить фото в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить фото в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
slog.Error("TG→MAX photo upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить фото в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить фото в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
if msg.ReplyToMessage != nil {
|
||||
|
|
@ -669,7 +669,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
mediaAttType = "video"
|
||||
} else {
|
||||
slog.Error("TG→MAX gif upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить GIF \"%s\" в MAX: %s", name, uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg(fmt.Sprintf("Не удалось отправить GIF \"%s\" в MAX", name), err), nil)
|
||||
return
|
||||
}
|
||||
} else if msg.Sticker != nil {
|
||||
|
|
@ -683,7 +683,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
mediaAttType = "video"
|
||||
} else {
|
||||
slog.Error("TG→MAX sticker upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить стикер в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить стикер в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
|
@ -701,7 +701,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
result, err := b.maxApi.Messages.SendWithResult(ctx, m)
|
||||
if err != nil {
|
||||
slog.Error("TG→MAX sticker send failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить стикер в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить стикер в MAX", err), nil)
|
||||
} else {
|
||||
slog.Info("TG→MAX sent", "mid", result.Body.Mid)
|
||||
b.repo.SaveMsg(msg.Chat.ID, msg.MessageID, maxChatID, result.Body.Mid, msg.MessageThreadID)
|
||||
|
|
@ -709,12 +709,12 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
return
|
||||
} else {
|
||||
slog.Error("TG→MAX sticker photo upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить стикер в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить стикер в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
slog.Error("TG→MAX sticker getFileURL failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить стикер в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить стикер в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -731,7 +731,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
mediaAttType = "video"
|
||||
} else {
|
||||
slog.Error("TG→MAX video upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить видео \"%s\" в MAX: %s", name, uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg(fmt.Sprintf("Не удалось отправить видео \"%s\" в MAX", name), err), nil)
|
||||
return
|
||||
}
|
||||
} else if msg.VideoNote != nil {
|
||||
|
|
@ -743,7 +743,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
mediaAttType = "video"
|
||||
} else {
|
||||
slog.Error("TG→MAX video note upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить кружок в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить кружок в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else if msg.Document != nil {
|
||||
|
|
@ -785,7 +785,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
}
|
||||
slog.Error("TG→MAX file upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID,
|
||||
fmt.Sprintf("Не удалось отправить файл \"%s\" в MAX: %s", name, uploadErrHint(err)), nil)
|
||||
uploadErrMsg(fmt.Sprintf("Не удалось отправить файл \"%s\" в MAX", name), err), nil)
|
||||
return
|
||||
}
|
||||
} else if msg.Voice != nil {
|
||||
|
|
@ -803,7 +803,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
return
|
||||
}
|
||||
slog.Error("TG→MAX voice upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить голосовое сообщение в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось отправить голосовое сообщение в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else if msg.Audio != nil {
|
||||
|
|
@ -834,7 +834,7 @@ func (b *Bridge) forwardTgToMax(ctx context.Context, msg *TGMessage, maxChatID i
|
|||
return
|
||||
}
|
||||
slog.Error("TG→MAX audio upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось отправить аудио \"%s\" в MAX: %s", name, uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg(fmt.Sprintf("Не удалось отправить аудио \"%s\" в MAX", name), err), nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -965,7 +965,7 @@ func (b *Bridge) editTgMediaInMax(ctx context.Context, msg *TGMessage, maxChatID
|
|||
m.AddPhoto(uploaded)
|
||||
} else {
|
||||
slog.Error("TG→MAX edit photo upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось обновить фото в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось обновить фото в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else if fileURL, err := b.tgFileURL(ctx, photo.FileID); err == nil {
|
||||
|
|
@ -973,12 +973,12 @@ func (b *Bridge) editTgMediaInMax(ctx context.Context, msg *TGMessage, maxChatID
|
|||
m.AddPhoto(uploaded)
|
||||
} else {
|
||||
slog.Error("TG→MAX edit photo upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось обновить фото в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось обновить фото в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
slog.Error("TG→MAX edit photo upload failed", "err", err)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, fmt.Sprintf("Не удалось обновить фото в MAX: %s", uploadErrHint(err)), nil)
|
||||
b.tg.SendMessage(ctx, msg.Chat.ID, uploadErrMsg("Не удалось обновить фото в MAX", err), nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue