Добавил новые типы вложений: стикеры и голосовые. Также добавил новый тип события: отредактированное сообщение
Some checks reported errors
continuous-integration/drone/push Build encountered an error

This commit is contained in:
Struchkov Mark 2023-11-24 21:18:35 +03:00
parent 842c36086e
commit 139bd06692
Signed by: upagge
GPG Key ID: D3018BE7BA428CA6
11 changed files with 165 additions and 26 deletions

View File

@ -1,6 +1,7 @@
package dev.struchkov.godfather.telegram.quarkus.consumer; package dev.struchkov.godfather.telegram.quarkus.consumer;
import dev.struchkov.godfather.main.domain.EventContainer; import dev.struchkov.godfather.main.domain.EventContainer;
import dev.struchkov.godfather.main.domain.content.EditedMail;
import dev.struchkov.godfather.main.domain.content.Mail; import dev.struchkov.godfather.main.domain.content.Mail;
import dev.struchkov.godfather.quarkus.context.service.EventDispatching; import dev.struchkov.godfather.quarkus.context.service.EventDispatching;
import dev.struchkov.godfather.telegram.domain.event.Subscribe; import dev.struchkov.godfather.telegram.domain.event.Subscribe;
@ -44,6 +45,7 @@ public class EventDistributorService implements EventDistributor {
.onItem().transformToUni( .onItem().transformToUni(
v -> { v -> {
final Message message = update.getMessage(); final Message message = update.getMessage();
final Message editedMessage = update.getEditedMessage();
final CallbackQuery callbackQuery = update.getCallbackQuery(); final CallbackQuery callbackQuery = update.getCallbackQuery();
final PreCheckoutQuery preCheckoutQuery = update.getPreCheckoutQuery(); final PreCheckoutQuery preCheckoutQuery = update.getPreCheckoutQuery();
final InlineQuery inlineQuery = update.getInlineQuery(); final InlineQuery inlineQuery = update.getInlineQuery();
@ -66,6 +68,10 @@ public class EventDistributorService implements EventDistributor {
return Uni.createFrom().item(new EventContainer<>(Mail.class, MessageMailConvert.apply(message))); return Uni.createFrom().item(new EventContainer<>(Mail.class, MessageMailConvert.apply(message)));
} }
if (update.hasEditedMessage()) {
return Uni.createFrom().item(new EventContainer<>(EditedMail.class, MessageMailConvert.applyEdited(editedMessage)));
}
if (update.hasCallbackQuery()) { if (update.hasCallbackQuery()) {
return Uni.createFrom().item(new EventContainer<>(Mail.class, CallbackQueryConvert.apply(callbackQuery))); return Uni.createFrom().item(new EventContainer<>(Mail.class, CallbackQueryConvert.apply(callbackQuery)));
} }

View File

@ -1,6 +1,7 @@
package dev.struchkov.godfather.telegram.main.context.convert; package dev.struchkov.godfather.telegram.main.context.convert;
import dev.struchkov.godfather.main.domain.content.Attachment; import dev.struchkov.godfather.main.domain.content.Attachment;
import dev.struchkov.godfather.main.domain.content.EditedMail;
import dev.struchkov.godfather.main.domain.content.Mail; import dev.struchkov.godfather.main.domain.content.Mail;
import dev.struchkov.godfather.telegram.domain.attachment.CommandAttachment; import dev.struchkov.godfather.telegram.domain.attachment.CommandAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.ContactAttachment; import dev.struchkov.godfather.telegram.domain.attachment.ContactAttachment;
@ -8,7 +9,9 @@ import dev.struchkov.godfather.telegram.domain.attachment.DocumentAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment; import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.Picture; import dev.struchkov.godfather.telegram.domain.attachment.Picture;
import dev.struchkov.godfather.telegram.domain.attachment.PictureGroupAttachment; import dev.struchkov.godfather.telegram.domain.attachment.PictureGroupAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.StickerAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.VideoAttachment; import dev.struchkov.godfather.telegram.domain.attachment.VideoAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.VoiceAttachment;
import dev.struchkov.godfather.telegram.main.context.MailPayload; import dev.struchkov.godfather.telegram.main.context.MailPayload;
import dev.struchkov.haiti.utils.Checker; import dev.struchkov.haiti.utils.Checker;
import dev.struchkov.haiti.utils.Strings; import dev.struchkov.haiti.utils.Strings;
@ -19,13 +22,17 @@ import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.MessageEntity; import org.telegram.telegrambots.meta.api.objects.MessageEntity;
import org.telegram.telegrambots.meta.api.objects.PhotoSize; import org.telegram.telegrambots.meta.api.objects.PhotoSize;
import org.telegram.telegrambots.meta.api.objects.Video; import org.telegram.telegrambots.meta.api.objects.Video;
import org.telegram.telegrambots.meta.api.objects.Voice;
import org.telegram.telegrambots.meta.api.objects.stickers.Sticker;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank; import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Exceptions.utilityClass; import static dev.struchkov.haiti.utils.Exceptions.utilityClass;
@ -41,6 +48,13 @@ public final class MessageMailConvert {
utilityClass(); utilityClass();
} }
public static EditedMail applyEdited(Message message) {
return EditedMail.builder()
.editDate(LocalDateTime.ofInstant(Instant.ofEpochSecond(message.getEditDate()), ZoneId.systemDefault()))
.newMail(apply(message))
.build();
}
public static Mail apply(Message message) { public static Mail apply(Message message) {
final Mail mail = new Mail(); final Mail mail = new Mail();
@ -59,6 +73,7 @@ public final class MessageMailConvert {
convertContact(message.getContact()).ifPresent(mail::addAttachment); convertContact(message.getContact()).ifPresent(mail::addAttachment);
convertPhoto(message.getPhoto()).ifPresent(mail::addAttachment); convertPhoto(message.getPhoto()).ifPresent(mail::addAttachment);
convertVideo(message.getVideo()).ifPresent(mail::addAttachment); convertVideo(message.getVideo()).ifPresent(mail::addAttachment);
convertVoice(message.getVoice()).ifPresent(mail::addAttachment);
final List<MessageEntity> entities = message.getEntities(); final List<MessageEntity> entities = message.getEntities();
if (entities != null) { if (entities != null) {
@ -134,6 +149,32 @@ public final class MessageMailConvert {
return Optional.empty(); return Optional.empty();
} }
private static Optional<VoiceAttachment> convertVoice(Voice voice) {
if (voice != null) {
final VoiceAttachment attachment = new VoiceAttachment();
attachment.setFileId(voice.getFileId());
attachment.setFileSize(voice.getFileSize());
attachment.setMimeType(voice.getMimeType());
attachment.setDuration(Duration.ofSeconds(voice.getDuration()));
attachment.setFileName(UUID.randomUUID().toString());
return Optional.of(attachment);
}
return Optional.empty();
}
private static Optional<StickerAttachment> convertVoice(Sticker sticker) {
if (sticker != null) {
final StickerAttachment attachment = new StickerAttachment();
attachment.setFileId(sticker.getFileId());
attachment.setFileSize(sticker.getFileSize().longValue());
attachment.setAnimated(sticker.getIsAnimated());
attachment.setVideo(sticker.getIsVideo());
attachment.setFileName(UUID.randomUUID().toString());
return Optional.of(attachment);
}
return Optional.empty();
}
private static Optional<VideoAttachment> convertVideo(Video video) { private static Optional<VideoAttachment> convertVideo(Video video) {
if (video != null) { if (video != null) {
final VideoAttachment attachment = new VideoAttachment(); final VideoAttachment attachment = new VideoAttachment();

View File

@ -1,6 +1,6 @@
package dev.struchkov.godfather.telegram.quarkus.context.service; package dev.struchkov.godfather.telegram.quarkus.context.service;
import dev.struchkov.godfather.telegram.domain.attachment.DocumentAttachment; import dev.struchkov.godfather.telegram.domain.attachment.FileAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.Picture; import dev.struchkov.godfather.telegram.domain.attachment.Picture;
import dev.struchkov.godfather.telegram.domain.files.ByteContainer; import dev.struchkov.godfather.telegram.domain.files.ByteContainer;
import dev.struchkov.godfather.telegram.domain.files.FileContainer; import dev.struchkov.godfather.telegram.domain.files.FileContainer;
@ -9,9 +9,9 @@ import org.jetbrains.annotations.NotNull;
public interface AttachmentService { public interface AttachmentService {
Uni<FileContainer> uploadFile(@NotNull DocumentAttachment documentAttachment); Uni<FileContainer> uploadFile(@NotNull FileAttachment documentAttachment);
Uni<ByteContainer> uploadBytes(@NotNull DocumentAttachment documentAttachment); Uni<ByteContainer> uploadBytes(@NotNull FileAttachment fileAttachment);
Uni<ByteContainer> uploadBytes(@NotNull Picture picture); Uni<ByteContainer> uploadBytes(@NotNull Picture picture);

View File

@ -8,8 +8,10 @@ import dev.struchkov.godfather.telegram.domain.attachment.DocumentAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment; import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.Picture; import dev.struchkov.godfather.telegram.domain.attachment.Picture;
import dev.struchkov.godfather.telegram.domain.attachment.PictureGroupAttachment; import dev.struchkov.godfather.telegram.domain.attachment.PictureGroupAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.StickerAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.TelegramAttachmentType; import dev.struchkov.godfather.telegram.domain.attachment.TelegramAttachmentType;
import dev.struchkov.godfather.telegram.domain.attachment.VideoAttachment; import dev.struchkov.godfather.telegram.domain.attachment.VideoAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.VoiceAttachment;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -47,6 +49,28 @@ public final class Attachments {
return Optional.empty(); return Optional.empty();
} }
public static Optional<VoiceAttachment> findFirstVoice(Collection<Attachment> attachments) {
if (checkNotEmpty(attachments)) {
for (Attachment attachment : attachments) {
if (isVoice(attachment)) {
return Optional.of((VoiceAttachment) attachment);
}
}
}
return Optional.empty();
}
public static Optional<StickerAttachment> findFirstSticker(Collection<Attachment> attachments) {
if (checkNotEmpty(attachments)) {
for (Attachment attachment : attachments) {
if (isSticker(attachment)) {
return Optional.of((StickerAttachment) attachment);
}
}
}
return Optional.empty();
}
public static Optional<ButtonClickAttachment> findFirstButtonClick(Collection<Attachment> attachments) { public static Optional<ButtonClickAttachment> findFirstButtonClick(Collection<Attachment> attachments) {
if (checkNotEmpty(attachments)) { if (checkNotEmpty(attachments)) {
for (Attachment attachment : attachments) { for (Attachment attachment : attachments) {
@ -145,17 +169,17 @@ public final class Attachments {
return TelegramAttachmentType.DOCUMENT.name().equals(attachment.getType()); return TelegramAttachmentType.DOCUMENT.name().equals(attachment.getType());
} }
private static boolean isContact(Attachment attachment) { public static boolean isContact(Attachment attachment) {
isNotNull(attachment); isNotNull(attachment);
return TelegramAttachmentType.CONTACT.name().equals(attachment.getType()); return TelegramAttachmentType.CONTACT.name().equals(attachment.getType());
} }
private static boolean isPictureGroup(Attachment attachment) { public static boolean isPictureGroup(Attachment attachment) {
isNotNull(attachment); isNotNull(attachment);
return TelegramAttachmentType.PICTURE.name().equals(attachment.getType()); return TelegramAttachmentType.PICTURE.name().equals(attachment.getType());
} }
private static boolean isLink(Attachment attachment) { public static boolean isLink(Attachment attachment) {
isNotNull(attachment); isNotNull(attachment);
return TelegramAttachmentType.LINK.name().equals(attachment.getType()); return TelegramAttachmentType.LINK.name().equals(attachment.getType());
} }
@ -170,4 +194,14 @@ public final class Attachments {
return TelegramAttachmentType.VIDEO.name().equals(attachment.getType()); return TelegramAttachmentType.VIDEO.name().equals(attachment.getType());
} }
public static boolean isVoice(Attachment attachment) {
isNotNull(attachment);
return TelegramAttachmentType.VOICE.name().equals(attachment.getType());
}
public static boolean isSticker(Attachment attachment) {
isNotNull(attachment);
return TelegramAttachmentType.STICKER.name().equals(attachment.getType());
}
} }

View File

@ -1,7 +1,9 @@
package dev.struchkov.godfather.telegram.quarkus.core.service; package dev.struchkov.godfather.telegram.quarkus.core.service;
import dev.struchkov.godfather.telegram.domain.attachment.DocumentAttachment; import dev.struchkov.godfather.telegram.domain.attachment.DocumentAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.FileAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.Picture; import dev.struchkov.godfather.telegram.domain.attachment.Picture;
import dev.struchkov.godfather.telegram.domain.attachment.TelegramAttachmentType;
import dev.struchkov.godfather.telegram.domain.files.ByteContainer; import dev.struchkov.godfather.telegram.domain.files.ByteContainer;
import dev.struchkov.godfather.telegram.domain.files.FileContainer; import dev.struchkov.godfather.telegram.domain.files.FileContainer;
import dev.struchkov.godfather.telegram.quarkus.context.service.AttachmentService; import dev.struchkov.godfather.telegram.quarkus.context.service.AttachmentService;
@ -62,17 +64,17 @@ public class AttachmentServiceImpl implements AttachmentService {
} }
@Override @Override
public Uni<FileContainer> uploadFile(@NotNull DocumentAttachment documentAttachment) { public Uni<FileContainer> uploadFile(@NotNull FileAttachment fileAttachment) {
isNotNull(documentAttachment); isNotNull(fileAttachment);
return downloadFile(documentAttachment) return downloadFile(fileAttachment)
.onItem().ifNotNull().transform(file -> new FileContainer(documentAttachment.getFileName(), documentAttachment.getMimeType(), file)); .onItem().ifNotNull().transform(file -> new FileContainer(fileAttachment.getFileName(), fileAttachment.getMimeType(), file));
} }
@Override @Override
public Uni<ByteContainer> uploadBytes(@NotNull DocumentAttachment documentAttachment) { public Uni<ByteContainer> uploadBytes(@NotNull FileAttachment fileAttachment) {
isNotNull(documentAttachment); isNotNull(fileAttachment);
return downloadBytes(documentAttachment) return downloadBytes(fileAttachment)
.onItem().ifNotNull().transform(bytes -> new ByteContainer(documentAttachment.getFileName(), documentAttachment.getMimeType(), bytes)); .onItem().ifNotNull().transform(bytes -> new ByteContainer(fileAttachment.getFileName(), fileAttachment.getMimeType(), bytes));
} }
@Override @Override
@ -86,7 +88,7 @@ public class AttachmentServiceImpl implements AttachmentService {
return telegramDownloadBytes(picture.getFileId()); return telegramDownloadBytes(picture.getFileId());
} }
private Uni<byte[]> downloadBytes(DocumentAttachment documentAttachment) { private Uni<byte[]> downloadBytes(FileAttachment documentAttachment) {
return telegramDownloadBytes(documentAttachment.getFileId()); return telegramDownloadBytes(documentAttachment.getFileId());
} }
@ -110,15 +112,15 @@ public class AttachmentServiceImpl implements AttachmentService {
); );
} }
private Uni<File> downloadFile(DocumentAttachment documentAttachment) { private Uni<File> downloadFile(FileAttachment fileAttachment) {
return getFileUrl(documentAttachment.getFileId()) return getFileUrl(fileAttachment.getFileId())
.onItem().ifNotNull().transformToUni(fileUrl -> Uni.createFrom().completionStage( .onItem().ifNotNull().transformToUni(fileUrl -> Uni.createFrom().completionStage(
CompletableFuture.supplyAsync(() -> { CompletableFuture.supplyAsync(() -> {
final StringBuilder filePath = new StringBuilder(); final StringBuilder filePath = new StringBuilder();
if (folderPathForFiles != null) { if (folderPathForFiles != null) {
filePath.append(folderPathForFiles); filePath.append(folderPathForFiles);
} }
filePath.append(UUID.randomUUID()).append("_").append(documentAttachment.getFileName()); filePath.append(UUID.randomUUID()).append("_").append(fileAttachment.getFileName());
final File localFile = new File(filePath.toString()); final File localFile = new File(filePath.toString());
final InputStream is; final InputStream is;
try { try {

View File

@ -1,17 +1,11 @@
package dev.struchkov.godfather.telegram.domain.attachment; package dev.struchkov.godfather.telegram.domain.attachment;
import dev.struchkov.godfather.main.domain.content.Attachment;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class DocumentAttachment extends Attachment { public class DocumentAttachment extends FileAttachment {
private String fileId;
private Long fileSize;
private String fileName;
private String mimeType;
public DocumentAttachment() { public DocumentAttachment() {
super(TelegramAttachmentType.DOCUMENT.name()); super(TelegramAttachmentType.DOCUMENT.name());

View File

@ -0,0 +1,20 @@
package dev.struchkov.godfather.telegram.domain.attachment;
import dev.struchkov.godfather.main.domain.content.Attachment;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class FileAttachment extends Attachment {
protected String fileId;
protected Long fileSize;
protected String mimeType;
private String fileName;
protected FileAttachment(String type) {
super(type);
}
}

View File

@ -0,0 +1,18 @@
package dev.struchkov.godfather.telegram.domain.attachment;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class StickerAttachment extends FileAttachment {
private String emoji;
private boolean video;
private boolean animated;
public StickerAttachment() {
super(TelegramAttachmentType.STICKER.name());
}
}

View File

@ -8,6 +8,8 @@ public enum TelegramAttachmentType {
LINK, LINK,
COMMAND, COMMAND,
BUTTON_CLICK, BUTTON_CLICK,
VIDEO VIDEO,
VOICE,
STICKER
} }

View File

@ -0,0 +1,18 @@
package dev.struchkov.godfather.telegram.domain.attachment;
import lombok.Getter;
import lombok.Setter;
import java.time.Duration;
@Getter
@Setter
public class VoiceAttachment extends FileAttachment {
private Duration duration;
public VoiceAttachment() {
super(TelegramAttachmentType.VOICE.name());
}
}

View File

@ -11,8 +11,10 @@ import dev.struchkov.godfather.telegram.domain.attachment.ContactAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.DocumentAttachment; import dev.struchkov.godfather.telegram.domain.attachment.DocumentAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment; import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.PictureGroupAttachment; import dev.struchkov.godfather.telegram.domain.attachment.PictureGroupAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.StickerAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.TelegramAttachmentType; import dev.struchkov.godfather.telegram.domain.attachment.TelegramAttachmentType;
import dev.struchkov.godfather.telegram.domain.attachment.VideoAttachment; import dev.struchkov.godfather.telegram.domain.attachment.VideoAttachment;
import dev.struchkov.godfather.telegram.domain.attachment.VoiceAttachment;
import dev.struchkov.haiti.utils.ObjectUtils; import dev.struchkov.haiti.utils.ObjectUtils;
import java.io.IOException; import java.io.IOException;
@ -41,6 +43,8 @@ public class TelegramAttachmentDeserializer extends StdDeserializer<Attachment>
case LINK -> parser.getCodec().treeToValue(node, LinkAttachment.class); case LINK -> parser.getCodec().treeToValue(node, LinkAttachment.class);
case COMMAND -> parser.getCodec().treeToValue(node, CommandAttachment.class); case COMMAND -> parser.getCodec().treeToValue(node, CommandAttachment.class);
case VIDEO -> parser.getCodec().treeToValue(node, VideoAttachment.class); case VIDEO -> parser.getCodec().treeToValue(node, VideoAttachment.class);
case VOICE -> parser.getCodec().treeToValue(node, VoiceAttachment.class);
case STICKER -> parser.getCodec().treeToValue(node, StickerAttachment.class);
}; };
} }