From 15f77a945acbcf980b3345d65723530cbd9d487d Mon Sep 17 00:00:00 2001 From: hdvt <=hadvart@hdvtdev.ru> Date: Mon, 3 Nov 2025 21:16:02 +0300 Subject: [PATCH] migration --- .idea/AndroidProjectSystem.xml | 6 + .idea/dictionaries/project.xml | 7 + TODO/ClassFinder.java | 139 ----------- annotation-processor/build.gradle | 20 ++ .../src/main/java/EventHandlersProcessor.java | 172 +++++++++++++ .../src/main/java/Generator.java | 42 ++++ .../src/main/java/HandlerWriter.java | 108 ++++++++ annotation-processor/src/main/java/Util.java | 63 +++++ .../hdvtdev/telegram/core/HandlersModule.java | 9 + .../hdvtdev/telegram/core/JsonModule.java | 8 + .../hdvtdev/telegram/core/TelegramBot.java | 2 + .../hdvtdev/telegram/core/UpdateConsumer.java | 20 +- .../hdvtdev/telegram/core/UpdateExecutor.java | 10 + .../hdvtdev/telegram/core/UpdateHandler.java | 80 ------ .../telegram/core/annotaions/Jsonable.java | 19 -- .../core/annotations/TelegramAPI.java | 9 + .../core/methods/ApproveChatJoinRequest.java | 3 +- .../telegram/core/methods/CopyMessage.java | 8 +- .../telegram/core/methods/CopyMessages.java | 9 +- .../telegram/core/methods/ForwardMessage.java | 10 +- .../core/methods/ForwardMessages.java | 7 +- .../telegram/core/methods/GetMyCommands.java | 8 +- .../telegram/core/methods/GetMyName.java | 4 +- .../telegram/core/methods/SendDice.java | 8 +- .../telegram/core/methods/SendMessage.java | 8 +- .../core/methods/SetMessageReaction.java | 8 +- .../telegram/core/methods/SetMyCommands.java | 8 +- .../core/methods/TelegramApiMethod.java | 4 + .../core/methods/TelegramApiMethodBody.java | 1 - .../telegram/core/objects/GeneralObject.java | 4 + .../hdvtdev/telegram/core/objects/Update.java | 13 +- .../core/objects/callback/CallbackQuery.java | 3 +- .../core/objects/message/Message.java | 2 +- event-handlers-annotations/build.gradle | 15 ++ .../handler/annotations/BotCommand.java | 17 ++ .../annotations/OnBusinessConnection.java | 20 ++ .../handler/annotations/OnCallbackQuery.java | 25 ++ .../annotations/OnChatBoostRemoved.java | 21 ++ .../annotations/OnChatBoostUpdated.java | 21 ++ .../annotations/OnChatJoinRequest.java | 21 ++ .../annotations/OnChatMemberUpdated.java | 21 ++ .../annotations/OnChosenInlineResult.java | 21 ++ .../handler/annotations/OnInlineQuery.java | 21 ++ .../handler/annotations/OnMessage.java | 65 +++++ .../annotations/OnPaidMediaPurchased.java | 21 ++ .../telegram/handler/annotations/OnPoll.java | 21 ++ .../handler/annotations/OnPollAnswer.java | 21 ++ .../annotations/OnPreCheckoutQuery.java | 21 ++ .../handler/annotations/OnShippingQuery.java | 21 ++ .../handler/annotations/OnUpdate.java | 23 ++ .../annotations/TelegramBotInstance.java | 15 ++ event-handlers/build.gradle | 18 ++ .../src/main/java/models/Handlers.java | 18 ++ gradlew | 234 ------------------ gradlew.bat | 89 ------- .../src/main/java/module-info.java | 3 + 56 files changed, 991 insertions(+), 604 deletions(-) create mode 100644 .idea/AndroidProjectSystem.xml create mode 100644 .idea/dictionaries/project.xml delete mode 100644 TODO/ClassFinder.java create mode 100644 annotation-processor/build.gradle create mode 100644 annotation-processor/src/main/java/EventHandlersProcessor.java create mode 100644 annotation-processor/src/main/java/Generator.java create mode 100644 annotation-processor/src/main/java/HandlerWriter.java create mode 100644 annotation-processor/src/main/java/Util.java create mode 100644 core/src/main/java/hdvtdev/telegram/core/HandlersModule.java create mode 100644 core/src/main/java/hdvtdev/telegram/core/JsonModule.java create mode 100644 core/src/main/java/hdvtdev/telegram/core/UpdateExecutor.java delete mode 100644 core/src/main/java/hdvtdev/telegram/core/UpdateHandler.java delete mode 100644 core/src/main/java/hdvtdev/telegram/core/annotaions/Jsonable.java create mode 100644 core/src/main/java/hdvtdev/telegram/core/annotations/TelegramAPI.java create mode 100644 core/src/main/java/hdvtdev/telegram/core/objects/GeneralObject.java create mode 100644 event-handlers-annotations/build.gradle create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/BotCommand.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnBusinessConnection.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnCallbackQuery.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostRemoved.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostUpdated.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatJoinRequest.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatMemberUpdated.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChosenInlineResult.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnInlineQuery.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnMessage.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPaidMediaPurchased.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPoll.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPollAnswer.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPreCheckoutQuery.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnShippingQuery.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnUpdate.java create mode 100644 event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/TelegramBotInstance.java create mode 100644 event-handlers/build.gradle create mode 100644 event-handlers/src/main/java/models/Handlers.java delete mode 100755 gradlew delete mode 100644 gradlew.bat diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml new file mode 100644 index 0000000..497b46f --- /dev/null +++ b/.idea/dictionaries/project.xml @@ -0,0 +1,7 @@ + + + + jsonable + + + \ No newline at end of file diff --git a/TODO/ClassFinder.java b/TODO/ClassFinder.java deleted file mode 100644 index cd7bfcb..0000000 --- a/TODO/ClassFinder.java +++ /dev/null @@ -1,139 +0,0 @@ -package hdvtdev.telegram.core.objects; - -import hdvtdev.telegram.annotations.handlers.CallbackQueryHandler; -import hdvtdev.telegram.annotations.handlers.TextMessageHandler; -import hdvtdev.telegram.objects.CallbackQuery; -import hdvtdev.telegram.objects.Message; -import hdvtdev.telegram.objects.Update; - -import java.io.File; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.security.CodeSource; -import java.util.*; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -public abstract class ClassFinder { - - private static final Set> annotationsToSearch = Set.of(TextMessageHandler.class, CallbackQueryHandler.class); - private static final Set> methodsArgumentType = Set.of(Message.class, Update.class, CallbackQuery.class); - - private static ErrorHandler errorHandler; - - public static Map, Map> getClasses() { - - Map, Map> allMethods = new HashMap<>(); - annotationsToSearch.forEach(annotation -> allMethods.put(annotation, new HashMap<>())); - - CodeSource codeSource = ClassFinder.class.getProtectionDomain().getCodeSource(); - if (codeSource != null) { - try { - String path = codeSource.getLocation().toURI().getPath(); - File file = new File(URLDecoder.decode(path, StandardCharsets.UTF_8)); - - if (file.isFile() && file.getName().endsWith(".jar")) { - processJar(file, allMethods); - } else if (file.isDirectory()) { - processDirectory(file, "", allMethods); - } - } catch (Exception e) { - return Map.of(); - } - } - - return Collections.unmodifiableMap(allMethods); - } - - private static void processDirectory(File directory, String packageName, Map, Map> methods) { - File[] files = directory.listFiles(); - if (files == null) return; - - for (File file : files) { - if (file.isDirectory()) { - processDirectory(file, packageName + file.getName() + ".", methods); - } else if (file.getName().endsWith(".class")) { - - String className = packageName + file.getName().replace(".class", ""); - loadClass(className, methods); - } - } - } - - private static void processJar(File jarFile, Map, Map> methods) { - try (JarFile jar = new JarFile(jarFile)) { - Enumeration entries = jar.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - if (entry.getName().endsWith(".class")) { - String className = entry.getName() - .replace("/", ".") - .replace(".class", ""); - - loadClass(className, methods); - } - } - } catch (IOException ignored) { - } - } - - public static Map, Map> localScan(Class cls) { - Map, Map> allMethods = new HashMap<>(); - annotationsToSearch.forEach(annotation -> allMethods.put(annotation, new HashMap<>())); - loadClass(cls.getName(), allMethods); - return allMethods; - } - - - private static void loadClass(String className, Map, Map> methods) { - try { - Class c = Class.forName(className); - - for (Method method : c.getDeclaredMethods()) { - - Class[] parameters = method.getParameterTypes(); - - if (parameters.length != 0 && !methodsArgumentType.contains(parameters[0])) { - continue; - } - - if (method.isAnnotationPresent(CallbackQueryHandler.class)) { - if (Modifier.isStatic(method.getModifiers())) { - for (String value : method.getAnnotation(CallbackQueryHandler.class).value()) { - methods.get(CallbackQueryHandler.class).put(value, new InvokeMethod(method, parameters[0])); - } - } else - System.err.println(method + " is annotated with @CallbackQueryHandler, but it is not static. For the annotation to work, the method must be static."); - } - - if (method.isAnnotationPresent(TextMessageHandler.class)) { - if (Modifier.isStatic(method.getModifiers())) { - for (String value : method.getAnnotation(TextMessageHandler.class).value()) { - methods.get(TextMessageHandler.class).put(value, new InvokeMethod(method, parameters[0])); - } - } else - System.err.println(method + " is annotated with @TextMessageHandler, but it is not static. For the annotation to work, the method must be static."); - } - - } - } catch (NoClassDefFoundError | UnsupportedClassVersionError | ClassNotFoundException e) { - if (errorHandler != null) errorHandler.onError(e); - } - } - - public void setErrorHandler(ErrorHandler errorHandler) { - ClassFinder.errorHandler = errorHandler; - } - - public interface ErrorHandler { - void onError(Throwable throwable); - } - - - //tod - -} diff --git a/annotation-processor/build.gradle b/annotation-processor/build.gradle new file mode 100644 index 0000000..33e4284 --- /dev/null +++ b/annotation-processor/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'java' +} + +group = 'com.github.hdvtdev' +version = '1.0.0' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'com.google.auto.service:auto-service:1.1.1' + implementation project(':core') + implementation 'org.ow2.asm:asm:9.9' + annotationProcessor 'com.google.auto.service:auto-service:1.1.1' + //implementation 'com.fasterxml.jackson.core:jackson-annotations:2.18.3' + implementation project(":event-handlers-annotations") +} + diff --git a/annotation-processor/src/main/java/EventHandlersProcessor.java b/annotation-processor/src/main/java/EventHandlersProcessor.java new file mode 100644 index 0000000..b79f941 --- /dev/null +++ b/annotation-processor/src/main/java/EventHandlersProcessor.java @@ -0,0 +1,172 @@ +import com.google.auto.service.AutoService; + +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import java.util.*; +import java.util.stream.Collectors; + + +import hdvtdev.telegram.handler.annotations.*; + +@AutoService(Processor.class) +@SupportedAnnotationTypes({ + "hdvtdev.telegram.handler.annotations.OnChosenInlineResult", + "hdvtdev.telegram.handler.annotations.OnChatMemberUpdated", + "hdvtdev.telegram.handler.annotations.OnChatBoostRemoved", + "hdvtdev.telegram.handler.annotations.OnPreCheckoutQuery", + "hdvtdev.telegram.handler.annotations.OnBusinessConnection", + "hdvtdev.telegram.handler.annotations.OnPaidMediaPurchased", + "hdvtdev.telegram.handler.annotations.OnUpdate", + "hdvtdev.telegram.handler.annotations.BotCommand", + "hdvtdev.telegram.handler.annotations.OnPoll", + "hdvtdev.telegram.handler.annotations.OnMessage", + "hdvtdev.telegram.handler.annotations.OnChatJoinRequest", + "hdvtdev.telegram.handler.annotations.OnChatBoostUpdated", + "hdvtdev.telegram.handler.annotations.OnCallbackQuery", + "hdvtdev.telegram.handler.annotations.OnShippingQuery", + "hdvtdev.telegram.handler.annotations.OnInlineQuery", + "hdvtdev.telegram.handler.annotations.OnPollAnswer"}) +@SupportedSourceVersion(SourceVersion.RELEASE_21) +public class EventHandlersProcessor extends AbstractProcessor { + + private final StringBuilder sb = new StringBuilder(); + + private static final String PACKAGE = "hdvtdev.telegram.handler.annotations."; + private static final String HANDLER_PACKAGE = "hdvtdev.telegram.handler."; + + private static final Set SUPPORTED_ANNOTATIONS = Set.of( + OnChosenInlineResult.class, + OnChatMemberUpdated.class, + OnChatBoostRemoved.class, + OnPreCheckoutQuery.class, + OnBusinessConnection.class, + OnPaidMediaPurchased.class, + OnUpdate.class, + OnPoll.class, + OnMessage.class, + OnChatJoinRequest.class, + OnChatBoostUpdated.class, + OnCallbackQuery.class, + OnShippingQuery.class, + OnInlineQuery.class, + OnPollAnswer.class + ).stream().map(Class::getName).collect(Collectors.toSet()); + + private static final Map SUPPORTED_PARAMETERS = Map.ofEntries( + Map.entry("Update", "hdvtdev.telegram.core.objects.Update"), + Map.entry("InlineQuery", "hdvtdev.telegram.core.objects.InlineQuery"), + Map.entry("ChatMemberUpdated", "hdvtdev.telegram.core.objects.chat.ChatMemberUpdated"), + Map.entry("ChatBoostRemoved", "hdvtdev.telegram.core.objects.chatboost.ChatBoostRemoved"), + Map.entry("PreCheckoutQuery", "hdvtdev.telegram.core.objects.payment.PreCheckoutQuery"), + Map.entry("BusinessConnection", "hdvtdev.telegram.core.objects.business.BusinessConnection"), + Map.entry("PaidMediaPurchased", "hdvtdev.telegram.core.objects.media.paidmedia.PaidMediaPurchased"), + Map.entry("Poll", "hdvtdev.telegram.core.objects.poll.Poll"), + Map.entry("Message", "hdvtdev.telegram.core.objects.Message"), + Map.entry("ChatJoinRequest", "hdvtdev.telegram.core.objects.chat.ChatJoinRequest"), + Map.entry("ChatBoostUpdated", "hdvtdev.telegram.core.objects.chatboost.ChatBoostUpdated"), + Map.entry("CallbackQuery", "hdvtdev.telegram.core.objects.callback.CallbackQuery"), + Map.entry("ShippingQuery", "hdvtdev.telegram.core.objects.payment.ShippingQuery"), + Map.entry("PollAnswer", "hdvtdev.telegram.core.objects.poll.PollAnswer"), + Map.entry("ChosenInlineResult", "hdvtdev.telegram.core.objects.ChosenInlineResult") + ); + + public static String getFullParameterName(String simpleName) { + return SUPPORTED_PARAMETERS.get(simpleName); + } + + private Messager messager; + + @Override + public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + messager = processingEnv.getMessager(); + } + + @Override + public boolean process(Set set, RoundEnvironment roundEnvironment) { + messager.printNote("Called"); + for (Element element : roundEnvironment.getRootElements()) { + for (Element enclosedElement : element.getEnclosedElements()) { + if (enclosedElement.getKind() == ElementKind.METHOD) { + processMethod((ExecutableElement) enclosedElement); + } + } + } + + if (roundEnvironment.processingOver()) { + write(); + } + + return true; + } + + private void write() { + + } + + private void processMethod(ExecutableElement methodElement) { + String methodName = methodElement.getSimpleName().toString(); + + List foundAnnotations = new ArrayList<>(); + for (AnnotationMirror mirror : methodElement.getAnnotationMirrors()) { + String mirrorAnnotationName = Util.getAnnotationMirrorName(mirror); + if (SUPPORTED_ANNOTATIONS.contains(PACKAGE + mirrorAnnotationName)) { + foundAnnotations.add(mirror); + } + } + + if (foundAnnotations.size() > 1) { + List annotationNames = new ArrayList<>(); + for (AnnotationMirror mirror : foundAnnotations) { + annotationNames.add("@" + Util.getAnnotationMirrorName(mirror)); + } + + messager.printError(String.format("Method %s cannot have multiple mutually exclusive annotations. Found: %s. Please leave only one.", + methodName, String.join(", ", annotationNames)), methodElement); + + return; + } + + if (foundAnnotations.size() == 1) { + AnnotationMirror annotation = foundAnnotations.getFirst(); + String annotationSimpleName = Util.getAnnotationMirrorName(annotation); + + var params = methodElement.getParameters(); + if (params.isEmpty()) { + messager.printError(String.format("Method %s, annotated with @%s, must have at least one parameter.", + methodName, annotationSimpleName), methodElement); + return; + } + + String firstParameterType = Util.getParameterClassName(params.getFirst().asType()); + String requiredParameter = Util.checkParameter(annotationSimpleName, firstParameterType); + + if (!requiredParameter.isEmpty()) { + messager.printError(String.format("Incorrect parameter type for method %s. Annotation @%s requires %s, but found %s.", + methodName, annotationSimpleName, requiredParameter, firstParameterType), params.getFirst()); + return; + } + + if (!annotationSimpleName.equals("BotCommand")) { + String paramName = params.getFirst().getSimpleName().toString(); + Set filters = new HashSet<>(); + + AnnotationValue vv = Util.getAnnotationValue(annotation, "filters"); + @SuppressWarnings("unchecked") + List enumValues = vv == null ? List.of() : (List) vv.getValue(); + for (AnnotationValue v : enumValues) { + if (v.getValue() instanceof VariableElement enumConstant) { + filters.add(enumConstant.getSimpleName().toString()); + } + } + sb.append(Generator.generateVoid(methodName, String.format("%s %s", firstParameterType, paramName), + Generator.generateFilterBlock(filters, paramName))); + } + + + + } + } + +} diff --git a/annotation-processor/src/main/java/Generator.java b/annotation-processor/src/main/java/Generator.java new file mode 100644 index 0000000..321d9b6 --- /dev/null +++ b/annotation-processor/src/main/java/Generator.java @@ -0,0 +1,42 @@ +import java.util.Set; + +public final class Generator { + + private Generator() { + + } + + public static String generateVoid(String name, String obj, String block) { + return String.format(""" + public static void %s(%s) { + %s + } + """, name, obj, block); + } + + public static String generateFilterBlock(Set filters, String objName) { + StringBuilder sb = new StringBuilder(); + for (String filter : filters) { + boolean skip = true; + sb.append("if ("); + sb.append(objName); + sb.append("."); + for (String part : filter.split("_")) { + part = part.toLowerCase(); + if (skip) { + sb.append(part); + skip = false; + } else { + char[] chars = part.toCharArray(); + chars[0] = Character.toUpperCase(chars[0]); + sb.append(chars); + } + } + sb.append("()) {"); + sb.append("\n /* some code */ \n}\n"); + + } + return sb.toString(); + } + +} diff --git a/annotation-processor/src/main/java/HandlerWriter.java b/annotation-processor/src/main/java/HandlerWriter.java new file mode 100644 index 0000000..8613f4c --- /dev/null +++ b/annotation-processor/src/main/java/HandlerWriter.java @@ -0,0 +1,108 @@ +import org.objectweb.asm.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class HandlerWriter { + + public static void write(String body) throws IOException { + + String classFilePath = "models/Handlers.class"; // Путь к вашему файлу + Path path = Paths.get(classFilePath); + + // 1. Читаем исходный класс в байты + byte[] originalBytecode = Files.readAllBytes(path); + + // 2. Инициализируем ASM + ClassReader classReader = new ClassReader(originalBytecode); + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + + // 3. Создаем наш визитор, который найдет и заменит метод + ClassVisitor classVisitor = new MethodReplacer(classWriter); + + // 4. Запускаем процесс + classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES); + + // 5. Получаем измененный байт-код + byte[] modifiedBytecode = classWriter.toByteArray(); + + // 6. Перезаписываем исходный файл + Files.write(path, modifiedBytecode); + + System.out.println("Метод invoke в файле " + classFilePath + " был успешно заменен."); + + + + } + + private static class MethodReplacer extends ClassVisitor { + + public MethodReplacer(ClassVisitor classVisitor) { + super(Opcodes.ASM9, classVisitor); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + String targetDescriptor = "(L" + EventHandlersProcessor.getFullParameterName("Update").replace('.', '/') + + ";)V"; + + if ("invoke".equals(name) && targetDescriptor.equals(descriptor)) { + System.out.println("Найден метод 'invoke'. Заменяем его тело..."); + // Найден нужный метод. Не передаем его дальше (старое тело удаляется). + // Вместо этого создаем новый MethodVisitor для генерации нового тела. + MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions); + generateNewBody(mv); + // Возвращаем null, так как мы уже создали метод через cv.visitMethod + return null; + } + + // Для всех остальных методов - просто передаем их дальше без изменений + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + + private void generateNewBody(MethodVisitor mv) { + mv.visitCode(); + + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("Hello from the new invoke method!"); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + + // Код для: Integer updateId = update.getUpdateId(); + // `update` - это первый аргумент, поэтому он в локальной переменной 1 (0 это `this`) + mv.visitVarInsn(Opcodes.ALOAD, 1); + // Предполагаем, что getUpdateId() возвращает Integer. Если он возвращает int, нужно использовать valueOf. + // Для примера, пусть он возвращает Integer. + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, EventHandlersProcessor.getFullParameterName("Update"), + "getUpdateId", + "()Ljava/lang/Long;", false); + // Сохраняем результат в локальную переменную 2 + mv.visitVarInsn(Opcodes.ASTORE, 2); + + // Код для: System.out.println("Update ID: " + updateId); + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); + // Создаем новый StringBuilder для конкатенации строк + mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); + mv.visitInsn(Opcodes.DUP); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "", "()V", false); + mv.visitLdcInsn("Update ID: "); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); + // Загружаем updateId из локальной переменной 2 + mv.visitVarInsn(Opcodes.ALOAD, 2); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuilder;", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + + + // Завершаем метод (поскольку он void, используем RETURN) + mv.visitInsn(Opcodes.RETURN); + + // Указываем максимальный размер стека и количество локальных переменных. + // ASM может вычислить это за нас, если использовать ClassWriter.COMPUTE_FRAMES + mv.visitMaxs(0, 0); // Значения игнорируются при COMPUTE_FRAMES + mv.visitEnd(); + } + } + +} diff --git a/annotation-processor/src/main/java/Util.java b/annotation-processor/src/main/java/Util.java new file mode 100644 index 0000000..d3b7597 --- /dev/null +++ b/annotation-processor/src/main/java/Util.java @@ -0,0 +1,63 @@ +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; +import java.util.Map; + +public final class Util { + + private Util() { + + } + + + + public static String checkParameter(String simpleAnnotationName, String simpleParameterName) { + String reqParameter = switch (simpleAnnotationName) { + case "OnMessage", "BotCommand" -> "Message"; + case "OnBusinessConnection" -> "BusinessConnection"; + case "OnCallbackQuery" -> "CallbackQuery"; + case "OnChatBoostRemoved" -> "ChatBoostRemoved"; + case "OnChatBoostUpdated" -> "ChatBoostUpdated"; + case "OnChatJoinRequest" -> "ChatJoinRequest"; + case "OnChatMemberUpdated" -> "ChatMemberUpdated"; + case "OnChosenInlineResult" -> "ChosenInlineResult"; + case "OnInlineQuery" -> "InlineQuery"; + case "OnPaidMediaPurchased" -> "PaidMediaPurchased"; + case "OnPoll" -> "Poll"; + case "OnPollAnswer" -> "PollAnswer"; + case "OnPreCheckoutQuery" -> "PreCheckoutQuery"; + case "OnShippingQuery" -> "ShippingQuery"; + case "OnUpdate" -> "Update"; + default -> throw new IllegalStateException("Unexpected value: " + simpleAnnotationName); + }; + return reqParameter.equals(simpleParameterName) ? "" : reqParameter; + } + + public static String getParameterClassName(TypeMirror typeMirror) { + String methodParameterName = "unknown (probably primitive type)"; + if (typeMirror instanceof DeclaredType declaredType) { + Element typeElement = declaredType.asElement(); + methodParameterName = typeElement.getSimpleName().toString(); + } + return methodParameterName; + } + + + public static String getAnnotationMirrorName(AnnotationMirror mirror) { + return mirror.getAnnotationType().asElement().getSimpleName().toString(); + } + + public static AnnotationValue getAnnotationValue(AnnotationMirror annotationMirror, String attributeName) { + Map elementValues = annotationMirror.getElementValues(); + for (Map.Entry entry : elementValues.entrySet()) { + if (entry.getKey().getSimpleName().toString().equals(attributeName)) { + return entry.getValue(); + } + } + return null; + } + +} diff --git a/core/src/main/java/hdvtdev/telegram/core/HandlersModule.java b/core/src/main/java/hdvtdev/telegram/core/HandlersModule.java new file mode 100644 index 0000000..1378d48 --- /dev/null +++ b/core/src/main/java/hdvtdev/telegram/core/HandlersModule.java @@ -0,0 +1,9 @@ +package hdvtdev.telegram.core; + +import hdvtdev.telegram.core.objects.Update; + +public interface HandlersModule { + + void dispatch(String botId, Update update); + +} diff --git a/core/src/main/java/hdvtdev/telegram/core/JsonModule.java b/core/src/main/java/hdvtdev/telegram/core/JsonModule.java new file mode 100644 index 0000000..146391b --- /dev/null +++ b/core/src/main/java/hdvtdev/telegram/core/JsonModule.java @@ -0,0 +1,8 @@ +package hdvtdev.telegram.core; + +public interface JsonModule { + + T fromJson(String json, Class type); + String toJson(Object object); + +} diff --git a/core/src/main/java/hdvtdev/telegram/core/TelegramBot.java b/core/src/main/java/hdvtdev/telegram/core/TelegramBot.java index 9085f3c..6839aab 100644 --- a/core/src/main/java/hdvtdev/telegram/core/TelegramBot.java +++ b/core/src/main/java/hdvtdev/telegram/core/TelegramBot.java @@ -21,6 +21,8 @@ public interface TelegramBot { void shutdown(); + void start(UpdateConsumer updateConsumer); + default CompletableFuture downloadFile(TelegramFile telegramFile, Path targetDirectory) { CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> awaitDownloadFile(telegramFile, targetDirectory)); completableFuture.exceptionally(e -> { diff --git a/core/src/main/java/hdvtdev/telegram/core/UpdateConsumer.java b/core/src/main/java/hdvtdev/telegram/core/UpdateConsumer.java index 6b96543..4b00ba8 100644 --- a/core/src/main/java/hdvtdev/telegram/core/UpdateConsumer.java +++ b/core/src/main/java/hdvtdev/telegram/core/UpdateConsumer.java @@ -1,23 +1,7 @@ package hdvtdev.telegram.core; -import hdvtdev.telegram.core.objects.ChosenInlineResult; -import hdvtdev.telegram.core.objects.InlineQuery; + import hdvtdev.telegram.core.objects.Update; -import hdvtdev.telegram.core.objects.business.BusinessConnection; -import hdvtdev.telegram.core.objects.business.BusinessMessagesDeleted; -import hdvtdev.telegram.core.objects.callback.CallbackQuery; -import hdvtdev.telegram.core.objects.chat.ChatJoinRequest; -import hdvtdev.telegram.core.objects.chat.ChatMemberUpdated; -import hdvtdev.telegram.core.objects.chatboost.ChatBoostRemoved; -import hdvtdev.telegram.core.objects.chatboost.ChatBoostUpdated; -import hdvtdev.telegram.core.objects.media.paidmedia.PaidMediaPurchased; -import hdvtdev.telegram.core.objects.message.Message; -import hdvtdev.telegram.core.objects.message.MessageReactionCountUpdated; -import hdvtdev.telegram.core.objects.message.MessageReactionUpdated; -import hdvtdev.telegram.core.objects.payment.PreCheckoutQuery; -import hdvtdev.telegram.core.objects.payment.ShippingQuery; -import hdvtdev.telegram.core.objects.poll.Poll; -import hdvtdev.telegram.core.objects.poll.PollAnswer; import java.util.List; @@ -25,7 +9,7 @@ public interface UpdateConsumer { - void onUpdates(List updates); + default void onUpdate(Update update) {} diff --git a/core/src/main/java/hdvtdev/telegram/core/UpdateExecutor.java b/core/src/main/java/hdvtdev/telegram/core/UpdateExecutor.java new file mode 100644 index 0000000..a19268c --- /dev/null +++ b/core/src/main/java/hdvtdev/telegram/core/UpdateExecutor.java @@ -0,0 +1,10 @@ +package hdvtdev.telegram.core; + +import hdvtdev.telegram.core.objects.Update; + +@FunctionalInterface +public interface UpdateExecutor { + + void execute(Update update); + +} diff --git a/core/src/main/java/hdvtdev/telegram/core/UpdateHandler.java b/core/src/main/java/hdvtdev/telegram/core/UpdateHandler.java deleted file mode 100644 index 00cf08c..0000000 --- a/core/src/main/java/hdvtdev/telegram/core/UpdateHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -package hdvtdev.telegram.core; - -import hdvtdev.telegram.core.objects.ChosenInlineResult; -import hdvtdev.telegram.core.objects.InlineQuery; -import hdvtdev.telegram.core.objects.Update; -import hdvtdev.telegram.core.objects.business.BusinessConnection; -import hdvtdev.telegram.core.objects.business.BusinessMessagesDeleted; -import hdvtdev.telegram.core.objects.callback.CallbackQuery; -import hdvtdev.telegram.core.objects.chat.ChatJoinRequest; -import hdvtdev.telegram.core.objects.chat.ChatMemberUpdated; -import hdvtdev.telegram.core.objects.chatboost.ChatBoostRemoved; -import hdvtdev.telegram.core.objects.chatboost.ChatBoostUpdated; -import hdvtdev.telegram.core.objects.media.paidmedia.PaidMediaPurchased; -import hdvtdev.telegram.core.objects.message.Message; -import hdvtdev.telegram.core.objects.message.MessageReactionCountUpdated; -import hdvtdev.telegram.core.objects.message.MessageReactionUpdated; -import hdvtdev.telegram.core.objects.payment.PreCheckoutQuery; -import hdvtdev.telegram.core.objects.payment.ShippingQuery; -import hdvtdev.telegram.core.objects.poll.Poll; -import hdvtdev.telegram.core.objects.poll.PollAnswer; - -import java.util.List; - -public interface UpdateHandler extends UpdateConsumer { - - @Override - default void onUpdates(List updates) { - for (Update update : updates) { - if (update.hasMessage()) onMessage(update.message()); - if (update.hasEditedMessage()) onEditedMessage(update.editedMessage()); - if (update.hasChannelPost()) onChannelPost(update.channelPost()); - if (update.hasEditedChannelPost()) onEditedChannelPost(update.editedChannelPost()); - if (update.hasBusinessConnection()) onBusinessConnection(update.businessConnection()); - if (update.hasBusinessMessage()) onBusinessMessage(update.businessMessage()); - if (update.hasEditedBusinessMessage()) onEditedBusinessMessage(update.editedBusinessMessage()); - if (update.hasDeletedBusinessMessages()) onDeletedBusinessMessages(update.businessMessagesDeleted()); - if (update.hasMessageReaction()) onMessageReaction(update.messageReaction()); - if (update.hasMessageReactionCount()) onMessageReactionCount(update.messageReactionCount()); - if (update.hasInlineQuery()) onInlineQuery(update.inlineQuery()); - if (update.hasChosenInlineResult()) onChosenInlineResult(update.chosenInlineResult()); - if (update.hasCallbackQuery()) onCallbackQuery(update.callbackQuery()); - if (update.hasShippingQuery()) onShippingQuery(update.shippingQuery()); - if (update.hasPreCheckoutQuery()) onPreCheckoutQuery(update.preCheckoutQuery()); - if (update.hasPurchasedPaidMedia()) onPaidMediaPurchased(update.paidMediaPurchased()); - if (update.hasPoll()) onPoll(update.poll()); - if (update.hasPollAnswer()) onPollAnswer(update.pollAnswer()); - if (update.hasMyChatMember()) onMyChatMember(update.myChatMember()); - if (update.hasChatMember()) onChatMember(update.chatMember()); - if (update.hasChatJoinRequest()) onChatJoinRequest(update.chatJoinRequest()); - if (update.hasChatBoost()) onChatBoost(update.chatBoost()); - if (update.hasRemovedChatBoost()) onChatBoostRemoved(update.chatBoostRemoved()); - } - } - - default void onMessage(Message message) {} - default void onEditedMessage(Message message) {} - default void onChannelPost(Message message) {} - default void onEditedChannelPost(Message message) {} - default void onBusinessConnection(BusinessConnection connection) {} - default void onBusinessMessage(Message message) {} - default void onEditedBusinessMessage(Message message) {} - default void onDeletedBusinessMessages(BusinessMessagesDeleted deleted) {} - default void onMessageReaction(MessageReactionUpdated reaction) {} - default void onMessageReactionCount(MessageReactionCountUpdated count) {} - default void onInlineQuery(InlineQuery query) {} - default void onChosenInlineResult(ChosenInlineResult result) {} - default void onCallbackQuery(CallbackQuery callbackQuery) {} - default void onShippingQuery(ShippingQuery query) {} - default void onPreCheckoutQuery(PreCheckoutQuery query) {} - default void onPaidMediaPurchased(PaidMediaPurchased paidMedia) {} - default void onPoll(Poll poll) {} - default void onPollAnswer(PollAnswer answer) {} - default void onMyChatMember(ChatMemberUpdated member) {} - default void onChatMember(ChatMemberUpdated member) {} - default void onChatJoinRequest(ChatJoinRequest request) {} - default void onChatBoost(ChatBoostUpdated boost) {} - default void onChatBoostRemoved(ChatBoostRemoved removedBoost) {} - - -} diff --git a/core/src/main/java/hdvtdev/telegram/core/annotaions/Jsonable.java b/core/src/main/java/hdvtdev/telegram/core/annotaions/Jsonable.java deleted file mode 100644 index 835b973..0000000 --- a/core/src/main/java/hdvtdev/telegram/core/annotaions/Jsonable.java +++ /dev/null @@ -1,19 +0,0 @@ -package hdvtdev.telegram.core.annotaions; - -import hdvtdev.telegram.core.methods.TelegramApiMethod; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This annotation is used to indicate {@link TelegramApiMethod} that should be serialized into JSON. - *
Last documentation update: 2025-04-05
- * @see com.fasterxml.jackson.databind.ObjectMapper - * @since 1.0.0 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface Jsonable { -} diff --git a/core/src/main/java/hdvtdev/telegram/core/annotations/TelegramAPI.java b/core/src/main/java/hdvtdev/telegram/core/annotations/TelegramAPI.java new file mode 100644 index 0000000..f856193 --- /dev/null +++ b/core/src/main/java/hdvtdev/telegram/core/annotations/TelegramAPI.java @@ -0,0 +1,9 @@ +package hdvtdev.telegram.core.annotations; + +public @interface TelegramAPI { + + String since(); + + + +} diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/ApproveChatJoinRequest.java b/core/src/main/java/hdvtdev/telegram/core/methods/ApproveChatJoinRequest.java index 8e1298a..4619cef 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/ApproveChatJoinRequest.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/ApproveChatJoinRequest.java @@ -8,7 +8,7 @@ import hdvtdev.telegram.core.objects.User; /** * Use this method to approve a chat join request. * The command must be an administrator in the chat for this to work and must have the {@link ChatAdministratorRights#canInviteUsers()} administrator right. - * Returns True on success. + * Returns {@code true} on success. * @param chatId Unique username of the target channel in the format @channelusername * @param userId Unique identifier of the target user * @see ChatAdministratorRights @@ -17,6 +17,7 @@ import hdvtdev.telegram.core.objects.User; * @since 0.1.0 */ //TODO NotTested + public record ApproveChatJoinRequest(String chatId, long userId) implements TelegramApiMethod { /** diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessage.java b/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessage.java index 172fd38..838d015 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessage.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessage.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.methods.util.ParseMode; import hdvtdev.telegram.core.objects.message.MessageEntity; import hdvtdev.telegram.core.objects.poll.Poll; @@ -24,7 +23,6 @@ import java.util.List; * @since 1.0.0 */ //TODO NotTested -@Jsonable @JsonInclude(JsonInclude.Include.NON_NULL) public final class CopyMessage implements TelegramApiMethod { @@ -136,6 +134,12 @@ public final class CopyMessage implements TelegramApiMethod { this.replyMarkup = replyMarkup; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } + @JsonIgnore @Override public TelegramApiMethodBody getBody() { diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessages.java b/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessages.java index 36d3e1a..0a013d7 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessages.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/CopyMessages.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.objects.poll.Poll; import java.util.ArrayList; @@ -21,7 +20,7 @@ import java.util.List; * @see Poll#correctOptionId() * @since 1.0.0 */ -@Jsonable + @JsonInclude(JsonInclude.Include.NON_NULL) public final class CopyMessages implements TelegramApiMethod { @@ -124,6 +123,12 @@ public final class CopyMessages implements TelegramApiMethod { return Long[].class; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } + public static final class Builder { private final String chatId; private Long messageThreadId; diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessage.java b/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessage.java index 2b7622f..f6dcf12 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessage.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessage.java @@ -4,16 +4,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.objects.message.Message; - /** * Use this method to forward message of any kind. * Service message and message with protected content can't be forwarded. * On success, the sent {@link Message} is returned. */ -@Jsonable + @JsonInclude(JsonInclude.Include.NON_NULL) public final class ForwardMessage implements TelegramApiMethod { @@ -90,6 +88,12 @@ public final class ForwardMessage implements TelegramApiMethod { return Message.class; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } + public static final class Builder { private final String chatId; private Long messageThreadId; diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessages.java b/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessages.java index d369ca1..43bb62e 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessages.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/ForwardMessages.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.objects.message.Message; import java.util.ArrayList; @@ -17,7 +16,6 @@ import java.util.List; * @see Message#hasProtectedContent() */ // TODO NotTested -@Jsonable @JsonInclude(JsonInclude.Include.NON_NULL) public final class ForwardMessages implements TelegramApiMethod { @@ -93,6 +91,11 @@ public final class ForwardMessages implements TelegramApiMethod { return Long[].class; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } public static final class Builder { private final String chatId; diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/GetMyCommands.java b/core/src/main/java/hdvtdev/telegram/core/methods/GetMyCommands.java index 1c04bd2..cf472a7 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/GetMyCommands.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/GetMyCommands.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.objects.command.BotCommand; import hdvtdev.telegram.core.objects.command.BotCommandScope; import hdvtdev.telegram.core.objects.command.BotCommandScopeDefault; @@ -17,7 +16,6 @@ import hdvtdev.telegram.core.objects.command.BotCommandScopeDefault; * @see BotCommandScope * @since 1.0.0 */ -@Jsonable @JsonInclude(JsonInclude.Include.NON_NULL) public record GetMyCommands( @JsonProperty("scope") BotCommandScope scope, @@ -53,4 +51,10 @@ public record GetMyCommands( public Class getResponseClass() { return BotCommand[].class; } + + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } } diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/GetMyName.java b/core/src/main/java/hdvtdev/telegram/core/methods/GetMyName.java index cf16657..07e1632 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/GetMyName.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/GetMyName.java @@ -1,5 +1,7 @@ package hdvtdev.telegram.core.methods; +import org.jetbrains.annotations.NotNull; + public record GetMyName(String languageCode) implements TelegramApiMethod { public GetMyName() { @@ -30,7 +32,7 @@ public record GetMyName(String languageCode) implements TelegramApiMethod { @@ -106,6 +104,12 @@ public final class SendDice implements TelegramApiMethod { return Message.class; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } + public enum Emoji { DICE("🎲"), DART("🎯"), diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/SendMessage.java b/core/src/main/java/hdvtdev/telegram/core/methods/SendMessage.java index ac8ddf0..78c5f4b 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/SendMessage.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/SendMessage.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.methods.util.ParseMode; import hdvtdev.telegram.core.objects.*; import hdvtdev.telegram.core.objects.markup.ReplyMarkup; @@ -13,7 +12,6 @@ import hdvtdev.telegram.core.objects.message.Message; import hdvtdev.telegram.core.objects.message.MessageEntity; -@Jsonable @JsonInclude(JsonInclude.Include.NON_NULL) public final class SendMessage implements TelegramApiMethod { @@ -137,6 +135,12 @@ public final class SendMessage implements TelegramApiMethod { return Message.class; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } + public static final class Builder { private final String chatId; private final String text; diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/SetMessageReaction.java b/core/src/main/java/hdvtdev/telegram/core/methods/SetMessageReaction.java index 1d15539..5e5fbb8 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/SetMessageReaction.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/SetMessageReaction.java @@ -4,12 +4,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.objects.reaction.ReactionType; import java.util.List; -@Jsonable @JsonInclude(JsonInclude.Include.NON_NULL) public class SetMessageReaction implements TelegramApiMethod { @@ -65,6 +63,12 @@ public class SetMessageReaction implements TelegramApiMethod { return Boolean.class; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } + public static final class Builder { private final String chatId; private final long messageId; diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/SetMyCommands.java b/core/src/main/java/hdvtdev/telegram/core/methods/SetMyCommands.java index c073a7c..46a66d3 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/SetMyCommands.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/SetMyCommands.java @@ -4,13 +4,11 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import hdvtdev.telegram.core.annotaions.Jsonable; import hdvtdev.telegram.core.objects.command.BotCommand; import hdvtdev.telegram.core.objects.command.BotCommandScope; import java.util.List; -@Jsonable @JsonInclude(JsonInclude.Include.NON_NULL) public final class SetMyCommands implements TelegramApiMethod { @@ -68,6 +66,12 @@ public final class SetMyCommands implements TelegramApiMethod { return Boolean.class; } + @JsonIgnore + @Override + public boolean isJsonable() { + return true; + } + public static final class Builder { private final List commands; diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethod.java b/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethod.java index 8f4e8f4..0bbbc40 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethod.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethod.java @@ -8,4 +8,8 @@ public interface TelegramApiMethod { Class getResponseClass(); + default boolean isJsonable() { + return false; + } + } diff --git a/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethodBody.java b/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethodBody.java index 804eea5..c09b460 100644 --- a/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethodBody.java +++ b/core/src/main/java/hdvtdev/telegram/core/methods/TelegramApiMethodBody.java @@ -1,7 +1,6 @@ package hdvtdev.telegram.core.methods; import java.util.ArrayList; -import java.util.function.Consumer; public final class TelegramApiMethodBody { diff --git a/core/src/main/java/hdvtdev/telegram/core/objects/GeneralObject.java b/core/src/main/java/hdvtdev/telegram/core/objects/GeneralObject.java new file mode 100644 index 0000000..7d0cb66 --- /dev/null +++ b/core/src/main/java/hdvtdev/telegram/core/objects/GeneralObject.java @@ -0,0 +1,4 @@ +package hdvtdev.telegram.core.objects; + +public interface GeneralObject { +} diff --git a/core/src/main/java/hdvtdev/telegram/core/objects/Update.java b/core/src/main/java/hdvtdev/telegram/core/objects/Update.java index 442909d..0c3314b 100644 --- a/core/src/main/java/hdvtdev/telegram/core/objects/Update.java +++ b/core/src/main/java/hdvtdev/telegram/core/objects/Update.java @@ -3,6 +3,7 @@ package hdvtdev.telegram.core.objects; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; + import hdvtdev.telegram.core.objects.business.BusinessConnection; import hdvtdev.telegram.core.objects.business.BusinessMessagesDeleted; import hdvtdev.telegram.core.objects.callback.CallbackQuery; @@ -19,6 +20,9 @@ import hdvtdev.telegram.core.objects.payment.ShippingQuery; import hdvtdev.telegram.core.objects.poll.Poll; import hdvtdev.telegram.core.objects.poll.PollAnswer; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; + import java.util.Optional; @JsonInclude(JsonInclude.Include.NON_NULL) @@ -48,8 +52,15 @@ public record Update( @JsonProperty("chat_join_request") ChatJoinRequest chatJoinRequest, @JsonProperty("chat_boost") ChatBoostUpdated chatBoost, @JsonProperty("removed_chat_boost") ChatBoostRemoved chatBoostRemoved -) { +) implements GeneralObject { + @Override + @Nullable + public Message message() { + return message; + } + + @Contract(pure = true) public boolean hasMessage() { return this.message != null; } diff --git a/core/src/main/java/hdvtdev/telegram/core/objects/callback/CallbackQuery.java b/core/src/main/java/hdvtdev/telegram/core/objects/callback/CallbackQuery.java index efd8a83..1781e77 100644 --- a/core/src/main/java/hdvtdev/telegram/core/objects/callback/CallbackQuery.java +++ b/core/src/main/java/hdvtdev/telegram/core/objects/callback/CallbackQuery.java @@ -3,6 +3,7 @@ package hdvtdev.telegram.core.objects.callback; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import hdvtdev.telegram.core.objects.GeneralObject; import hdvtdev.telegram.core.objects.User; import hdvtdev.telegram.core.objects.message.MaybeInaccessibleMessage; @@ -16,7 +17,7 @@ public record CallbackQuery( @JsonProperty("chat_instance") String chatInstance, @JsonProperty("data") String data, @JsonProperty("game_short_name") String gameShortName -) { +) implements GeneralObject { public boolean hasMessage() { return this.message != null; diff --git a/core/src/main/java/hdvtdev/telegram/core/objects/message/Message.java b/core/src/main/java/hdvtdev/telegram/core/objects/message/Message.java index 476f236..b290872 100644 --- a/core/src/main/java/hdvtdev/telegram/core/objects/message/Message.java +++ b/core/src/main/java/hdvtdev/telegram/core/objects/message/Message.java @@ -113,7 +113,7 @@ public record Message( @JsonProperty("web_app_data") WebAppData webAppData, @JsonProperty("reply_markup") InlineKeyboardMarkup inlineKeyboardMarkup -) implements MaybeInaccessibleMessage { +) implements MaybeInaccessibleMessage, GeneralObject { public boolean hasMessageThreadId() { return messageThreadId != null; diff --git a/event-handlers-annotations/build.gradle b/event-handlers-annotations/build.gradle new file mode 100644 index 0000000..a308f13 --- /dev/null +++ b/event-handlers-annotations/build.gradle @@ -0,0 +1,15 @@ +plugins { + id 'java' +} + +group = 'com.github.hdvtdev' +version = '1.0.0' + +repositories { + mavenCentral() +} + +dependencies { + +} + diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/BotCommand.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/BotCommand.java new file mode 100644 index 0000000..168d187 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/BotCommand.java @@ -0,0 +1,17 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface BotCommand { + + String name() default ""; + String description(); + + String botId() default "primary"; + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnBusinessConnection.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnBusinessConnection.java new file mode 100644 index 0000000..d1152ab --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnBusinessConnection.java @@ -0,0 +1,20 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface OnBusinessConnection { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnCallbackQuery.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnCallbackQuery.java new file mode 100644 index 0000000..aa1a096 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnCallbackQuery.java @@ -0,0 +1,25 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnCallbackQuery { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + HAS_MESSAGE, + HAS_INLINE_MESSAGE_ID, + HAS_CHAT_INSTANCE, + HAS_DATA, + HAS_GAME_SHORT_NAME + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostRemoved.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostRemoved.java new file mode 100644 index 0000000..3f05bdd --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostRemoved.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnChatBoostRemoved { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostUpdated.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostUpdated.java new file mode 100644 index 0000000..e8b659e --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatBoostUpdated.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnChatBoostUpdated { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatJoinRequest.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatJoinRequest.java new file mode 100644 index 0000000..94fc7d0 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatJoinRequest.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnChatJoinRequest { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatMemberUpdated.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatMemberUpdated.java new file mode 100644 index 0000000..95105d4 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChatMemberUpdated.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnChatMemberUpdated { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChosenInlineResult.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChosenInlineResult.java new file mode 100644 index 0000000..9ea6a0a --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnChosenInlineResult.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnChosenInlineResult { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnInlineQuery.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnInlineQuery.java new file mode 100644 index 0000000..24587da --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnInlineQuery.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnInlineQuery { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnMessage.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnMessage.java new file mode 100644 index 0000000..034f846 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnMessage.java @@ -0,0 +1,65 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface OnMessage { + + String botId() default "primary"; + + + Filter[] filters() default {}; + enum Filter { + HAS_MESSAGE_THREAD_ID, + HAS_SENDER_CHAT, + HAS_SENDER_BOOST_COUNT, + HAS_SENDER_BUSINESS_BOT, + HAS_BUSINESS_CONNECTION_ID, + HAS_FORWARD_ORIGIN, + HAS_REPLY_TO_MESSAGE, + HAS_EXTERNAL_REPLY, + HAS_QUOTE, + HAS_REPLY_TO_STORY, + HAS_VIA_BOT, + HAS_EDIT_DATE, + HAS_MEDIA_GROUP_ID, + HAS_AUTHOR_SIGNATURE, + HAS_TEXT, + HAS_ENTITIES, + HAS_LINK_PREVIEW_OPTIONS, + HAS_EFFECT_ID, + HAS_ANIMATION, + HAS_AUDIO, + HAS_DOCUMENT, + HAS_PAID_MEDIA_INFO, + HAS_PHOTO, + HAS_STICKER, + HAS_STORY, + HAS_VIDEO, + HAS_VIDEO_NOTE, + HAS_VOICE, + HAS_CAPTION, + HAS_CAPTION_ENTITIES, + HAS_CONTACT, + HAS_DICE, + HAS_GAME, + HAS_POLL, + HAS_VENUE, + HAS_LOCATION, + HAS_NEW_CHAT_MEMBERS, + HAS_LEFT_CHAT_MEMBER, + HAS_NEW_CHAT_TITLE, + HAS_NEW_CHAT_PHOTO, + HAS_MESSAGE_AUTO_DELETE_TIMER_CHANGED, + HAS_MIGRATE_TO_CHAT_ID, + HAS_MIGRATE_FROM_CHAT_ID + + } + + + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPaidMediaPurchased.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPaidMediaPurchased.java new file mode 100644 index 0000000..cac1ec0 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPaidMediaPurchased.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnPaidMediaPurchased { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPoll.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPoll.java new file mode 100644 index 0000000..29c428c --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPoll.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnPoll { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPollAnswer.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPollAnswer.java new file mode 100644 index 0000000..b591484 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPollAnswer.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnPollAnswer { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPreCheckoutQuery.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPreCheckoutQuery.java new file mode 100644 index 0000000..4dabc0f --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnPreCheckoutQuery.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnPreCheckoutQuery { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnShippingQuery.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnShippingQuery.java new file mode 100644 index 0000000..0d4a276 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnShippingQuery.java @@ -0,0 +1,21 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface OnShippingQuery { + + String botId() default "primary"; + + + Filter[] filters() default {}; + + enum Filter { + + } + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnUpdate.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnUpdate.java new file mode 100644 index 0000000..44c16c1 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/OnUpdate.java @@ -0,0 +1,23 @@ +package hdvtdev.telegram.handler.annotations; + + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface OnUpdate { + + String botId() default "primary"; + + Filter[] filters() default {}; + + enum Filter { + + } + + +} diff --git a/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/TelegramBotInstance.java b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/TelegramBotInstance.java new file mode 100644 index 0000000..7f2e201 --- /dev/null +++ b/event-handlers-annotations/src/main/java/hdvtdev/telegram/handler/annotations/TelegramBotInstance.java @@ -0,0 +1,15 @@ +package hdvtdev.telegram.handler.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.FIELD) +public @interface TelegramBotInstance { + String id() default "primary"; + + boolean primary(); + +} diff --git a/event-handlers/build.gradle b/event-handlers/build.gradle new file mode 100644 index 0000000..19c8134 --- /dev/null +++ b/event-handlers/build.gradle @@ -0,0 +1,18 @@ +plugins { + id 'java' +} + +group = 'hdvtdev' +version = '1.0.0' + +repositories { + mavenCentral() +} + +dependencies { + implementation project(':core') + //annotationProcessor 'com.fasterxml.jackson.core:jackson-annotations:2.18.3' + annotationProcessor project(':annotation-processor') + implementation project(":event-handlers-annotations") + implementation 'org.jetbrains:annotations:26.0.2-1' +} diff --git a/event-handlers/src/main/java/models/Handlers.java b/event-handlers/src/main/java/models/Handlers.java new file mode 100644 index 0000000..aa80e2c --- /dev/null +++ b/event-handlers/src/main/java/models/Handlers.java @@ -0,0 +1,18 @@ +package models; + +import hdvtdev.telegram.core.HandlersModule; +import hdvtdev.telegram.core.objects.Update; + +public final class Handlers implements HandlersModule { + + private Handlers() { + } + + + @Override + public void dispatch(String botId, Update update) { + + } + + +} diff --git a/gradlew b/gradlew deleted file mode 100755 index 1b6c787..0000000 --- a/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index ac1b06f..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/longpolling-okhttp/src/main/java/module-info.java b/longpolling-okhttp/src/main/java/module-info.java index e7df579..cbacbe1 100644 --- a/longpolling-okhttp/src/main/java/module-info.java +++ b/longpolling-okhttp/src/main/java/module-info.java @@ -2,5 +2,8 @@ module longpolling.okhttp { exports hdvtdev.telegram.longpolling.okhttp; requires core; requires okhttp3; + requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.databind; + + }