Вопрос отчасти повторяет мой старый (
https://qna.habr.com/q/1265138), на который не дали ответ.
Небольшое пояснение темы для джавистов, кто не шарит в тг.
Когда в чате с ботом что-то происходит, прилетает обновление, из которого можно вытащить сообщение. Каждое сообщение может содержать в себе медиа. Но когда вы пересылаете медиа группы (альбомы), они на самом деле уходят как сообщения-одиночки, но имеющие общий идентификатор медиа группы. Для каждого уникального чата в сообщении есть уникальный идентификатор.
С помощью документации, я в итоге написал такую простыню:
кодimport org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.send.SendMediaGroup;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.PhotoSize;
import org.telegram.telegrambots.meta.api.objects.media.InputMedia;
import org.telegram.telegrambots.meta.api.objects.media.InputMediaDocument;
import org.telegram.telegrambots.meta.api.objects.media.InputMediaPhoto;
import org.telegram.telegrambots.meta.api.objects.media.InputMediaVideo;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class MediaGroupHandler {
private Timer timer;
private List<InputMedia> mediaList;
private String currentMediaGroupId;
private TelegramLongPollingBot bot;
private long chatId;
public MediaGroupHandler(TelegramLongPollingBot bot, long chatId) {
this.bot = bot;
this.mediaList = new ArrayList<>();
this.chatId = chatId;
}
public bool isInstanceFor(long chatId) {
return this.chatId == chatId;
}
public void handleMediaGroup(Message message) {
String mediaGroupId = message.getMediaGroupId();
if (mediaGroupId == null) {
return;
}
if (!mediaGroupId.equals(currentMediaGroupId)) {
sendMediaList();
mediaList.clear();
currentMediaGroupId = mediaGroupId;
}
List<PhotoSize> photos = message.getPhoto();
if (!photos.isEmpty()) {
PhotoSize photo = photos.get(photos.size() - 1);
mediaList.add(new InputMediaPhoto(photo.getFileId()));
} else if (message.getVideo() != null) {
mediaList.add(new InputMediaVideo(message.getVideo().getFileId()));
} else if (message.getDocument() != null) {
mediaList.add(new InputMediaDocument(message.getDocument().getFileId()));
}
if (timer != null) {
timer.cancel();
}
timer = new Timer();
timer.schedule(new MediaGroupTask(), 1000);
}
private void sendMediaList() {
if (mediaList.isEmpty()) {
return;
}
SendMediaGroup sendMediaGroup = new SendMediaGroup();
sendMediaGroup.setChatId(chatId);
sendMediaGroup.setMedia(mediaList);
try {
bot.execute(sendMediaGroup);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
private class MediaGroupTask extends TimerTask {
@Override
public void run() {
sendMediaList();
mediaList.clear();
currentMediaGroupId = null;
timer = null;
}
}
}
Проблема в том, что апдейт может прилететь от любого пользователя бота в любой момент и мне нужно запускать неизвестное количество инстансов этого класса (для каждого чата по 1). Типа он начинает ждать секунду нового сообщения, а в этот момент 50±50 других пользователей одновременно высылают своё и всё сбивают.
Я пока дошёл только до того, что всякий раз, как когда прилетает альбом от нового пользователя, я создаю для него новый инстанс класса и они все висят до рестарта приложения.
Я не шарю в теме пулов объектов, но что-то мне подсказывает, что задачу можно как-то решить с его помощью. Если нет, то есть ли какие-нибудь ещё способы с этим разобраться? Критично важно, чтобы альбомы приходили такими, какими их отправляли.