Compare commits

...

24 Commits

Author SHA1 Message Date
hdvt
a9742134b2 backup 2025-11-13 23:51:01 +03:00
hdvt
a8b772a5ea Merge remote-tracking branch 'origin/master' 2025-11-04 01:58:18 +03:00
hdvt
ca295b66f9 readme 2025-11-04 01:57:41 +03:00
hdvt
9fdfd91e1d Update README.md 2025-11-04 01:52:55 +03:00
hdvt
7607ec4205 Update README.md 2025-11-04 01:52:38 +03:00
hdvt
b8615d3b90 migration 2025-11-03 21:20:12 +03:00
hdvt
15f77a945a migration 2025-11-03 21:17:46 +03:00
hdvt
d80d4e3b94 migration 2025-11-03 21:16:02 +03:00
hdvt
6093465f0d todo 2025-09-06 14:26:37 +03:00
hdvt
92aa5cd951 todo 2025-09-06 14:25:41 +03:00
Hadvart
f67cbf2df1 Merge pull request #6 from hdvtdev/dev
Dev
2025-04-24 23:15:37 +03:00
hdvtdev
66d2172f51 some refactoring 2025-04-24 23:14:43 +03:00
hdvtdev
97e93f7feb some refactoring 2025-04-24 21:57:53 +03:00
hdvtdev
5fe53b2539 some refactoring 2025-04-24 20:59:49 +03:00
hdvtdev
ab43f9cb52 Merge remote-tracking branch 'origin/dev' into dev 2025-04-22 12:37:28 +03:00
hdvtdev
111eafdc0a some refactoring 2025-04-22 12:37:13 +03:00
hdvtdev
7b66404e3e some refactoring 2025-04-22 12:36:22 +03:00
Hadvart
a936b9d560 Merge pull request #5 from hdvtdev/dev
dev
2025-04-19 20:24:03 +03:00
Hadvart
cb87ea0eee Merge branch 'master' into dev 2025-04-19 20:23:56 +03:00
Hadvart
3c62306a93 Update README.md 2025-04-08 22:07:51 +03:00
Hadvart
e80de4eab7 Update README.md 2025-04-08 22:06:51 +03:00
Hadvart
dc877fa97e Merge pull request #3
dev
2025-04-07 00:26:05 +03:00
Hadvart
9d3f7e74ef Merge pull request #2 from hdvtdev/dev
in dev
2025-04-05 19:14:03 +03:00
Hadvart
00ada710ac Merge pull request #1 from hdvtdev/dev
hdvtdev
2025-04-04 22:57:57 +03:00
422 changed files with 1849 additions and 9361 deletions

6
.gitignore vendored
View File

@@ -40,4 +40,8 @@ bin/
### Mac OS ###
.DS_Store
/src/main/java/hdvtdev/telegram/Count.java
/core/src/main/java/hdvtdev/telegram/Count.java
/src/
/test/
/.idea/
/gradle/

6
.idea/AndroidProjectSystem.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

7
.idea/dictionaries/project.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="project">
<words>
<w>jsonable</w>
</words>
</dictionary>
</component>

6
.idea/gradle.xml generated
View File

@@ -8,6 +8,12 @@
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/annotation-processor" />
<option value="$PROJECT_DIR$/core" />
<option value="$PROJECT_DIR$/event-handlers" />
<option value="$PROJECT_DIR$/event-handlers-annotations" />
<option value="$PROJECT_DIR$/longpolling-okhttp" />
<option value="$PROJECT_DIR$/test" />
</set>
</option>
</GradleProjectSettings>

1
.idea/misc.xml generated
View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">

145
README.md
View File

@@ -1,14 +1,143 @@
### English Version
# TeleJ
An elegant Java library for creating Telegram bots, featuring a framework module to reduce boilerplate and speed up development.
## ⚠️ Project Status ⚠️
**This project is currently under active development.** APIs may change, and features are still being added. It is not yet recommended for production use.
## About The Project
TeleJ is a library designed to simplify and accelerate the process of creating Telegram bots in Java. It provides a convenient API and a modular structure that helps you focus on your bot's logic rather than on repetitive code.
## Key Features
* **Simple Setup:** Get started with your bot quickly.
* **Modular Architecture:** Includes a `core` module, an `event-handlers` framework module, and other components that can be included as needed.
* **Modern Approach:** Utilizes modern Java features to create clean and readable code.
* **Extensible:** Easily extendable to add custom functionality.
### Usage Example
Below is a simple example of how to create and run a bot using TeleJ.
```java
public class MyAwesomeBot {
private static final TelegramBot telegramBot = new OkHttpTelegramBot("token");
public static void main(String[] args) {
telegramBot.start(new UpdateConsumer() {
@Override
public void onUpdate(Update update) {
if (update.hasMessage()) {
Message message = update.message();
if (message.hasText()) {
if (message.text().equalsIgnoreCase("ping!")) {
telegramBot.execute(new SendMessage.Builder(
message.chatId(), "pong!").replyToMessage(message.messageId())
.build());
}
}
}
}
});
}
}
```
## Project Structure
The project consists of several modules:
* `core`: The core of the library with all the basic functions for interacting with the Telegram Bot API.
* `event-handlers`: A framework module designed to reduce boilerplate and speed up development by simplifying the handling of events and updates from Telegram.
* `annotation-processor`: An annotation processor to simplify code writing.
* `longpolling-okhttp`: An implementation for receiving updates via Long Polling using OkHttp.
## License
This project is distributed under the MIT License.
***
### Русская версия
# TeleJ
Изящная библиотека на Java для создания ботов в Telegram, с модулем фреймворка для ускорения разработки и уменьшения количества шаблонного кода.
## ⚠️ Статус проекта ⚠️
**Этот проект находится в стадии активной разработки.** API может изменяться, а новые функции все еще добавляются. Пока не рекомендуется использовать его в продакшене.
## О проекте
TeleJ — это библиотека, разработанная для упрощения и ускорения процесса создания ботов для Telegram на языке Java. Она предоставляет удобный API и модульную структуру, которая помогает сосредоточиться на логике вашего бота, а не на повторяющемся коде.
## Основные возможности
* **Простая настройка:** Быстрое начало работы с вашим ботом.
* **Модульная архитектура:** Включает основной модуль (`core`), модуль фреймворка (`event-handlers`) и другие компоненты, которые можно подключать по мере необходимости.
* **Современный подход:** Использует современные возможности Java для создания чистого и читаемого кода.
* **Расширяемость:** Легко расширяется для добавления пользовательского функционала.
### Пример использования
Total lines of code:
<span style="background-color: blue; color: white; padding: 2px 4px;">02 April 2025 20:52:22 3472</span>
Ниже приведен простой пример того, как создать и запустить бота с использованием TeleJ.
<p>
<span style="background-color: blue; color: white; padding: 2px 4px;">08 April 2025 22:05:30 code: 3440 docs: 0</span>
<p>
```java
public class MyAwesomeBot {
<p>
<span style="background-color: blue; color: white; padding: 2px 4px;">08 April 2025 22:07:16 code: 6094 docs: 173</span>
<p>
private static final TelegramBot telegramBot = new OkHttpTelegramBot("token");
public static void main(String[] args) {
telegramBot.start(new UpdateConsumer() {
@Override
public void onUpdate(Update update) {
if (update.hasMessage()) {
Message message = update.message();
if (message.hasText()) {
if (message.text().equalsIgnoreCase("ping!")) {
telegramBot.execute(new SendMessage.Builder(
message.chatId(), "pong!").replyToMessage(message.messageId())
.build());
}
}
}
}
});
}
}
```
## Структура проекта
Проект состоит из нескольких модулей:
* `core`: Ядро библиотеки со всеми основными функциями для взаимодействия с Telegram Bot API.
* `event-handlers`: Модуль фреймворка, предназначенный для уменьшения бойлерплейта (шаблонного кода) и ускорения разработки за счет упрощения обработки событий и обновлений от Telegram.
* `annotation-processor`: Обработчик аннотаций для упрощения написания кода.
* `longpolling-okhttp`: Реализация получения обновлений через Long Polling с использованием OkHttp.
## Лицензия
Этот проект распространяется под лицензией MIT License.

View File

@@ -1,136 +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<Class<? extends Annotation>> annotationsToSearch = Set.of(TextMessageHandler.class, CallbackQueryHandler.class);
private static final Set<Class<?>> methodsArgumentType = Set.of(Message.class, Update.class, CallbackQuery.class);
private static ErrorHandler errorHandler;
public static Map<Class<?>, Map<String, InvokeMethod>> getClasses() {
Map<Class<?>, Map<String, InvokeMethod>> 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<Class<?>, Map<String, InvokeMethod>> 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<Class<?>, Map<String, InvokeMethod>> methods) {
try (JarFile jar = new JarFile(jarFile)) {
Enumeration<JarEntry> 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<Class<?>, Map<String, InvokeMethod>> localScan(Class<?> cls) {
Map<Class<?>, Map<String, InvokeMethod>> allMethods = new HashMap<>();
annotationsToSearch.forEach(annotation -> allMethods.put(annotation, new HashMap<>()));
loadClass(cls.getName(), allMethods);
return allMethods;
}
private static void loadClass(String className, Map<Class<?>, Map<String, InvokeMethod>> 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);
}
}

View File

@@ -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")
}

View File

@@ -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<String> 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<String, String> 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<? extends TypeElement> 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<AnnotationMirror> 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<String> 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<String> filters = new HashSet<>();
AnnotationValue vv = Util.getAnnotationValue(annotation, "filters");
@SuppressWarnings("unchecked")
List<? extends AnnotationValue> enumValues = vv == null ? List.of() : (List<? extends AnnotationValue>) 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)));
}
}
}
}

View File

@@ -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<String> 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();
}
}

View File

@@ -0,0 +1,112 @@
import org.objectweb.asm.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class HandlerWriter {
public static void write(String body) throws IOException {
Consumer<String> consumer = (String s) -> {};
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", "<init>", "()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();
}
}
}

View File

@@ -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<? extends ExecutableElement, ? extends AnnotationValue> elementValues = annotationMirror.getElementValues();
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : elementValues.entrySet()) {
if (entry.getKey().getSimpleName().toString().equals(attributeName)) {
return entry.getValue();
}
}
return null;
}
}

View File

@@ -1,5 +1,6 @@
plugins {
id 'java'
id 'application'
}
group = 'com.github.hdvtdev'
@@ -10,18 +11,26 @@ repositories {
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.3'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation(project(":core"))
annotationProcessor(project(":annotation-processor"))
implementation(project(":longpolling-okhttp"))
implementation(project(":event-handlers"))
implementation(project(":event-handlers-annotations"))
}
jar {
application {
mainClass = "Main"
}
manifest {
attributes(
'Main-Class': 'hdvtdev.telegram.Main'
)
}
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
tasks.register('fat', Jar) {
archiveClassifier.set('all')
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from sourceSets.main.output
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}

View File

@@ -5,15 +5,18 @@ plugins {
group = 'com.github.hdvtdev'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.3'
implementation platform('com.fasterxml.jackson:jackson-bom:2.18.3')
implementation 'com.fasterxml.jackson.core:jackson-core'
implementation 'com.fasterxml.jackson.core:jackson-annotations'
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'org.jetbrains:annotations:26.0.2-1'
}
jar {
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

View File

@@ -1,55 +0,0 @@
package hdvtdev.telegram;
import com.fasterxml.jackson.databind.ObjectMapper;
import hdvtdev.telegram.annotations.handlers.TextMessageHandler;
import hdvtdev.telegram.core.OkHttpTelegramBot;
import hdvtdev.telegram.core.TelegramBot;
import hdvtdev.telegram.core.UpdateConsumer;
import hdvtdev.telegram.exceptions.TelegramApiException;
import hdvtdev.telegram.methods.*;
import hdvtdev.telegram.objects.*;
import hdvtdev.telegram.util.ClassFinder;
import java.util.Arrays;
import java.util.List;
public class Main {
private static String apiKey;
private static long idd = 2027845508;
public static TelegramBot bot;
@TextMessageHandler("пинг")
private static void ping(Message message) {
bot.execute(new SendMessage(message.chatId(), String.valueOf(bot.getPing())));
}
public static void main(String[] args) throws Exception {
bot = new OkHttpTelegramBot.Builder(args[0]).enableHandlers(true).build();
bot.enableDefaultUpdateConsumer();
apiKey = args[2];
}
private static class Upd implements UpdateConsumer, ClassFinder.ErrorHandler {
@Override
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
@Override
public void getUpdates(List<Update> updates) {
updates.forEach(System.out::println);
}
}
}

View File

@@ -1,58 +0,0 @@
package hdvtdev.telegram.annotations.handlers;
import hdvtdev.telegram.objects.CallbackQuery;
import hdvtdev.telegram.objects.Update;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a static method as a handler for {@link CallbackQuery} updates with specific data values.
* <p>
* If {@code value} is set to "*", the method will handle all {@link CallbackQuery} data,
* and other {@code @CallbackQueryHandler} methods will be ignored.
* <p>
* The annotated method must be {@code static} and may accept:
* <ul>
* <li>{@link Void} {@code (no params)}</li>
* <li>{@link Update}</li>
* <li>{@link CallbackQuery}</li>
* </ul>
* Only one parameter is allowed.
* <p>
* You do not need to call {@link CallbackQuery#hasData()} or {@link Update#hasCallbackQuery()},
* as these checks are performed automatically before invocation.
*
* <h3>Usage example:</h3>
* <pre><code>
* {@code @CallbackQueryHandler({"stop",} "shutdown"})
* private static void stop(CallbackQuery callbackQuery) {
* long id = callbackQuery.message.chatId;
* if (DatabaseManager.isAdmin(id)) {
* bot.awaitExecute(new SendMessage(id, "Shutting down..."));
* System.exit(0);
* }
* }
* </code></pre>
* <h5>Last documentation update: 2025-04-05</h5>
* @see Update
* @see CallbackQuery
* @since 1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CallbackQueryHandler {
/**
* Values to match against {@link CallbackQuery#data()}.
* If set to "*", this method will handle all {@link CallbackQuery} updates,
* overriding any other {@code @CallbackQueryHandler} annotations.
*
* @return array of matching strings
*/
@NotNull String[] value() default "*";
}

View File

@@ -1,61 +0,0 @@
package hdvtdev.telegram.annotations.handlers;
import hdvtdev.telegram.objects.Message;
import hdvtdev.telegram.objects.Update;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a static method as a handler for {@link Message} updates with specific data values.
* <p>
* If {@code value} is set to "*", the method will handle all {@link Message} text,
* and other {@code @TextMessageHandler} methods will be ignored.
* <p>
* The annotated method must be {@code static} and may accept:
* <ul>
* <li>{@link Void} {@code (no params)}</li>
* <li>{@link Update}</li>
* <li>{@link Message}</li>
* </ul>
* Only one parameter is allowed.
* <p>
* You do not need to call {@link Message#hasText()} or {@link Update#hasMessage()},
* as these checks are performed automatically before invocation.
*
* <h3>Usage example:</h3>
* <pre><code>
* {@code @TextMessageHandler}({"rock", "paper", "scissors"})
* private static void cheaterRockPaperScissors(Message message) {
* bot.execute(new SendMessage(message.chatId(), switch(message.text()) {
* case "rock" -> "paper";
* case "paper" -> "scissors";
* default -> "rock";
* }));
*
* {@code @TextMessageHandler}("/ping")
* private static void ping(Message message) {
* bot.execute(new SendMessage(message.chatId(), String.valueOf(bot.getPing())));
* }
* </code></pre>
* <h5>Last documentation update: 2025-04-05</h5>
* @see Update
* @see Message
* @since 1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TextMessageHandler {
/**
* Values to match against {@link Message#text()}.
* If set to "*", this method will handle all {@link Message} updates,
* overriding any other {@code @TextMessageHandler} annotations.
*
* @return array of matching strings
*/
@NotNull String[] value() default "*";
}

View File

@@ -1,19 +0,0 @@
package hdvtdev.telegram.annotations.util;
import hdvtdev.telegram.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.
* <h5>Last documentation update: 2025-04-05</h5>
* @see com.fasterxml.jackson.databind.ObjectMapper
* @since 1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Jsonable {
}

View File

@@ -1,18 +0,0 @@
package hdvtdev.telegram.annotations.util;
import hdvtdev.telegram.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 is not tested, usually used if the method was created recently.
* @since 1.0.0
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface NotTested {
}

View File

@@ -0,0 +1,9 @@
package hdvtdev.telegram.core;
import hdvtdev.telegram.core.objects.Update;
public interface HandlersModule {
void dispatch(String botId, Update update);
}

View File

@@ -1,7 +0,0 @@
package hdvtdev.telegram.core.objects;
import java.lang.reflect.Method;
public record InvokeMethod(Method method, Class<?> parameterType) {
}

View File

@@ -0,0 +1,8 @@
package hdvtdev.telegram.core;
public interface JsonModule {
<T> T fromJson(String json, Class<T> type);
String toJson(Object object);
}

View File

@@ -1,52 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.handlers.TextMessageHandler;
import hdvtdev.telegram.longpolling
import hdvtdev.telegram.core.TelegramBot;
import hdvtdev.telegram.core.UpdateConsumer;
import hdvtdev.telegram.methods.*;
import hdvtdev.telegram.objects.*;
import hdvtdev.telegram.util.ClassFinder;
import java.util.List;
public class Main {
private static String apiKey;
private static long idd = 2027845508;
public static TelegramBot bot;
@TextMessageHandler("пинг")
private static void ping(Message message) {
bot.execute(new SendMessage(message.chatId(), String.valueOf(bot.getPing())));
}
public static void main(String[] args) throws Exception {
bot = new OkHttpTelegramBot.Builder(args[0]).enableHandlers(true).build();
bot.enableDefaultUpdateConsumer();
apiKey = args[2];
}
private static class Upd implements UpdateConsumer, ClassFinder.ErrorHandler {
@Override
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
@Override
public void getUpdates(List<Update> updates) {
updates.forEach(System.out::println);
}
}
}

View File

@@ -1,10 +1,10 @@
package hdvtdev.telegram.core.bot;
package hdvtdev.telegram.core;
import hdvtdev.telegram.exceptions.TelegramApiException;
import hdvtdev.telegram.exceptions.TelegramApiNetworkException;
import hdvtdev.telegram.exceptions.TelegramMethodParsingException;
import hdvtdev.telegram.methods.TelegramApiMethod;
import hdvtdev.telegram.objects.TelegramFile;
import hdvtdev.telegram.core.exceptions.TelegramApiException;
import hdvtdev.telegram.core.exceptions.TelegramApiNetworkException;
import hdvtdev.telegram.core.exceptions.TelegramMethodParsingException;
import hdvtdev.telegram.core.methods.TelegramApiMethod;
import hdvtdev.telegram.core.objects.media.TelegramFile;
import java.io.File;
import java.io.IOException;
@@ -19,12 +19,26 @@ public interface TelegramBot {
File awaitDownloadFile(TelegramFile telegramFile, Path targetDirectory);
default CompletableFuture<File> downloadFile(TelegramFile telegramFile, Path targetDirectory) throws TelegramApiException, TelegramApiNetworkException {
return CompletableFuture.supplyAsync(() -> awaitDownloadFile(telegramFile, targetDirectory));
void shutdown();
void start(UpdateConsumer updateConsumer);
default CompletableFuture<File> downloadFile(TelegramFile telegramFile, Path targetDirectory) {
CompletableFuture<File> completableFuture = CompletableFuture.supplyAsync(() -> awaitDownloadFile(telegramFile, targetDirectory));
completableFuture.exceptionally(e -> {
e.printStackTrace();
return null;
});
return completableFuture;
}
default <T> CompletableFuture<T> execute(TelegramApiMethod<T> telegramApiMethod) throws TelegramApiException, TelegramApiNetworkException, TelegramMethodParsingException {
return CompletableFuture.supplyAsync(() -> awaitExecute(telegramApiMethod));
default <T> CompletableFuture<T> execute(TelegramApiMethod<T> telegramApiMethod) {
CompletableFuture<T> completableFuture = CompletableFuture.supplyAsync(() -> awaitExecute(telegramApiMethod));
completableFuture.exceptionally(e -> {
e.printStackTrace();
return null;
});
return completableFuture;
}
default int getPing() throws TelegramApiNetworkException {

View File

@@ -1,4 +1,5 @@
package hdvtdev.telegram.core.bot;
package hdvtdev.telegram.core;
import hdvtdev.telegram.core.objects.Update;
@@ -6,6 +7,10 @@ import java.util.List;
public interface UpdateConsumer {
void getUpdates(List<Update> updates);
default void onUpdate(Update update) {}
}

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.core.bot;
package hdvtdev.telegram.core;
public interface UserState {
}

View File

@@ -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.
* <h5>Last documentation update: 2025-04-05</h5>
* @see com.fasterxml.jackson.databind.ObjectMapper
* @since 1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Jsonable {
}

View File

@@ -0,0 +1,9 @@
package hdvtdev.telegram.core.annotations;
public @interface TelegramAPI {
String since();
}

View File

@@ -1,6 +1,5 @@
package hdvtdev.telegram.exceptions;
package hdvtdev.telegram.core.exceptions;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.exceptions;
package hdvtdev.telegram.core.exceptions;
import java.io.IOException;

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.exceptions;
package hdvtdev.telegram.core.exceptions;
public class TelegramMethodParsingException extends RuntimeException {
public TelegramMethodParsingException(String message) {

View File

@@ -1,22 +1,19 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.Game;
import hdvtdev.telegram.core.objects.Game;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to send answers to callback queries sent from inline keyboards.
* The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
* Alternatively, the user can be redirected to the specified {@link Game} URL.
* For this option to work, you must first create a game for your bot via @BotFather and accept the terms. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter.
* For this option to work, you must first create a game for your command via @BotFather and accept the terms. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your command with a parameter.
* @apiNote On success, {@code Boolean == true} is returned.
* @since 1.0.0
*/
@NotTested
public class AnswerCallbackQuery implements TelegramApiMethod<Boolean> {
//@NotTested
public final class AnswerCallbackQuery implements TelegramApiMethod<Boolean> {
/**
* Unique identifier for the query to be answered
@@ -33,7 +30,7 @@ public class AnswerCallbackQuery implements TelegramApiMethod<Boolean> {
/**
* URL that will be opened by the user's client.
* If you have created a {@link Game} and accepted the conditions via @BotFather, specify the URL that opens your game.
* Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter.
* Otherwise, you may use links like t.me/your_bot?start=XXXX that open your command with a parameter.
* @apiNote this will only work if the query comes from a callback_game button.
*/
private String url;
@@ -56,13 +53,14 @@ public class AnswerCallbackQuery implements TelegramApiMethod<Boolean> {
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("callback_query_id", this.callbackQueryId);
if (text != null) builder.add("text", this.text);
if (showAlert != null) builder.add("show_alert", String.valueOf(this.showAlert));
if (url != null) builder.add("url", this.url);
if (cacheTime != null) builder.add("cache_time", String.valueOf(this.cacheTime));
return builder.build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("callback_query_id", this.callbackQueryId);
body.add("text", this.text);
body.add("show_alert", String.valueOf(this.showAlert));
body.add("url", this.url);
body.add("cache_time", String.valueOf(this.cacheTime));
return body;
}
@Override

View File

@@ -1,19 +1,14 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import hdvtdev.telegram.objects.Chat;
import hdvtdev.telegram.objects.User;
import hdvtdev.telegram.core.objects.chat.Chat;
import hdvtdev.telegram.core.objects.chat.ChatAdministratorRights;
import hdvtdev.telegram.core.objects.User;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
/**
* Use this method to approve a chat join request.
* The bot must be an <u>administrator</u> in the chat for this to work and must have the {@link ChatAdministratorRights#canInviteUsers()} administrator right.
* Returns True on success.
* The command must be an <u>administrator</u> in the chat for this to work and must have the {@link ChatAdministratorRights#canInviteUsers()} administrator right.
* 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
@@ -21,8 +16,9 @@ import org.jetbrains.annotations.NotNull;
* @see Chat#id()
* @since 0.1.0
*/
@NotTested
public record ApproveChatJoinRequest(@NotNull String chatId, long userId) implements TelegramApiMethod<Boolean> {
//TODO NotTested
public record ApproveChatJoinRequest(String chatId, long userId) implements TelegramApiMethod<Boolean> {
/**
* @param chatId Unique identifier for the target chat
@@ -35,8 +31,11 @@ public record ApproveChatJoinRequest(@NotNull String chatId, long userId) implem
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("user_id", String.valueOf(userId)).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", chatId);
body.add("user_id", String.valueOf(userId));
return body;
}
@Override

View File

@@ -1,20 +1,19 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.core.objects.chat.ChatAdministratorRights;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to ban a user in a group, a supergroup or a channel.
* In the case of supergroups and channels, the user will not be able to return
* to the chat on their own using invite links, etc., unless unbanned first.
* The bot must be an administrator in the chat for this to work and must have
* The command must be an administrator in the chat for this to work and must have
* the appropriate administrator rights: {@link ChatAdministratorRights#canRestrictMembers()}. Returns True on success.
* @see ChatAdministratorRights
* @since 0.1.1
*/
@NotTested
//TODO NotTested
public final class BanChatMember implements TelegramApiMethod<Boolean> {
/**
@@ -33,8 +32,8 @@ public final class BanChatMember implements TelegramApiMethod<Boolean> {
*/
private Long untilDate;
/**
* Pass true to delete all messages from the chat for the user that is being removed.
* If false, the user will be able to see messages in the group that were sent before the user was removed.
* Pass true to delete all message from the chat for the user that is being removed.
* If false, the user will be able to see message in the group that were sent before the user was removed.
* Always True for supergroups and channels.
*/
private Boolean revokeMessages;
@@ -65,11 +64,13 @@ public final class BanChatMember implements TelegramApiMethod<Boolean> {
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("chat_id", this.chatId).add("user_id", String.valueOf(userId));
if (untilDate != null) builder.add("until_date", String.valueOf(untilDate));
if (revokeMessages != null) builder.add("revoke_messages", String.valueOf(revokeMessages));
return builder.build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", this.chatId);
body.add("user_id", String.valueOf(userId));
body.add("until_date", String.valueOf(untilDate));
body.add("revoke_messages", String.valueOf(revokeMessages));
return body;
}
@Override

View File

@@ -1,29 +1,25 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
package hdvtdev.telegram.core.methods;
/**
* Use this method to ban a channel chat in a supergroup or a channel.
* Until the chat is unbanned, the owner of the banned chat won't be able to send messages on behalf of
* their channels. The bot must be an administrator in the supergroup or channel for this to
* Until the chat is unbanned, the owner of the banned chat won't be able to send message on behalf of
* their channels. The command must be an administrator in the supergroup or channel for this to
* work and must have the appropriate administrator rights. Returns True on success.
* @since 1.0.0
*/
@NotTested
public record BanChatSenderChat(@NotNull String chatId, long userId) implements TelegramApiMethod<Boolean> {
//TODO NotTested
public record BanChatSenderChat(String chatId, long userId) implements TelegramApiMethod<Boolean> {
public BanChatSenderChat(long chatId, long userId) {
this(String.valueOf(chatId), userId);
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("user_id", String.valueOf(userId)).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", chatId);
body.add("user_id", String.valueOf(userId));
return body;
}
@Override

View File

@@ -1,19 +1,16 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.chat.ChatAdministratorRights;
/**
* Use this method to close an open topic in a forum supergroup chat.
* The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights,
* The command must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights,
* unless it is the creator of the topic. Returns {@code true} on success.
* @param chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
* @param messageThreadId Unique identifier for the target message thread of the forum topic
* @see ChatAdministratorRights#canManageTopics()
*/
@NotTested
//TODO NotTested
public record CloseForumTopic(String chatId, long messageThreadId) implements TelegramApiMethod<Boolean> {
public CloseForumTopic(long chatId, long messageThreadId) {
@@ -21,8 +18,11 @@ public record CloseForumTopic(String chatId, long messageThreadId) implements Te
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("message_thread_id", String.valueOf(messageThreadId)).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", chatId);
body.add("message_thread_id", String.valueOf(messageThreadId));
return body;
}
@Override

View File

@@ -1,19 +1,15 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.chat.ChatAdministratorRights;
/**
* Use this method to close an open 'General' topic in a forum supergroup chat.
* The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
* The command must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
* Returns {@code true} on success.
* @see ChatAdministratorRights#canManageTopics()
* @param chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
*/
@NotTested
// TODO NotTested
public record CloseGeneralForumTopic(String chatId) implements TelegramApiMethod<Boolean> {
public CloseGeneralForumTopic(long chatId) {
@@ -21,8 +17,10 @@ public record CloseGeneralForumTopic(String chatId) implements TelegramApiMethod
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", chatId);
return body;
}
@Override

View File

@@ -1,32 +1,28 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.MessageEntity;
import hdvtdev.telegram.objects.Poll;
import hdvtdev.telegram.objects.ReplyMarkup;
import hdvtdev.telegram.objects.ReplyParameters;
import hdvtdev.telegram.util.ParseMode;
import hdvtdev.telegram.core.methods.util.ParseMode;
import hdvtdev.telegram.core.objects.message.MessageEntity;
import hdvtdev.telegram.core.objects.poll.Poll;
import hdvtdev.telegram.core.objects.markup.ReplyMarkup;
import hdvtdev.telegram.core.objects.ReplyParameters;
import okhttp3.RequestBody;
import java.util.List;
/**
* Use this method to copy messages of any kind.
* Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied.
* A quiz {@link Poll} can be copied only if the value of the field correct_option_id is known to the bot.
* Use this method to copy message of any kind.
* Service message, paid media message, giveaway message, giveaway winners message, and invoice message can't be copied.
* A quiz {@link Poll} can be copied only if the value of the field correct_option_id is known to the command.
* The method is analogous to the method {@link ForwardMessage}, but the copied message doesn't have a link to the original message.
* Returns the messageId as {@link Long} of the sent message on success.
* @see Poll#correctOptionId()
* @since 1.0.0
*/
@NotTested
@Jsonable
//TODO NotTested
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class CopyMessage implements TelegramApiMethod<Long> {
@@ -140,7 +136,13 @@ public final class CopyMessage implements TelegramApiMethod<Long> {
@JsonIgnore
@Override
public RequestBody getBody() {
public boolean isJsonable() {
return true;
}
@JsonIgnore
@Override
public TelegramApiMethodBody getBody() {
return null;
}

View File

@@ -1,29 +1,26 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.Poll;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.poll.Poll;
import java.util.ArrayList;
import java.util.List;
/**
* Use this method to copy messages of any kind.
* If some of the specified messages can't be found or copied, they are skipped.
* Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied.
* A quiz {@link Poll} can be copied only if the value of the field correct_option_id is known to the bot.
* The method is analogous to the method {@link ForwardMessages}, but the copied messages don't have a link to the original message.
* Album grouping is kept for copied messages.
* On success, an array of MessageId as {@link Long}{@code []} of the sent messages is returned.
* Use this method to copy message of any kind.
* If some of the specified message can't be found or copied, they are skipped.
* Service message, paid media message, giveaway message, giveaway winners message, and invoice message can't be copied.
* A quiz {@link Poll} can be copied only if the value of the field correct_option_id is known to the command.
* The method is analogous to the method {@link ForwardMessages}, but the copied message don't have a link to the original message.
* Album grouping is kept for copied message.
* On success, an array of MessageId as {@link Long}{@code []} of the sent message is returned.
* @see Poll#correctOptionId()
* @since 1.0.0
*/
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class CopyMessages implements TelegramApiMethod<Long[]> {
@@ -44,8 +41,8 @@ public final class CopyMessages implements TelegramApiMethod<Long[]> {
/**
* @param chatId Username of the target channel (in the format @channelusername)
* @param fromChatId Channel username in the format @channelusername for the chat where the original messages were sent
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
* @param fromChatId Channel username in the format @channelusername for the chat where the original message were sent
* @param messageIds List of 1-100 identifiers of message in the chat to copy.
*/
public CopyMessages(String chatId, String fromChatId, List<Long> messageIds) {
this.chatId = chatId;
@@ -57,8 +54,8 @@ public final class CopyMessages implements TelegramApiMethod<Long[]> {
/**
* @param chatId Unique identifier for the target chat
* @param fromChatId Channel username in the format @channelusername for the chat where the original messages were sent
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
* @param fromChatId Channel username in the format @channelusername for the chat where the original message were sent
* @param messageIds List of 1-100 identifiers of message in the chat to copy.
*/
public CopyMessages(long chatId, String fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), fromChatId, messageIds);
@@ -66,17 +63,17 @@ public final class CopyMessages implements TelegramApiMethod<Long[]> {
/**
* @param chatId Unique identifier for the target chat
* @param fromChatId Unique identifier for the chat where the original messages were sent
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
* @param fromChatId Unique identifier for the chat where the original message were sent
* @param messageIds List of 1-100 identifiers of message in the chat to copy.
*/
public CopyMessages(long chatId, long fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), String.valueOf(fromChatId), messageIds);
}
/**
* @param chatId Channel username in the format @channelusername for the chat where the original messages were sent
* @param chatId Channel username in the format @channelusername for the chat where the original message were sent
* @param fromChatId Unique identifier for the target chat
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
* @param messageIds List of 1-100 identifiers of message in the chat to copy.
*/
public CopyMessages(String chatId, long fromChatId, List<Long> messageIds) {
this(chatId, String.valueOf(fromChatId), messageIds);
@@ -110,7 +107,7 @@ public final class CopyMessages implements TelegramApiMethod<Long[]> {
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -126,6 +123,12 @@ public final class CopyMessages implements TelegramApiMethod<Long[]> {
return Long[].class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
public static final class Builder {
private final String chatId;
private Long messageThreadId;

View File

@@ -1,14 +1,11 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import hdvtdev.telegram.objects.ChatInviteLink;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.chat.ChatAdministratorRights;
import hdvtdev.telegram.core.objects.chat.ChatInviteLink;
/**
* Use this method to create an additional invite link for a chat.
* The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights.
* The command must be an administrator in the chat for this to work and must have the appropriate administrator rights.
* The link can be revoked using the method {@link RevokeChatInviteLink}. Returns the new invite link as {@link ChatInviteLink} object.
* @see ChatAdministratorRights#canInviteUsers()
*/
@@ -54,12 +51,14 @@ public final class CreateChatInviteLink implements TelegramApiMethod<ChatInviteL
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("chat_id", chatId);
if (expireDate != null) builder.add("expire_date", String.valueOf(expireDate));
if (memberLimit != null) builder.add("member_limit", String.valueOf(memberLimit));
if (createsJoinRequest != null) builder.add("creates_join_request", String.valueOf(createsJoinRequest));
return builder.build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("name", name);
body.add("chat_id", chatId);
body.add("expire_date", String.valueOf(expireDate));
body.add("member_limit", String.valueOf(memberLimit));
body.add("creates_join_request", String.valueOf(createsJoinRequest));
return body;
}
@Override

View File

@@ -1,20 +1,17 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.Message;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.message.Message;
/**
* Use this method to forward messages of any kind.
* Service messages and messages with protected content can't be forwarded.
* 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<Message> {
@@ -75,7 +72,7 @@ public final class ForwardMessage implements TelegramApiMethod<Message> {
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -91,6 +88,12 @@ public final class ForwardMessage implements TelegramApiMethod<Message> {
return Message.class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
public static final class Builder {
private final String chatId;
private Long messageThreadId;

View File

@@ -1,26 +1,21 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.Message;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.message.Message;
import java.util.ArrayList;
import java.util.List;
/**
* Use this method to forward multiple messages of any kind. If some of the specified messages can't be found or forwarded, they are skipped.
* Service messages and messages with protected content can't be forwarded. Album grouping is kept for forwarded messages.
* On success, an array of MessageId as {@link Long} of the sent messages is returned.
* Use this method to forward multiple message of any kind. If some of the specified message can't be found or forwarded, they are skipped.
* Service message and message with protected content can't be forwarded. Album grouping is kept for forwarded message.
* On success, an array of MessageId as {@link Long} of the sent message is returned.
* @see Message#hasProtectedContent()
*/
@Jsonable
@NotTested
// TODO NotTested
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class ForwardMessages implements TelegramApiMethod<Long[]> {
@@ -80,7 +75,7 @@ public final class ForwardMessages implements TelegramApiMethod<Long[]> {
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -96,6 +91,11 @@ public final class ForwardMessages implements TelegramApiMethod<Long[]> {
return Long[].class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
public static final class Builder {
private final String chatId;

View File

@@ -1,27 +1,23 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatMember;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
import hdvtdev.telegram.core.objects.chat.ChatMember;
/**
* Use this method to get a list of administrators in a chat, which aren't bots. Returns an Array of {@link ChatMember} objects.
* @param chatId
*/
@NotTested
public record GetChatAdministrators(@NotNull String chatId) implements TelegramApiMethod<ChatMember[]> {
//TODO NotTested
public record GetChatAdministrators(String chatId) implements TelegramApiMethod<ChatMember[]> {
public GetChatAdministrators(long chatId) {
this(String.valueOf(chatId));
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", chatId);
return body;
}
@Override

View File

@@ -1,13 +1,8 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.objects.ChatMember;
import hdvtdev.telegram.core.objects.chat.ChatMember;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
public record GetChatMember(@NotNull String chatId, long userId) implements TelegramApiMethod<ChatMember> {
public record GetChatMember(String chatId, long userId) implements TelegramApiMethod<ChatMember> {
public GetChatMember(long chatId, long userId) {
this(String.valueOf(chatId), userId);
@@ -22,8 +17,11 @@ public record GetChatMember(@NotNull String chatId, long userId) implements Tele
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("user_id", String.valueOf(userId)).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", chatId);
body.add("user_id", String.valueOf(userId));
return body;
}
@Override

View File

@@ -1,14 +1,14 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.objects.TelegramFile;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.media.TelegramFile;
public record GetFile(String fileId) implements TelegramApiMethod<TelegramFile> {
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("file_id", fileId).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("file_id", fileId);
return body;
}
@Override

View File

@@ -1,12 +1,11 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.objects.User;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.User;
public final class GetMe implements TelegramApiMethod<User.Bot> {
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}

View File

@@ -1,25 +1,21 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.bot.BotCommand;
import hdvtdev.telegram.objects.bot.BotCommandScope;
import hdvtdev.telegram.objects.bot.BotCommandScopeDefault;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.command.BotCommand;
import hdvtdev.telegram.core.objects.command.BotCommandScope;
import hdvtdev.telegram.core.objects.command.BotCommandScopeDefault;
/**
* Use this method to get the current list of the bot's commands for the given scope and user language.
* Use this method to get the current list of the command's commands for the given scope and user language.
* Returns an Array of {@link BotCommand} objects. If commands aren't set, an empty list is returned.
* @param scope Scope of users. Defaults to {@link BotCommandScopeDefault}.
* @param languageCode A two-letter ISO 639-1 language code or an empty string
* @see BotCommandScope
* @since 1.0.0
*/
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public record GetMyCommands(
@JsonProperty("scope") BotCommandScope scope,
@@ -40,7 +36,7 @@ public record GetMyCommands(
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -55,4 +51,10 @@ public record GetMyCommands(
public Class<BotCommand[]> getResponseClass() {
return BotCommand[].class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
}

View File

@@ -1,9 +1,4 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
package hdvtdev.telegram.core.methods;
public record GetMyDescription(String languageCode) implements TelegramApiMethod<GetMyDescription.BotDescription> {
@@ -12,8 +7,14 @@ public record GetMyDescription(String languageCode) implements TelegramApiMethod
}
@Override
public RequestBody getBody() {
return languageCode == null ? null : new FormBody.Builder().add("language_code", languageCode).build();
public TelegramApiMethodBody getBody() {
if (languageCode == null) {
return null;
} else {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("language_code", languageCode);
return body;
}
}
@Override
@@ -27,7 +28,7 @@ public record GetMyDescription(String languageCode) implements TelegramApiMethod
}
public record BotDescription(String description) {
@NotNull
@Override
public String toString() {
return description;

View File

@@ -1,7 +1,5 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
public record GetMyName(String languageCode) implements TelegramApiMethod<GetMyName.BotName> {
@@ -11,8 +9,14 @@ public record GetMyName(String languageCode) implements TelegramApiMethod<GetMyN
}
@Override
public RequestBody getBody() {
return this.languageCode == null ? null : new FormBody.Builder().add("language_code", this.languageCode).build();
public TelegramApiMethodBody getBody() {
if (languageCode == null) {
return null;
} else {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("language_code", languageCode);
return body;
}
}
@Override
@@ -27,9 +31,8 @@ public record GetMyName(String languageCode) implements TelegramApiMethod<GetMyN
public record BotName(String name) {
@NotNull
@Override
public String toString() {
public @NotNull String toString() {
return this.name;
}

View File

@@ -1,8 +1,6 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.objects.Update;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.Update;
import java.util.ArrayList;
@@ -17,7 +15,7 @@ public record GetUpdates(
}
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}

View File

@@ -1,28 +1,26 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import hdvtdev.telegram.objects.ChatInviteLink;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
import hdvtdev.telegram.core.objects.chat.ChatInviteLink;
/**
* Use this method to revoke an invite link created by the bot. If the primary link is revoked, a new link is automatically generated.
* The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights.
* Use this method to revoke an invite link created by the command. If the primary link is revoked, a new link is automatically generated.
* The command must be an administrator in the chat for this to work and must have the appropriate administrator rights.
* Returns the revoked invite link as {@link ChatInviteLink} object.
* @param chatId Unique identifier of the target chat or username of the target channel (in the format @channelusername)
* @param link The invite link to revoke
*/
public record RevokeChatInviteLink(@NotNull String chatId, @NotNull String link) implements TelegramApiMethod<ChatInviteLink> {
public record RevokeChatInviteLink(String chatId, String link) implements TelegramApiMethod<ChatInviteLink> {
public RevokeChatInviteLink(long chatId, @NotNull String link) {
public RevokeChatInviteLink(long chatId, String link) {
this(String.valueOf(chatId), link);
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("link", link).build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody(2);
body.add("chat_id", chatId);
body.add("link", link);
return body;
}
@Override

View File

@@ -1,10 +1,4 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
package hdvtdev.telegram.core.methods;
public final class SendChatAction implements TelegramApiMethod<Boolean> {
@@ -13,7 +7,7 @@ public final class SendChatAction implements TelegramApiMethod<Boolean> {
private Long messageThreadId;
private final ChatAction chatAction;
public SendChatAction(@Nullable String businessConnectionId, @NotNull String chatId, @Nullable Long messageThreadId, @NotNull ChatAction chatAction) {
public SendChatAction(String businessConnectionId, String chatId, Long messageThreadId, ChatAction chatAction) {
this.businessConnectionId = businessConnectionId;
this.chatId = chatId;
this.messageThreadId = messageThreadId;
@@ -41,14 +35,13 @@ public final class SendChatAction implements TelegramApiMethod<Boolean> {
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("chat_id", chatId).add("action", chatAction.equals(ChatAction.UPLOAD_FILE) ? ChatAction.UPLOAD_DOCUMENT.name() : chatAction.name());
if (businessConnectionId != null) builder.add("business_connection_id", businessConnectionId);
if (messageThreadId != null) builder.add("message_thread_id", String.valueOf(messageThreadId));
return builder.build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody();
body.add("chat_id", chatId);
body.add("action", chatAction.equals(ChatAction.UPLOAD_FILE) ? ChatAction.UPLOAD_DOCUMENT.name() : chatAction.name());
body.add("business_connection_id", businessConnectionId);
body.add("message_thread_id", String.valueOf(messageThreadId));
return body;
}
@Override

View File

@@ -1,17 +1,13 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.Message;
import hdvtdev.telegram.objects.ReplyMarkup;
import hdvtdev.telegram.objects.ReplyParameters;
import hdvtdev.telegram.core.objects.message.Message;
import hdvtdev.telegram.core.objects.markup.ReplyMarkup;
import hdvtdev.telegram.core.objects.ReplyParameters;
import okhttp3.RequestBody;
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class SendDice implements TelegramApiMethod<Message> {
@@ -92,7 +88,7 @@ public final class SendDice implements TelegramApiMethod<Message> {
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -108,6 +104,12 @@ public final class SendDice implements TelegramApiMethod<Message> {
return Message.class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
public enum Emoji {
DICE("🎲"),
DART("🎯"),

View File

@@ -1,16 +1,17 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.*;
import hdvtdev.telegram.util.ParseMode;
import hdvtdev.telegram.core.methods.util.ParseMode;
import hdvtdev.telegram.core.objects.*;
import hdvtdev.telegram.core.objects.markup.ReplyMarkup;
import hdvtdev.telegram.core.objects.message.LinkPreviewOptions;
import hdvtdev.telegram.core.objects.message.Message;
import hdvtdev.telegram.core.objects.message.MessageEntity;
import okhttp3.RequestBody;
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class SendMessage implements TelegramApiMethod<Message> {
@@ -118,7 +119,7 @@ public final class SendMessage implements TelegramApiMethod<Message> {
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -134,6 +135,12 @@ public final class SendMessage implements TelegramApiMethod<Message> {
return Message.class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
public static final class Builder {
private final String chatId;
private final String text;

View File

@@ -1,17 +1,13 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.ReactionType;
import okhttp3.RequestBody;
import hdvtdev.telegram.core.objects.reaction.ReactionType;
import java.util.List;
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SetMessageReaction implements TelegramApiMethod<Boolean> {
@@ -51,7 +47,7 @@ public class SetMessageReaction implements TelegramApiMethod<Boolean> {
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -67,6 +63,12 @@ public class SetMessageReaction implements TelegramApiMethod<Boolean> {
return Boolean.class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
public static final class Builder {
private final String chatId;
private final long messageId;

View File

@@ -1,17 +1,14 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.methods;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.bot.BotCommand;
import hdvtdev.telegram.objects.bot.BotCommandScope;
import okhttp3.RequestBody;
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<Boolean> {
@@ -53,7 +50,7 @@ public final class SetMyCommands implements TelegramApiMethod<Boolean> {
@JsonIgnore
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
return null;
}
@@ -69,6 +66,12 @@ public final class SetMyCommands implements TelegramApiMethod<Boolean> {
return Boolean.class;
}
@JsonIgnore
@Override
public boolean isJsonable() {
return true;
}
public static final class Builder {
private final List<BotCommand> commands;

View File

@@ -1,12 +1,9 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
package hdvtdev.telegram.core.methods;
/**
* Use this method to change the bot's description, which is shown in the chat with the bot if the chat is empty.
* Use this method to change the command's description, which is shown in the chat with the command if the chat is empty.
* Returns {@code true} on success.
* @param description New bot description; 0-512 characters. Pass an empty string to remove the dedicated description for the given language.
* @param description New command description; 0-512 characters. Pass an empty string to remove the dedicated description for the given language.
* @param languageCode A two-letter ISO 639-1 language code. If empty, the description will be applied to all users for whose language there is no dedicated description.
*/
public record SetMyDescription(String description, String languageCode) implements TelegramApiMethod<Boolean> {
@@ -20,13 +17,15 @@ public record SetMyDescription(String description, String languageCode) implemen
}
@Override
public RequestBody getBody() {
public TelegramApiMethodBody getBody() {
if (description == null) {
return null;
} else {
TelegramApiMethodBody body = new TelegramApiMethodBody(2);
body.add("language_code", languageCode);
body.add("description", description);
return body;
}
FormBody.Builder builder = new FormBody.Builder().add("description", description);
if (languageCode != null) builder.add("language_code", languageCode);
return builder.build();
}
@Override

View File

@@ -1,7 +1,4 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
package hdvtdev.telegram.core.methods;
public record SetMyName(String name, String languageCode) implements TelegramApiMethod<Boolean> {
@@ -10,10 +7,11 @@ public record SetMyName(String name, String languageCode) implements TelegramApi
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("name", this.name);
if (languageCode != null) builder.add("language_code", this.languageCode);
return builder.build();
public TelegramApiMethodBody getBody() {
TelegramApiMethodBody body = new TelegramApiMethodBody(2);
body.add("name", this.name);
body.add("language_code", this.languageCode);
return body;
}
@Override

View File

@@ -1,13 +1,15 @@
package hdvtdev.telegram.core.objects;
import okhttp3.RequestBody;
package hdvtdev.telegram.core.methods;
public interface TelegramApiMethod<T> {
RequestBody getBody();
TelegramApiMethodBody getBody();
String getMethodName();
Class<T> getResponseClass();
default boolean isJsonable() {
return false;
}
}

View File

@@ -1,7 +1,6 @@
package hdvtdev.telegram.core.bot;
package hdvtdev.telegram.core.methods;
import java.util.ArrayList;
import java.util.function.Consumer;
public final class TelegramApiMethodBody {
@@ -19,8 +18,12 @@ public final class TelegramApiMethodBody {
if (value != null) this.elements.add(new Element(name, value));
}
public void forEach(Consumer<? super Element> action) {
this.elements.forEach(action);
public int size() {
return this.elements.size();
}
public Element get(int i) {
return this.elements.get(i);
}
public record Element(String name, String value) {

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.core;
package hdvtdev.telegram.core.methods.util;
public enum ParseMode {
MARKDOWN,

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.core;
package hdvtdev.telegram.core.methods.util;
import java.io.BufferedWriter;
import java.io.FileWriter;

View File

@@ -1,113 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.Game;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to send answers to callback queries sent from inline keyboards.
* The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
* Alternatively, the user can be redirected to the specified {@link Game} URL.
* For this option to work, you must first create a game for your bot via @BotFather and accept the terms. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter.
* @apiNote On success, {@code Boolean == true} is returned.
* @since 1.0.0
*/
@NotTested
public class AnswerCallbackQuery implements TelegramApiMethod<Boolean> {
/**
* Unique identifier for the query to be answered
*/
private final String callbackQueryId;
/**
* Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters
*/
private String text;
/**
* If True, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false.
*/
private Boolean showAlert;
/**
* URL that will be opened by the user's client.
* If you have created a {@link Game} and accepted the conditions via @BotFather, specify the URL that opens your game.
* Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter.
* @apiNote this will only work if the query comes from a callback_game button.
*/
private String url;
/**
* The maximum amount of time in seconds that the result of the callback query may be cached client-side.
* Telegram apps will support caching starting in version 3.14. Defaults to 0.
*/
private Integer cacheTime;
public AnswerCallbackQuery(String callbackQueryId) {
this.callbackQueryId = callbackQueryId;
}
private AnswerCallbackQuery(Builder builder) {
callbackQueryId = builder.callbackQueryId;
text = builder.text;
showAlert = builder.showAlert;
url = builder.url;
cacheTime = builder.cacheTime;
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("callback_query_id", this.callbackQueryId);
if (text != null) builder.add("text", this.text);
if (showAlert != null) builder.add("show_alert", String.valueOf(this.showAlert));
if (url != null) builder.add("url", this.url);
if (cacheTime != null) builder.add("cache_time", String.valueOf(this.cacheTime));
return builder.build();
}
@Override
public String getMethodName() {
return "answerCallbackQuery";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
public static final class Builder {
private final String callbackQueryId;
private String text;
private Boolean showAlert;
private String url;
private Integer cacheTime;
public Builder(String callbackQueryId) {
this.callbackQueryId = callbackQueryId;
}
public Builder text(String text) {
this.text = text;
return this;
}
public Builder showAlert(Boolean showAlert) {
this.showAlert = showAlert;
return this;
}
public Builder url(String url) {
this.url = url;
return this;
}
public Builder cacheTime(Integer cacheTime) {
this.cacheTime = cacheTime;
return this;
}
public AnswerCallbackQuery build() {
return new AnswerCallbackQuery(this);
}
}
}

View File

@@ -1,51 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import hdvtdev.telegram.objects.Chat;
import hdvtdev.telegram.objects.User;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
/**
* Use this method to approve a chat join request.
* The bot must be an <u>administrator</u> in the chat for this to work and must have the {@link ChatAdministratorRights#canInviteUsers()} administrator right.
* Returns 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
* @see Chat
* @see Chat#id()
* @since 0.1.0
*/
@NotTested
public record ApproveChatJoinRequest(@NotNull String chatId, long userId) implements TelegramApiMethod<Boolean> {
/**
* @param chatId Unique identifier for the target chat
* @param userId Unique identifier of the target user
* @see User#id()
* @see Chat#id()
*/
public ApproveChatJoinRequest(long chatId, long userId) {
this(String.valueOf(chatId), userId);
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("user_id", String.valueOf(userId)).build();
}
@Override
public String getMethodName() {
return "approveChatJoinRequest";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
}

View File

@@ -1,110 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to ban a user in a group, a supergroup or a channel.
* In the case of supergroups and channels, the user will not be able to return
* to the chat on their own using invite links, etc., unless unbanned first.
* The bot must be an administrator in the chat for this to work and must have
* the appropriate administrator rights: {@link ChatAdministratorRights#canRestrictMembers()}. Returns True on success.
* @see ChatAdministratorRights
* @since 0.1.1
*/
@NotTested
public final class BanChatMember implements TelegramApiMethod<Boolean> {
/**
* Unique identifier for the target group or username of the target supergroup or channel (in the format @channelusername)
*/
private final String chatId;
/**
* Unique identifier of the target user
*/
private final long userId;
/**
* Date when the user will be unbanned; Unix time.
* If user is banned for more than 366 days or less than 30 seconds from
* the current time they are considered to be banned forever.
* Applied for supergroups and channels only.
*/
private Long untilDate;
/**
* Pass true to delete all messages from the chat for the user that is being removed.
* If false, the user will be able to see messages in the group that were sent before the user was removed.
* Always True for supergroups and channels.
*/
private Boolean revokeMessages;
public BanChatMember(String chatId, long userId) {
this.chatId = chatId;
this.userId = userId;
}
public BanChatMember(long chatId, long userId) {
this.chatId = String.valueOf(chatId);
this.userId = userId;
}
private BanChatMember(Builder builder) {
chatId = builder.chatId;
userId = builder.userId;
setUntilDate(builder.untilDate);
setRevokeMessages(builder.revokeMessages);
}
public void setUntilDate(Long untilDate) {
this.untilDate = untilDate;
}
public void setRevokeMessages(Boolean revokeMessages) {
this.revokeMessages = revokeMessages;
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("chat_id", this.chatId).add("user_id", String.valueOf(userId));
if (untilDate != null) builder.add("until_date", String.valueOf(untilDate));
if (revokeMessages != null) builder.add("revoke_messages", String.valueOf(revokeMessages));
return builder.build();
}
@Override
public String getMethodName() {
return "banChatMember";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
public static final class Builder {
private final String chatId;
private final long userId;
private Long untilDate;
private Boolean revokeMessages;
public Builder(String chatId, long userId) {
this.chatId = chatId;
this.userId = userId;
}
public Builder untilDate(Long untilDate) {
this.untilDate = untilDate;
return this;
}
public Builder revokeMessages(Boolean revokeMessages) {
this.revokeMessages = revokeMessages;
return this;
}
public BanChatMember build() {
return new BanChatMember(this);
}
}
}

View File

@@ -1,38 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
/**
* Use this method to ban a channel chat in a supergroup or a channel.
* Until the chat is unbanned, the owner of the banned chat won't be able to send messages on behalf of
* their channels. The bot must be an administrator in the supergroup or channel for this to
* work and must have the appropriate administrator rights. Returns True on success.
* @since 1.0.0
*/
@NotTested
public record BanChatSenderChat(@NotNull String chatId, long userId) implements TelegramApiMethod<Boolean> {
public BanChatSenderChat(long chatId, long userId) {
this(String.valueOf(chatId), userId);
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("user_id", String.valueOf(userId)).build();
}
@Override
public String getMethodName() {
return "banChatSenderChat";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
}

View File

@@ -1,37 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to close an open topic in a forum supergroup chat.
* The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights,
* unless it is the creator of the topic. Returns {@code true} on success.
* @param chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
* @param messageThreadId Unique identifier for the target message thread of the forum topic
* @see ChatAdministratorRights#canManageTopics()
*/
@NotTested
public record CloseForumTopic(String chatId, long messageThreadId) implements TelegramApiMethod<Boolean> {
public CloseForumTopic(long chatId, long messageThreadId) {
this(String.valueOf(chatId), messageThreadId);
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("message_thread_id", String.valueOf(messageThreadId)).build();
}
@Override
public String getMethodName() {
return "closeForumTopic";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
}

View File

@@ -1,37 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to close an open 'General' topic in a forum supergroup chat.
* The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights.
* Returns {@code true} on success.
* @see ChatAdministratorRights#canManageTopics()
* @param chatId Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
*/
@NotTested
public record CloseGeneralForumTopic(String chatId) implements TelegramApiMethod<Boolean> {
public CloseGeneralForumTopic(long chatId) {
this(String.valueOf(chatId));
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).build();
}
@Override
public String getMethodName() {
return "closeGeneralForumTopic";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
}

View File

@@ -1,244 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.MessageEntity;
import hdvtdev.telegram.objects.Poll;
import hdvtdev.telegram.objects.ReplyMarkup;
import hdvtdev.telegram.objects.ReplyParameters;
import hdvtdev.telegram.util.ParseMode;
import okhttp3.RequestBody;
import java.util.List;
/**
* Use this method to copy messages of any kind.
* Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied.
* A quiz {@link Poll} can be copied only if the value of the field correct_option_id is known to the bot.
* The method is analogous to the method {@link ForwardMessage}, but the copied message doesn't have a link to the original message.
* Returns the messageId as {@link Long} of the sent message on success.
* @see Poll#correctOptionId()
* @since 1.0.0
*/
@NotTested
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class CopyMessage implements TelegramApiMethod<Long> {
@JsonProperty("chat_id")
private final String chatId;
@JsonProperty("message_thread_id")
private Long messageThreadId;
@JsonProperty("from_chat_id")
private final String fromChatId;
@JsonProperty("message_id")
private final long messageId;
@JsonProperty("video_start_timestamp")
private long videoStartTimestamp;
@JsonProperty("caption")
private String caption;
@JsonProperty("parse_mode")
private ParseMode parseMode;
@JsonProperty("caption_entities")
private List<MessageEntity> captionEntities;
@JsonProperty("show_caption_above_media")
private Boolean showCaptionAboveMedia;
@JsonProperty("disable_notification")
private Boolean disableNotification;
@JsonProperty("protect_content")
private Boolean protectContent;
@JsonProperty("allow_paid_broadcast")
private Boolean allowPaidBroadcast;
@JsonProperty("reply_parameters")
private ReplyParameters replyParameters;
@JsonProperty("reply_markup")
private ReplyMarkup replyMarkup;
public CopyMessage(String chatId, String fromChatId, long messageId) {
this.chatId = chatId;
this.fromChatId = fromChatId;
this.messageId = messageId;
}
public CopyMessage(long chatId, String fromChatId, long messageId) {
this(String.valueOf(chatId), fromChatId, messageId);
}
public CopyMessage(long chatId, long fromChatId, long messageId) {
this(String.valueOf(chatId), String.valueOf(fromChatId), messageId);
}
public CopyMessage(String chatId, long fromChatId, long messageId) {
this(chatId, String.valueOf(fromChatId), messageId);
}
private CopyMessage(Builder builder) {
chatId = builder.chatId;
setMessageThreadId(builder.messageThreadId);
fromChatId = builder.fromChatId;
messageId = builder.messageId;
setVideoStartTimestamp(builder.videoStartTimestamp);
setCaption(builder.caption);
setParseMode(builder.parseMode);
setCaptionEntities(builder.captionEntities);
setShowCaptionAboveMedia(builder.showCaptionAboveMedia);
setDisableNotification(builder.disableNotification);
setProtectContent(builder.protectContent);
setAllowPaidBroadcast(builder.allowPaidBroadcast);
setReplyParameters(builder.replyParameters);
setReplyMarkup(builder.replyMarkup);
}
public void setMessageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
}
public void setVideoStartTimestamp(long videoStartTimestamp) {
this.videoStartTimestamp = videoStartTimestamp;
}
public void setCaption(String caption) {
this.caption = caption;
}
public void setParseMode(ParseMode parseMode) {
this.parseMode = parseMode;
}
public void setCaptionEntities(List<MessageEntity> captionEntities) {
this.captionEntities = captionEntities;
}
public void setShowCaptionAboveMedia(Boolean showCaptionAboveMedia) {
this.showCaptionAboveMedia = showCaptionAboveMedia;
}
public void setDisableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
}
public void setProtectContent(Boolean protectContent) {
this.protectContent = protectContent;
}
public void setAllowPaidBroadcast(Boolean allowPaidBroadcast) {
this.allowPaidBroadcast = allowPaidBroadcast;
}
public void setReplyParameters(ReplyParameters replyParameters) {
this.replyParameters = replyParameters;
}
public void setReplyMarkup(ReplyMarkup replyMarkup) {
this.replyMarkup = replyMarkup;
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "copyMessage";
}
@JsonIgnore
@Override
public Class<Long> getResponseClass() {
return Long.class;
}
public static final class Builder {
private final String chatId;
private Long messageThreadId;
private final String fromChatId;
private final long messageId;
private long videoStartTimestamp;
private String caption;
private ParseMode parseMode;
private List<MessageEntity> captionEntities;
private Boolean showCaptionAboveMedia;
private Boolean disableNotification;
private Boolean protectContent;
private Boolean allowPaidBroadcast;
private ReplyParameters replyParameters;
private ReplyMarkup replyMarkup;
public Builder(String chatId, String fromChatId, long messageId) {
this.chatId = chatId;
this.fromChatId = fromChatId;
this.messageId = messageId;
}
public Builder(long chatId, String fromChatId, long messageId) {
this(String.valueOf(chatId), fromChatId, messageId);
}
public Builder messageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
return this;
}
public Builder videoStartTimestamp(long videoStartTimestamp) {
this.videoStartTimestamp = videoStartTimestamp;
return this;
}
public Builder caption(String caption) {
this.caption = caption;
return this;
}
public Builder parseMode(ParseMode parseMode) {
this.parseMode = parseMode;
return this;
}
public Builder captionEntities(List<MessageEntity> captionEntities) {
this.captionEntities = captionEntities;
return this;
}
public Builder showCaptionAboveMedia(Boolean showCaptionAboveMedia) {
this.showCaptionAboveMedia = showCaptionAboveMedia;
return this;
}
public Builder disableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
return this;
}
public Builder protectContent(Boolean protectContent) {
this.protectContent = protectContent;
return this;
}
public Builder allowPaidBroadcast(Boolean allowPaidBroadcast) {
this.allowPaidBroadcast = allowPaidBroadcast;
return this;
}
public Builder replyParameters(ReplyParameters replyParameters) {
this.replyParameters = replyParameters;
return this;
}
public Builder replyMarkup(ReplyMarkup replyMarkup) {
this.replyMarkup = replyMarkup;
return this;
}
public CopyMessage build() {
return new CopyMessage(this);
}
}
}

View File

@@ -1,181 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.Poll;
import okhttp3.RequestBody;
import java.util.ArrayList;
import java.util.List;
/**
* Use this method to copy messages of any kind.
* If some of the specified messages can't be found or copied, they are skipped.
* Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied.
* A quiz {@link Poll} can be copied only if the value of the field correct_option_id is known to the bot.
* The method is analogous to the method {@link ForwardMessages}, but the copied messages don't have a link to the original message.
* Album grouping is kept for copied messages.
* On success, an array of MessageId as {@link Long}{@code []} of the sent messages is returned.
* @see Poll#correctOptionId()
* @since 1.0.0
*/
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class CopyMessages implements TelegramApiMethod<Long[]> {
@JsonProperty("chat_id")
private final String chatId;
@JsonProperty("message_thread_id")
private Long messageThreadId;
@JsonProperty("from_chat_id")
private final String fromChatId;
@JsonProperty("message_id")
private final List<Long> messageIds;
@JsonProperty("disable_notification")
private Boolean disableNotification;
@JsonProperty("protect_content")
private Boolean protectContent;
@JsonProperty("remove_caption")
private Boolean removeCaption;
/**
* @param chatId Username of the target channel (in the format @channelusername)
* @param fromChatId Channel username in the format @channelusername for the chat where the original messages were sent
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
*/
public CopyMessages(String chatId, String fromChatId, List<Long> messageIds) {
this.chatId = chatId;
this.fromChatId = fromChatId;
ArrayList<Long> sortedMessageIds = new ArrayList<>(messageIds.subList(0, Math.min(messageIds.size(), 100)));
sortedMessageIds.sort(null);
this.messageIds = sortedMessageIds;
}
/**
* @param chatId Unique identifier for the target chat
* @param fromChatId Channel username in the format @channelusername for the chat where the original messages were sent
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
*/
public CopyMessages(long chatId, String fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), fromChatId, messageIds);
}
/**
* @param chatId Unique identifier for the target chat
* @param fromChatId Unique identifier for the chat where the original messages were sent
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
*/
public CopyMessages(long chatId, long fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), String.valueOf(fromChatId), messageIds);
}
/**
* @param chatId Channel username in the format @channelusername for the chat where the original messages were sent
* @param fromChatId Unique identifier for the target chat
* @param messageIds List of 1-100 identifiers of messages in the chat to copy.
*/
public CopyMessages(String chatId, long fromChatId, List<Long> messageIds) {
this(chatId, String.valueOf(fromChatId), messageIds);
}
private CopyMessages(Builder builder) {
chatId = builder.chatId;
setMessageThreadId(builder.messageThreadId);
fromChatId = builder.fromChatId;
messageIds = builder.messageIds;
setDisableNotification(builder.disableNotification);
setProtectContent(builder.protectContent);
setRemoveCaption(builder.removeCaption);
}
public void setMessageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
}
public void setDisableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
}
public void setProtectContent(Boolean protectContent) {
this.protectContent = protectContent;
}
public void setRemoveCaption(Boolean removeCaption) {
this.removeCaption = removeCaption;
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "copyMessages";
}
@JsonIgnore
@Override
public Class<Long[]> getResponseClass() {
return Long[].class;
}
public static final class Builder {
private final String chatId;
private Long messageThreadId;
private final String fromChatId;
private final List<Long> messageIds;
private Boolean disableNotification;
private Boolean protectContent;
private Boolean removeCaption;
public Builder(String chatId, String fromChatId, List<Long> messageIds) {
this.chatId = chatId;
this.fromChatId = fromChatId;
ArrayList<Long> sortedMessageIds = new ArrayList<>(messageIds.subList(0, Math.min(messageIds.size(), 100)));
sortedMessageIds.sort(null);
this.messageIds = sortedMessageIds;
}
public Builder(long chatId, String fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), fromChatId, messageIds);
}
public Builder(long chatId, long fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), String.valueOf(fromChatId), messageIds);
}
public Builder(String chatId, long fromChatId, List<Long> messageIds) {
this(chatId, String.valueOf(fromChatId), messageIds);
}
public Builder messageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
return this;
}
public Builder disableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
return this;
}
public Builder protectContent(Boolean protectContent) {
this.protectContent = protectContent;
return this;
}
public Builder removeCaption(Boolean removeCaption) {
this.removeCaption = removeCaption;
return this;
}
public CopyMessages build() {
return new CopyMessages(this);
}
}
}

View File

@@ -1,114 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.objects.ChatAdministratorRights;
import hdvtdev.telegram.objects.ChatInviteLink;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to create an additional invite link for a chat.
* The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights.
* The link can be revoked using the method {@link RevokeChatInviteLink}. Returns the new invite link as {@link ChatInviteLink} object.
* @see ChatAdministratorRights#canInviteUsers()
*/
public final class CreateChatInviteLink implements TelegramApiMethod<ChatInviteLink> {
private final String chatId;
private String name;
private Long expireDate;
private Integer memberLimit;
private Boolean createsJoinRequest;
public CreateChatInviteLink(String chatId) {
this.chatId = chatId;
}
public CreateChatInviteLink(long chatId) {
this(String.valueOf(chatId));
}
private CreateChatInviteLink(Builder builder) {
chatId = builder.chatId;
setName(builder.name);
setExpireDate(builder.expireDate);
setMemberLimit(builder.memberLimit);
setCreatesJoinRequest(builder.createsJoinRequest);
}
public void setName(String name) {
this.name = name;
}
public void setExpireDate(Long expireDate) {
this.expireDate = expireDate;
}
public void setMemberLimit(Integer memberLimit) {
this.memberLimit = memberLimit;
}
public void setCreatesJoinRequest(Boolean createsJoinRequest) {
this.createsJoinRequest = createsJoinRequest;
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("chat_id", chatId);
if (expireDate != null) builder.add("expire_date", String.valueOf(expireDate));
if (memberLimit != null) builder.add("member_limit", String.valueOf(memberLimit));
if (createsJoinRequest != null) builder.add("creates_join_request", String.valueOf(createsJoinRequest));
return builder.build();
}
@Override
public String getMethodName() {
return "createChatInviteLink";
}
@Override
public Class<ChatInviteLink> getResponseClass() {
return ChatInviteLink.class;
}
public static final class Builder {
private final String chatId;
private String name;
private Long expireDate;
private Integer memberLimit;
private Boolean createsJoinRequest;
public Builder(String chatId) {
this.chatId = chatId;
}
public Builder(long chatId) {
this(String.valueOf(chatId));
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder expireDate(Long expireDate) {
this.expireDate = expireDate;
return this;
}
public Builder memberLimit(Integer memberLimit) {
this.memberLimit = memberLimit;
return this;
}
public Builder createsJoinRequest(Boolean createsJoinRequest) {
this.createsJoinRequest = createsJoinRequest;
return this;
}
public CreateChatInviteLink build() {
return new CreateChatInviteLink(this);
}
}
}

View File

@@ -1,133 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.Message;
import okhttp3.RequestBody;
/**
* Use this method to forward messages of any kind.
* Service messages and messages 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<Message> {
@JsonProperty("chat_id")
private final String chatId;
@JsonProperty("message_thread_id")
private Long messageThreadId;
@JsonProperty("from_chat_id")
private final String fromChatId;
@JsonProperty("message_id")
private final long messageId;
@JsonProperty("disable_notification")
private Boolean disableNotification;
@JsonProperty("protect_content")
private Boolean protectContent;
@JsonProperty("video_start_timestamp")
private long videoStartTimestamp;
public ForwardMessage(String chatId, String fromChatId, long messageId) {
this.chatId = chatId;
this.fromChatId = fromChatId;
this.messageId = messageId;
}
public ForwardMessage(long chatId, String fromChatId, long messageId) {
this(String.valueOf(chatId), fromChatId, messageId);
}
public ForwardMessage(long chatId, long fromChatId, long messageId) {
this(String.valueOf(chatId), String.valueOf(fromChatId), messageId);
}
private ForwardMessage(Builder builder) {
chatId = builder.chatId;
setMessageThreadId(builder.messageThreadId);
fromChatId = builder.fromChatId;
messageId = builder.messageId;
setDisableNotification(builder.disableNotification);
setProtectContent(builder.protectContent);
setVideoStartTimestamp(builder.videoStartTimestamp);
}
public void setMessageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
}
public void setDisableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
}
public void setProtectContent(Boolean protectContent) {
this.protectContent = protectContent;
}
public void setVideoStartTimestamp(long videoStartTimestamp) {
this.videoStartTimestamp = videoStartTimestamp;
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "forwardMessage";
}
@JsonIgnore
@Override
public Class<Message> getResponseClass() {
return Message.class;
}
public static final class Builder {
private final String chatId;
private Long messageThreadId;
private final String fromChatId;
private final long messageId;
private Boolean disableNotification;
private Boolean protectContent;
private long videoStartTimestamp;
public Builder(String chatId, String fromChatId, long messageId) {
this.chatId = chatId;
this.fromChatId = fromChatId;
this.messageId = messageId;
}
public Builder messageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
return this;
}
public Builder disableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
return this;
}
public Builder protectContent(Boolean protectContent) {
this.protectContent = protectContent;
return this;
}
public Builder videoStartTimestamp(long videoStartTimestamp) {
this.videoStartTimestamp = videoStartTimestamp;
return this;
}
public ForwardMessage build() {
return new ForwardMessage(this);
}
}
}

View File

@@ -1,147 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.Message;
import okhttp3.RequestBody;
import java.util.ArrayList;
import java.util.List;
/**
* Use this method to forward multiple messages of any kind. If some of the specified messages can't be found or forwarded, they are skipped.
* Service messages and messages with protected content can't be forwarded. Album grouping is kept for forwarded messages.
* On success, an array of MessageId as {@link Long} of the sent messages is returned.
* @see Message#hasProtectedContent()
*/
@Jsonable
@NotTested
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class ForwardMessages implements TelegramApiMethod<Long[]> {
@JsonProperty("chat_id")
private final String chatId;
@JsonProperty("message_thread_id")
private Long messageThreadId;
@JsonProperty("from_chat_id")
private final String fromChatId;
@JsonProperty("message_id")
private final List<Long> messageIds;
@JsonProperty("disable_notification")
private Boolean disableNotification;
@JsonProperty("protect_content")
private Boolean protectContent;
public ForwardMessages(String chatId, String fromChatId, List<Long> messageIds) {
ArrayList<Long> sortedMessageIds = new ArrayList<>(messageIds.size() > 100 ? messageIds.subList(0, 100) : messageIds);
sortedMessageIds.sort(null);
this.chatId = chatId;
this.fromChatId = fromChatId;
this.messageIds = sortedMessageIds;
}
public ForwardMessages(long chatId, String fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), fromChatId, messageIds);
}
public ForwardMessages(String chatId, long fromChatId, List<Long> messageIds) {
this(chatId, String.valueOf(fromChatId), messageIds);
}
public ForwardMessages(long chatId, long fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), String.valueOf(fromChatId), messageIds);
}
private ForwardMessages(Builder builder) {
chatId = builder.chatId;
messageThreadId = builder.messageThreadId;
fromChatId = builder.fromChatId;
messageIds = builder.messageIds;
disableNotification = builder.disableNotification;
protectContent = builder.protectContent;
}
public void setMessageThreadId(long messageThreadId) {
this.messageThreadId = messageThreadId;
}
public void setDisableNotification(boolean disableNotification) {
this.disableNotification = disableNotification;
}
public void setProtectContent(boolean protectContent) {
this.protectContent = protectContent;
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "forwardMessages";
}
@JsonIgnore
@Override
public Class<Long[]> getResponseClass() {
return Long[].class;
}
public static final class Builder {
private final String chatId;
private Long messageThreadId;
private final String fromChatId;
private final List<Long> messageIds;
private Boolean disableNotification;
private Boolean protectContent;
public Builder(String chatId, String fromChatId, List<Long> messageIds) {
ArrayList<Long> sortedMessageIds = new ArrayList<>(messageIds.size() > 100 ? messageIds.subList(0, 100) : messageIds);
sortedMessageIds.sort(null);
this.chatId = chatId;
this.fromChatId = fromChatId;
this.messageIds = sortedMessageIds;
}
public Builder(long chatId, String fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), fromChatId, messageIds);
}
public Builder(String chatId, long fromChatId, List<Long> messageIds) {
this(chatId, String.valueOf(fromChatId), messageIds);
}
public Builder(long chatId, long fromChatId, List<Long> messageIds) {
this(String.valueOf(chatId), String.valueOf(fromChatId), messageIds);
}
public Builder messageThreadId(long messageThreadId) {
this.messageThreadId = messageThreadId;
return this;
}
public Builder disableNotification(boolean disableNotification) {
this.disableNotification = disableNotification;
return this;
}
public Builder protectContent(boolean protectContent) {
this.protectContent = protectContent;
return this;
}
public ForwardMessages build() {
return new ForwardMessages(this);
}
}
}

View File

@@ -3,6 +3,9 @@ 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.media.Animation;
import hdvtdev.telegram.core.objects.media.PhotoSize;
import hdvtdev.telegram.core.objects.message.MessageEntity;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)

View File

@@ -0,0 +1,4 @@
package hdvtdev.telegram.core.objects;
public interface GeneralObject {
}

View File

@@ -1,36 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.annotations.util.NotTested;
import hdvtdev.telegram.objects.ChatMember;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
/**
* Use this method to get a list of administrators in a chat, which aren't bots. Returns an Array of {@link ChatMember} objects.
* @param chatId
*/
@NotTested
public record GetChatAdministrators(@NotNull String chatId) implements TelegramApiMethod<ChatMember[]> {
public GetChatAdministrators(long chatId) {
this(String.valueOf(chatId));
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).build();
}
@Override
public String getMethodName() {
return "getChatAdministrators";
}
@Override
public Class<ChatMember[]> getResponseClass() {
return ChatMember[].class;
}
}

View File

@@ -1,38 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.objects.ChatMember;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
public record GetChatMember(@NotNull String chatId, long userId) implements TelegramApiMethod<ChatMember> {
public GetChatMember(long chatId, long userId) {
this(String.valueOf(chatId), userId);
}
public GetChatMember(String chatId, String userId) {
this(chatId, Long.parseLong(userId));
}
public GetChatMember(long chatId, String userId) {
this(String.valueOf(chatId), userId);
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("user_id", String.valueOf(userId)).build();
}
@Override
public String getMethodName() {
return "getChatMember";
}
@Override
public Class<ChatMember> getResponseClass() {
return ChatMember.class;
}
}

View File

@@ -1,23 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.objects.TelegramFile;
import okhttp3.FormBody;
import okhttp3.RequestBody;
public record GetFile(String fileId) implements TelegramApiMethod<TelegramFile> {
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("file_id", fileId).build();
}
@Override
public String getMethodName() {
return "getFile";
}
@Override
public Class<TelegramFile> getResponseClass() {
return TelegramFile.class;
}
}

View File

@@ -1,22 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.objects.User;
import okhttp3.RequestBody;
public final class GetMe implements TelegramApiMethod<User.Bot> {
@Override
public RequestBody getBody() {
return null;
}
@Override
public String getMethodName() {
return "getMe";
}
@Override
public Class<User.Bot> getResponseClass() {
return User.Bot.class;
}
}

View File

@@ -1,58 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.bot.BotCommand;
import hdvtdev.telegram.objects.bot.BotCommandScope;
import hdvtdev.telegram.objects.bot.BotCommandScopeDefault;
import okhttp3.RequestBody;
/**
* Use this method to get the current list of the bot's commands for the given scope and user language.
* Returns an Array of {@link BotCommand} objects. If commands aren't set, an empty list is returned.
* @param scope Scope of users. Defaults to {@link BotCommandScopeDefault}.
* @param languageCode A two-letter ISO 639-1 language code or an empty string
* @see BotCommandScope
* @since 1.0.0
*/
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public record GetMyCommands(
@JsonProperty("scope") BotCommandScope scope,
@JsonProperty("language_code") String languageCode
) implements TelegramApiMethod<BotCommand[]> {
public GetMyCommands() {
this(null, null);
}
public GetMyCommands(String languageCode) {
this(null, languageCode);
}
public GetMyCommands(BotCommandScope scope) {
this(scope, null);
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "getMyCommands";
}
@JsonIgnore
@Override
public Class<BotCommand[]> getResponseClass() {
return BotCommand[].class;
}
}

View File

@@ -1,42 +0,0 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
public record GetMyDescription(String languageCode) implements TelegramApiMethod<GetMyDescription.BotDescription> {
public GetMyDescription() {
this(null);
}
@Override
public RequestBody getBody() {
return languageCode == null ? null : new FormBody.Builder().add("language_code", languageCode).build();
}
@Override
public String getMethodName() {
return "getMyDescription";
}
@Override
public Class<BotDescription> getResponseClass() {
return BotDescription.class;
}
public record BotDescription(String description) {
@NotNull
@Override
public String toString() {
return description;
}
public boolean isEmpty() {
return description.isEmpty();
}
}
}

View File

@@ -1,38 +0,0 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
public record GetMyName(String languageCode) implements TelegramApiMethod<GetMyName.BotName> {
public GetMyName() {
this(null);
}
@Override
public RequestBody getBody() {
return this.languageCode == null ? null : new FormBody.Builder().add("language_code", this.languageCode).build();
}
@Override
public String getMethodName() {
return "getMyName";
}
@Override
public Class<BotName> getResponseClass() {
return BotName.class;
}
public record BotName(String name) {
@NotNull
@Override
public String toString() {
return this.name;
}
}
}

View File

@@ -1,42 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.objects.Update;
import okhttp3.RequestBody;
import java.util.ArrayList;
public record GetUpdates(
Long offset,
Integer limit,
Integer timeout
) implements TelegramApiMethod<Update[]> {
public GetUpdates() {
this(null, null, null);
}
@Override
public RequestBody getBody() {
return null;
}
@Override
public String getMethodName() {
ArrayList<String> params = new ArrayList<>(3);
if (offset != null) params.add("offset=" + offset);
if (limit != null) params.add("limit=" + limit);
if (timeout != null) params.add("timeout=" + timeout);
if (params.isEmpty()) {
return "getUpdates";
} else {
return "getUpdates?" + String.join("&", params);
}
}
@Override
public Class<Update[]> getResponseClass() {
return Update[].class;
}
}

View File

@@ -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.message.MessageEntity;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)

View File

@@ -1,37 +0,0 @@
package hdvtdev.telegram.core.objects;
import hdvtdev.telegram.objects.ChatInviteLink;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
/**
* Use this method to revoke an invite link created by the bot. If the primary link is revoked, a new link is automatically generated.
* The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights.
* Returns the revoked invite link as {@link ChatInviteLink} object.
* @param chatId Unique identifier of the target chat or username of the target channel (in the format @channelusername)
* @param link The invite link to revoke
*/
public record RevokeChatInviteLink(@NotNull String chatId, @NotNull String link) implements TelegramApiMethod<ChatInviteLink> {
public RevokeChatInviteLink(long chatId, @NotNull String link) {
this(String.valueOf(chatId), link);
}
@Override
public RequestBody getBody() {
return new FormBody.Builder().add("chat_id", chatId).add("link", link).build();
}
@Override
public String getMethodName() {
return "revokeChatInviteLink";
}
@Override
public Class<ChatInviteLink> getResponseClass() {
return ChatInviteLink.class;
}
}

View File

@@ -1,104 +0,0 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class SendChatAction implements TelegramApiMethod<Boolean> {
private String businessConnectionId;
private final String chatId;
private Long messageThreadId;
private final ChatAction chatAction;
public SendChatAction(@Nullable String businessConnectionId, @NotNull String chatId, @Nullable Long messageThreadId, @NotNull ChatAction chatAction) {
this.businessConnectionId = businessConnectionId;
this.chatId = chatId;
this.messageThreadId = messageThreadId;
this.chatAction = chatAction;
}
public SendChatAction(String chatId, ChatAction chatAction) {
this(null, chatId, null, chatAction);
}
public SendChatAction(long chatId, ChatAction chatAction) {
this(String.valueOf(chatId), chatAction);
}
private SendChatAction(Builder builder) {
this(builder.businessConnectionId, builder.chatId, builder.messageThreadId, builder.chatAction);
}
public void setBusinessConnectionId(String businessConnectionId) {
this.businessConnectionId = businessConnectionId;
}
public void setMessageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("chat_id", chatId).add("action", chatAction.equals(ChatAction.UPLOAD_FILE) ? ChatAction.UPLOAD_DOCUMENT.name() : chatAction.name());
if (businessConnectionId != null) builder.add("business_connection_id", businessConnectionId);
if (messageThreadId != null) builder.add("message_thread_id", String.valueOf(messageThreadId));
return builder.build();
}
@Override
public String getMethodName() {
return "sendChatAction";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
public enum ChatAction {
TYPING,
UPLOAD_PHOTO,
RECORD_VIDEO,
UPLOAD_VIDEO,
RECORD_VOICE,
UPLOAD_VOICE,
UPLOAD_DOCUMENT,
UPLOAD_FILE,
CHOOSE_STICKER,
FIND_LOCATION,
RECORD_VIDEO_NOTE,
UPLOAD_VIDEO_NOTE
}
public static final class Builder {
private String businessConnectionId;
private final String chatId;
private Long messageThreadId;
private final ChatAction chatAction;
public Builder(String chatId, ChatAction chatAction) {
this.chatId = chatId;
this.chatAction = chatAction;
}
public Builder businessConnectionId(String businessConnectionId) {
this.businessConnectionId = businessConnectionId;
return this;
}
public Builder messageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
return this;
}
public SendChatAction build() {
return new SendChatAction(this);
}
}
}

View File

@@ -1,133 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.Message;
import hdvtdev.telegram.objects.ReplyMarkup;
import hdvtdev.telegram.objects.ReplyParameters;
import okhttp3.RequestBody;
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class SendDice implements TelegramApiMethod<Message> {
@JsonProperty("chat_id")
private final String chatId;
@JsonProperty("business_connection_id")
private String businessConnectionId;
@JsonProperty("message_thread_id")
private Long messageThreadId;
@JsonProperty("emoji")
private String emoji;
@JsonProperty("disable_notification")
private Boolean disableNotification;
@JsonProperty("protect_content")
private Boolean protectContent;
@JsonProperty("allow_paid_broadcast")
private Boolean allowPaidBroadcast;
@JsonProperty("message_effect_id")
private String messageEffectId;
@JsonProperty("reply_parameters")
private ReplyParameters replyParameters;
@JsonProperty("reply_markup")
private ReplyMarkup replyMarkup;
public SendDice(String chatId) {
this.chatId = chatId;
}
public SendDice(long chatId) {
this(String.valueOf(chatId));
}
public SendDice(String chatId, Emoji emoji) {
this.emoji = emoji.getEmoji();
this.chatId = chatId;
}
public SendDice(long chatId, Emoji emoji) {
this(String.valueOf(chatId), emoji);
}
public void setBusinessConnectionId(String businessConnectionId) {
this.businessConnectionId = businessConnectionId;
}
public void setMessageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
}
public void setEmoji(Emoji emoji) {
this.emoji = emoji.getEmoji();
}
public void setDisableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
}
public void setProtectContent(Boolean protectContent) {
this.protectContent = protectContent;
}
public void setAllowPaidBroadcast(Boolean allowPaidBroadcast) {
this.allowPaidBroadcast = allowPaidBroadcast;
}
public void setMessageEffectId(String messageEffectId) {
this.messageEffectId = messageEffectId;
}
public void setReplyParameters(ReplyParameters replyParameters) {
this.replyParameters = replyParameters;
}
public void setReplyMarkup(ReplyMarkup replyMarkup) {
this.replyMarkup = replyMarkup;
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "sendDice";
}
@JsonIgnore
@Override
public Class<Message> getResponseClass() {
return Message.class;
}
public enum Emoji {
DICE("🎲"),
DART("🎯"),
BASKETBALL("🏀"),
FOOTBALL(""),
BOWLING("🎳"),
SLOT_MACHINE("🎰");
private final String emoji;
Emoji(String emoji) {
this.emoji = emoji;
}
public String getEmoji() {
return emoji;
}
}
}

View File

@@ -1,226 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.*;
import hdvtdev.telegram.util.ParseMode;
import okhttp3.RequestBody;
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class SendMessage implements TelegramApiMethod<Message> {
@JsonProperty("chat_id")
private final String chatId;
@JsonProperty("text")
private final String text;
@JsonProperty("business_connection_id")
private String businessConnectionId;
@JsonProperty("message_thread_id")
private Long messageThreadId;
@JsonProperty("parse_mode")
private ParseMode parseMode;
@JsonProperty("entities")
private MessageEntity[] entities;
@JsonProperty("link_preview_options")
private LinkPreviewOptions linkPreviewOptions;
@JsonProperty("disable_notification")
private Boolean disableNotification;
@JsonProperty("protect_content")
private Boolean protectContent;
@JsonProperty("allow_paid_broadcast")
private Boolean allowPaidBroadcast;
@JsonProperty("message_effect_id")
private String messageEffectId;
@JsonProperty("reply_parameters")
private ReplyParameters replyParameters;
@JsonProperty("reply_markup")
private ReplyMarkup replyMarkup;
private SendMessage(Builder builder) {
chatId = builder.chatId;
text = builder.text;
setBusinessConnectionId(builder.businessConnectionId);
setMessageThreadId(builder.messageThreadId);
setParseMode(builder.parseMode);
setEntities(builder.entities);
setLinkPreviewOptions(builder.linkPreviewOptions);
setDisableNotification(builder.disableNotification);
setProtectContent(builder.protectContent);
setAllowPaidBroadcast(builder.allowPaidBroadcast);
setMessageEffectId(builder.messageEffectId);
setReplyParameters(builder.replyParameters);
setReplyMarkup(builder.replyMarkup);
}
public void setLinkPreviewOptions(LinkPreviewOptions linkPreviewOptions) {
this.linkPreviewOptions = linkPreviewOptions;
}
public void setBusinessConnectionId(String businessConnectionId) {
this.businessConnectionId = businessConnectionId;
}
public void setMessageThreadId(Long messageThreadId) {
this.messageThreadId = messageThreadId;
}
public void setParseMode(ParseMode parseMode) {
this.parseMode = parseMode;
}
public void setEntities(MessageEntity[] entities) {
this.entities = entities;
}
public void setDisableNotification(Boolean disableNotification) {
this.disableNotification = disableNotification;
}
public void setProtectContent(Boolean protectContent) {
this.protectContent = protectContent;
}
public void setAllowPaidBroadcast(Boolean allowPaidBroadcast) {
this.allowPaidBroadcast = allowPaidBroadcast;
}
public void setMessageEffectId(String messageEffectId) {
this.messageEffectId = messageEffectId;
}
public void setReplyParameters(ReplyParameters replyParameters) {
this.replyParameters = replyParameters;
}
public void setReplyToMessage(long messageId) {
this.replyParameters = new ReplyParameters(messageId, chatId);
}
public void setReplyMarkup(ReplyMarkup replyMarkup) {
this.replyMarkup = replyMarkup;
}
public SendMessage(String chatId, String text) {
if (chatId.isEmpty() || text.isEmpty())
throw new IllegalArgumentException("chatId or/and message (text) cannot be empty.");
this.chatId = chatId;
this.text = text;
}
public SendMessage(long chatIdAsLong, String text) {
this(String.valueOf(chatIdAsLong), text);
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "sendMessage";
}
@JsonIgnore
@Override
public Class<Message> getResponseClass() {
return Message.class;
}
public static final class Builder {
private final String chatId;
private final String text;
private String businessConnectionId;
private Long messageThreadId;
private ParseMode parseMode;
private MessageEntity[] entities;
private LinkPreviewOptions linkPreviewOptions;
private Boolean disableNotification;
private Boolean protectContent;
private Boolean allowPaidBroadcast;
private String messageEffectId;
private ReplyParameters replyParameters;
private ReplyMarkup replyMarkup;
public Builder(long chatId, String text) {
this(String.valueOf(chatId), text);
}
public Builder(String chatId, String text) {
this.chatId = chatId;
this.text = text;
}
public Builder businessConnectionId(String val) {
businessConnectionId = val;
return this;
}
public Builder messageThreadId(Long val) {
messageThreadId = val;
return this;
}
public Builder parseMode(ParseMode val) {
parseMode = val;
return this;
}
public Builder entities(MessageEntity[] val) {
entities = val;
return this;
}
public Builder linkPreviewOptions(LinkPreviewOptions val) {
linkPreviewOptions = val;
return this;
}
public Builder disableNotification() {
disableNotification = true;
return this;
}
public Builder protectContent() {
protectContent = true;
return this;
}
public Builder allowPaidBroadcast() {
allowPaidBroadcast = true;
return this;
}
public Builder messageEffectId(String val) {
messageEffectId = val;
return this;
}
public Builder replyParameters(ReplyParameters val) {
replyParameters = val;
return this;
}
public Builder replyToMessage(long val) {
replyParameters = new ReplyParameters(val, this.chatId);
return this;
}
public Builder replyMarkup(ReplyMarkup val) {
replyMarkup = val;
return this;
}
public SendMessage build() {
return new SendMessage(this);
}
}
}

View File

@@ -1,100 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.ReactionType;
import okhttp3.RequestBody;
import java.util.List;
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SetMessageReaction implements TelegramApiMethod<Boolean> {
@JsonProperty("chat_id")
private final String chatId;
@JsonProperty("message_id")
private final long messageId;
@JsonProperty("reaction")
private List<ReactionType> reactions;
@JsonProperty("is_big")
private Boolean isBig;
public SetMessageReaction(String chatId, long messageId) {
this.chatId = chatId;
this.messageId = messageId;
}
public SetMessageReaction(long chatId, long messageId) {
this.chatId = String.valueOf(chatId);
this.messageId = messageId;
}
private SetMessageReaction(Builder builder) {
chatId = builder.chatId;
messageId = builder.messageId;
setReactions(builder.reactions);
isBig = builder.isBig;
}
public void setReactions(List<ReactionType> reactions) {
this.reactions = reactions;
}
public void setBig(Boolean big) {
isBig = big;
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "setMessageReaction";
}
@JsonIgnore
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
public static final class Builder {
private final String chatId;
private final long messageId;
private List<ReactionType> reactions;
private Boolean isBig;
public Builder(String chatId, long messageId) {
this.chatId = chatId;
this.messageId = messageId;
}
public Builder(long chatId, long messageId) {
this.chatId = String.valueOf(chatId);
this.messageId = messageId;
}
public Builder reactions(List<ReactionType> reactions) {
this.reactions = reactions;
return this;
}
public Builder isBig(Boolean isBig) {
this.isBig = isBig;
return this;
}
public SetMessageReaction build() {
return new SetMessageReaction(this);
}
}
}

View File

@@ -1,100 +0,0 @@
package hdvtdev.telegram.core.objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import hdvtdev.telegram.annotations.util.Jsonable;
import hdvtdev.telegram.objects.bot.BotCommand;
import hdvtdev.telegram.objects.bot.BotCommandScope;
import okhttp3.RequestBody;
import java.util.List;
@Jsonable
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class SetMyCommands implements TelegramApiMethod<Boolean> {
@JsonProperty("commands")
private final List<BotCommand> commands;
@JsonProperty("scope")
private Object scope;
@JsonProperty("language_code")
private String languageCode;
public SetMyCommands(List<BotCommand> commands, Object scope, String languageCode) {
this.commands = commands;
this.scope = scope;
this.languageCode = languageCode;
}
public SetMyCommands(BotCommand... commands) {
this.commands = List.of(commands);
}
public SetMyCommands(List<BotCommand> commands) {
this.commands = commands;
}
private SetMyCommands(Builder builder) {
commands = builder.commands;
setScope(builder.scope);
setLanguageCode(builder.languageCode);
}
public void setScope(Object scope) {
this.scope = scope;
}
public void setLanguageCode(String languageCode) {
this.languageCode = languageCode;
}
@JsonIgnore
@Override
public RequestBody getBody() {
return null;
}
@JsonIgnore
@Override
public String getMethodName() {
return "setMyCommands";
}
@JsonIgnore
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
public static final class Builder {
private final List<BotCommand> commands;
private Object scope;
private String languageCode;
public Builder(List<BotCommand> commands) {
this.commands = commands;
}
public Builder(BotCommand... commands) {
this.commands = List.of(commands);
}
public Builder scope(BotCommandScope scope) {
this.scope = scope;
return this;
}
public Builder languageCode(String languageCode) {
this.languageCode = languageCode;
return this;
}
public SetMyCommands build() {
return new SetMyCommands(this);
}
}
}

View File

@@ -1,41 +0,0 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
/**
* Use this method to change the bot's description, which is shown in the chat with the bot if the chat is empty.
* Returns {@code true} on success.
* @param description New bot description; 0-512 characters. Pass an empty string to remove the dedicated description for the given language.
* @param languageCode A two-letter ISO 639-1 language code. If empty, the description will be applied to all users for whose language there is no dedicated description.
*/
public record SetMyDescription(String description, String languageCode) implements TelegramApiMethod<Boolean> {
public SetMyDescription() {
this(null, null);
}
public SetMyDescription(String description) {
this(description, null);
}
@Override
public RequestBody getBody() {
if (description == null) {
return null;
}
FormBody.Builder builder = new FormBody.Builder().add("description", description);
if (languageCode != null) builder.add("language_code", languageCode);
return builder.build();
}
@Override
public String getMethodName() {
return "setMyDescription";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
}

View File

@@ -1,28 +0,0 @@
package hdvtdev.telegram.core.objects;
import okhttp3.FormBody;
import okhttp3.RequestBody;
public record SetMyName(String name, String languageCode) implements TelegramApiMethod<Boolean> {
public SetMyName(String name) {
this(name, null);
}
@Override
public RequestBody getBody() {
FormBody.Builder builder = new FormBody.Builder().add("name", this.name);
if (languageCode != null) builder.add("language_code", this.languageCode);
return builder.build();
}
@Override
public String getMethodName() {
return "setMyName";
}
@Override
public Class<Boolean> getResponseClass() {
return Boolean.class;
}
}

View File

@@ -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.media.PhotoSize;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)

View File

@@ -1,13 +0,0 @@
package hdvtdev.telegram.core.objects;
import okhttp3.RequestBody;
public interface TelegramApiMethod<T> {
RequestBody getBody();
String getMethodName();
Class<T> getResponseClass();
}

View File

@@ -4,6 +4,25 @@ 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;
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 org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -33,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;
}

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.objects.background;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

View File

@@ -1,4 +1,27 @@
package hdvtdev.telegram.core.objects.background;
public class BackgroundFillDeserializer {
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
public final class BackgroundFillDeserializer extends JsonDeserializer<BackgroundFill> {
@Override
public BackgroundFill deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
ObjectCodec codec = parser.getCodec();
JsonNode node = codec.readTree(parser);
String type = node.get("type").asText();
return switch (type) {
case "solid" -> codec.treeToValue(node, BackgroundFillSolid.class);
case "gradient" -> codec.treeToValue(node, BackgroundFillGradient.class);
case "freeform_gradient" -> codec.treeToValue(node, BackgroundFillFreeformGradient.class);
default -> throw new IllegalArgumentException("Unknown type: " + type);
};
}
}

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.objects.background;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.objects.background;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

View File

@@ -1,4 +1,4 @@
package hdvtdev.telegram.core.objects;
package hdvtdev.telegram.core.objects.background;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

Some files were not shown because too many files have changed in this diff Show More