diff --git a/.gitignore b/.gitignore index 9ae098b..4dc9ad8 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ bridge.db.bak broadcast.sh broadcast_*.html .broadcast_sent/ +bridge_chats.csv diff --git a/max.go b/max.go index f3dcbe9..e47a25b 100644 --- a/max.go +++ b/max.go @@ -63,6 +63,28 @@ func (b *Bridge) listenMax(ctx context.Context) { slog.Debug("MAX update", "type", fmt.Sprintf("%T", upd)) + // Логируем выкидывание бота из чата — пара остаётся в БД (мб случайно + // выкинули, потом вернут), но видно кто/когда удалил. + if rm, isRm := upd.(*maxschemes.BotRemovedFromChatUpdate); isRm { + tgChatID, linked := b.repo.GetTgChat(rm.ChatId) + slog.Warn("MAX bot removed from chat", + "maxChat", rm.ChatId, + "byUser", rm.User.UserId, + "byUsername", rm.User.Username, + "byName", rm.User.Name, + "linkedTgChat", tgChatID, + "linked", linked) + continue + } + if add, isAdd := upd.(*maxschemes.BotAddedToChatUpdate); isAdd { + slog.Info("MAX bot added to chat", + "maxChat", add.ChatId, + "byUser", add.User.UserId, + "byUsername", add.User.Username, + "byName", add.User.Name) + continue + } + // Обработка удаления (только bridge, не crosspost) if delUpd, isDel := upd.(*maxschemes.MessageRemovedUpdate); isDel { tgChatID, tgMsgID, _, ok := b.repo.LookupTgMsgID(delUpd.MessageId) diff --git a/queue.go b/queue.go index 3eb9376..2fe1e2c 100644 --- a/queue.go +++ b/queue.go @@ -127,8 +127,11 @@ func (b *Bridge) processQueueTg2Max(ctx context.Context, item QueueItem, now tim mid, err := b.sendMaxDirectFormatted(ctx, item.DstChatID, item.Text, item.AttType, item.AttToken, item.ReplyTo, item.Format) if err != nil { errStr := err.Error() - // Permanent errors — дропаем - if strings.Contains(errStr, "403") || strings.Contains(errStr, "404") || strings.Contains(errStr, "chat.denied") { + // Permanent errors — дропаем сразу, чтобы не блокировать очередь HoL-ом. + if strings.Contains(errStr, "403") || strings.Contains(errStr, "404") || + strings.Contains(errStr, "chat.denied") || + strings.Contains(errStr, "attachment not ready after") || + strings.Contains(errStr, "must be at most") { slog.Warn("queue item dropped (permanent error)", "id", item.ID, "err", errStr) b.repo.DeleteFromQueue(item.ID) return @@ -182,7 +185,11 @@ func (b *Bridge) processQueueMax2Tg(ctx context.Context, item QueueItem, now tim b.repo.IncrementAttempt(item.ID, now.Unix()) // retry immediately return } - if strings.Contains(errStr, "TOPIC_CLOSED") || strings.Contains(errStr, "403") || strings.Contains(errStr, "chat not found") { + if strings.Contains(errStr, "TOPIC_CLOSED") || strings.Contains(errStr, "403") || strings.Contains(errStr, "chat not found") || + strings.Contains(errStr, "can't parse entities") || + strings.Contains(errStr, "caption is too long") || + strings.Contains(errStr, "message is too long") || + strings.Contains(errStr, "MESSAGE_TOO_LONG") { slog.Warn("queue item dropped (permanent error)", "id", item.ID, "dir", "max2tg", "err", errStr) b.repo.DeleteFromQueue(item.ID) return