2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.telegram.internal.action;
15 import static org.openhab.binding.telegram.internal.TelegramBindingConstants.PHOTO_EXTENSIONS;
17 import java.io.ByteArrayInputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.net.MalformedURLException;
23 import java.nio.charset.StandardCharsets;
24 import java.nio.file.Path;
25 import java.util.Base64;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.TimeUnit;
29 import org.eclipse.jdt.annotation.NonNullByDefault;
30 import org.eclipse.jdt.annotation.Nullable;
31 import org.eclipse.jetty.client.HttpClient;
32 import org.eclipse.jetty.client.api.Authentication;
33 import org.eclipse.jetty.client.api.AuthenticationStore;
34 import org.eclipse.jetty.client.api.ContentResponse;
35 import org.eclipse.jetty.client.api.Request;
36 import org.eclipse.jetty.client.util.FutureResponseListener;
37 import org.eclipse.jetty.http.HttpHeader;
38 import org.eclipse.jetty.http.HttpMethod;
39 import org.openhab.binding.telegram.internal.TelegramHandler;
40 import org.openhab.core.automation.annotation.ActionInput;
41 import org.openhab.core.automation.annotation.RuleAction;
42 import org.openhab.core.thing.binding.ThingActions;
43 import org.openhab.core.thing.binding.ThingActionsScope;
44 import org.openhab.core.thing.binding.ThingHandler;
45 import org.osgi.service.component.annotations.Component;
46 import org.osgi.service.component.annotations.ServiceScope;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
51 import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup;
52 import com.pengrad.telegrambot.request.AnswerCallbackQuery;
53 import com.pengrad.telegrambot.request.DeleteMessage;
54 import com.pengrad.telegrambot.request.EditMessageReplyMarkup;
55 import com.pengrad.telegrambot.request.SendAnimation;
56 import com.pengrad.telegrambot.request.SendMessage;
57 import com.pengrad.telegrambot.request.SendPhoto;
58 import com.pengrad.telegrambot.request.SendVideo;
59 import com.pengrad.telegrambot.response.BaseResponse;
60 import com.pengrad.telegrambot.response.SendResponse;
63 * Provides the actions for the Telegram API.
65 * @author Alexander Krasnogolowy - Initial contribution
67 @Component(scope = ServiceScope.PROTOTYPE, service = TelegramActions.class)
68 @ThingActionsScope(name = "telegram")
70 public class TelegramActions implements ThingActions {
71 private final Logger logger = LoggerFactory.getLogger(TelegramActions.class);
72 private @Nullable TelegramHandler handler;
74 private boolean evaluateResponse(@Nullable BaseResponse response) {
75 if (response != null && !response.isOk()) {
76 logger.warn("Failed to send telegram message: {}", response.description());
82 private static class BasicResult implements Authentication.Result {
84 private final HttpHeader header;
85 private final URI uri;
86 private final String value;
88 public BasicResult(HttpHeader header, URI uri, String value) {
100 public void apply(@Nullable Request request) {
101 if (request != null) {
102 request.header(this.header, this.value);
107 public String toString() {
108 return String.format("Basic authentication result for %s", this.uri);
112 @RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
113 public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
114 @ActionInput(name = "callbackId") @Nullable String callbackId,
115 @ActionInput(name = "messageId") @Nullable Long messageId,
116 @ActionInput(name = "message") @Nullable String message) {
117 if (chatId == null) {
118 logger.warn("chatId not defined; action skipped.");
121 if (messageId == null) {
122 logger.warn("messageId not defined; action skipped.");
125 TelegramHandler localHandler = handler;
126 if (localHandler != null) {
127 if (callbackId != null) {
128 AnswerCallbackQuery answerCallbackQuery = new AnswerCallbackQuery(callbackId);
129 // we could directly set the text here, but this
130 // doesn't result in a real message only in a
131 // little popup or in an alert, so the only purpose
132 // is to stop the progress bar on client side
133 logger.debug("Answering query with callbackId '{}'", callbackId);
134 if (!evaluateResponse(localHandler.execute(answerCallbackQuery))) {
138 EditMessageReplyMarkup editReplyMarkup = new EditMessageReplyMarkup(chatId, messageId.intValue())
139 .replyMarkup(new InlineKeyboardMarkup(new InlineKeyboardButton[0]));// remove reply markup from
141 if (!evaluateResponse(localHandler.execute(editReplyMarkup))) {
144 return message != null ? sendTelegram(chatId, message) : true;
149 @RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
150 public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
151 @ActionInput(name = "replyId") @Nullable String replyId,
152 @ActionInput(name = "message") @Nullable String message) {
153 if (replyId == null) {
154 logger.warn("ReplyId not defined; action skipped.");
157 if (chatId == null) {
158 logger.warn("chatId not defined; action skipped.");
161 TelegramHandler localHandler = handler;
162 if (localHandler != null) {
163 String callbackId = localHandler.getCallbackId(chatId, replyId);
164 if (callbackId != null) {
165 logger.debug("AnswerCallbackQuery for chatId {} and replyId {} is the callbackId {}", chatId, replyId,
168 Integer messageId = localHandler.removeMessageId(chatId, replyId);
169 logger.debug("remove messageId {} for chatId {} and replyId {}", messageId, chatId, replyId);
171 return sendTelegramAnswer(chatId, callbackId, messageId != null ? Long.valueOf(messageId) : null, message);
176 @RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
177 public boolean sendTelegramAnswer(@ActionInput(name = "replyId") @Nullable String replyId,
178 @ActionInput(name = "message") @Nullable String message) {
179 TelegramHandler localHandler = handler;
180 if (localHandler != null) {
181 for (Long chatId : localHandler.getReceiverChatIds()) {
182 if (!sendTelegramAnswer(chatId, replyId, message)) {
190 @RuleAction(label = "send a message", description = "Send a Telegram message using the Telegram API.")
191 public boolean sendTelegram(@ActionInput(name = "chatId") @Nullable Long chatId,
192 @ActionInput(name = "message") @Nullable String message) {
193 return sendTelegramGeneral(chatId, message, (String) null);
196 @RuleAction(label = "send a message", description = "Send a Telegram message using the Telegram API.")
197 public boolean sendTelegram(@ActionInput(name = "message") @Nullable String message) {
198 TelegramHandler localHandler = handler;
199 if (localHandler != null) {
200 for (Long chatId : localHandler.getReceiverChatIds()) {
201 if (!sendTelegram(chatId, message)) {
209 @RuleAction(label = "send a query", description = "Send a Telegram Query using the Telegram API.")
210 public boolean sendTelegramQuery(@ActionInput(name = "chatId") @Nullable Long chatId,
211 @ActionInput(name = "message") @Nullable String message,
212 @ActionInput(name = "replyId") @Nullable String replyId,
213 @ActionInput(name = "buttons") @Nullable String... buttons) {
214 return sendTelegramGeneral(chatId, message, replyId, buttons);
217 @RuleAction(label = "send a query", description = "Send a Telegram Query using the Telegram API.")
218 public boolean sendTelegramQuery(@ActionInput(name = "message") @Nullable String message,
219 @ActionInput(name = "replyId") @Nullable String replyId,
220 @ActionInput(name = "buttons") @Nullable String... buttons) {
221 TelegramHandler localHandler = handler;
222 if (localHandler != null) {
223 for (Long chatId : localHandler.getReceiverChatIds()) {
224 if (!sendTelegramQuery(chatId, message, replyId, buttons)) {
232 private boolean sendTelegramGeneral(@ActionInput(name = "chatId") @Nullable Long chatId, @Nullable String message,
233 @Nullable String replyId, @Nullable String... buttons) {
234 if (message == null) {
235 logger.warn("Message not defined; action skipped.");
238 if (chatId == null) {
239 logger.warn("chatId not defined; action skipped.");
242 TelegramHandler localHandler = handler;
243 if (localHandler != null) {
244 SendMessage sendMessage = new SendMessage(chatId, message);
245 if (localHandler.getParseMode() != null) {
246 sendMessage.parseMode(localHandler.getParseMode());
248 if (replyId != null) {
249 if (!replyId.contains(" ")) {
250 if (buttons.length > 0) {
251 InlineKeyboardButton[][] keyboard2D = new InlineKeyboardButton[1][];
252 InlineKeyboardButton[] keyboard = new InlineKeyboardButton[buttons.length];
253 keyboard2D[0] = keyboard;
254 for (int i = 0; i < buttons.length; i++) {
255 keyboard[i] = new InlineKeyboardButton(buttons[i]).callbackData(replyId + " " + buttons[i]);
257 InlineKeyboardMarkup keyBoardMarkup = new InlineKeyboardMarkup(keyboard2D);
258 sendMessage.replyMarkup(keyBoardMarkup);
261 "The replyId {} for message {} is given, but no buttons are defined. ReplyMarkup will be ignored.",
265 logger.warn("replyId {} must not contain spaces. ReplyMarkup will be ignored.", replyId);
268 SendResponse retMessage = null;
270 retMessage = localHandler.execute(sendMessage);
271 } catch (Exception e) {
272 logger.warn("Exception occured whilst sending message:{}", e.getMessage());
274 if (!evaluateResponse(retMessage)) {
277 if (replyId != null && retMessage != null) {
278 logger.debug("Adding chatId {}, replyId {} and messageId {}", chatId, replyId,
279 retMessage.message().messageId());
280 localHandler.addMessageId(chatId, replyId, retMessage.message().messageId());
287 @RuleAction(label = "delete a query", description = "Delete a Query using the Telegram API.")
288 public boolean deleteTelegramQuery(@ActionInput(name = "replyId") @Nullable String replyId) {
289 if (replyId == null) {
290 logger.warn("deleteTelegramQuery() - replyId not passed!");
293 TelegramHandler localHandler = handler;
294 if (localHandler == null) {
295 logger.debug("deleteTelegramQuery() - localHandler is null!");
299 Integer messageId = 0;
300 BaseResponse response = null;
302 for (Long chatId : localHandler.getReceiverChatIds()) {
303 messageId = localHandler.removeMessageId(chatId, replyId);
304 if (messageId == null) {
305 logger.debug("deleteTelegramQuery() - messageId not found!");
308 DeleteMessage deleteMessage = new DeleteMessage(chatId, messageId);
309 response = localHandler.execute(deleteMessage);
311 if (response == null || response.errorCode() != 0) {
312 logger.debug("deleteTelegramQuery() - DeleteMessage execution not successful! Response: {}", response);
318 } // public boolean deleteTelegramQuery(String replyId)
320 @RuleAction(label = "send a message", description = "Send a Telegram using the Telegram API.")
321 public boolean sendTelegram(@ActionInput(name = "chatId") @Nullable Long chatId,
322 @ActionInput(name = "message") @Nullable String message,
323 @ActionInput(name = "args") @Nullable Object... args) {
324 if (message == null) {
327 return sendTelegram(chatId, String.format(message, args));
330 @RuleAction(label = "send a message", description = "Send a Telegram using the Telegram API.")
331 public boolean sendTelegram(@ActionInput(name = "message") @Nullable String message,
332 @ActionInput(name = "args") @Nullable Object... args) {
333 TelegramHandler localHandler = handler;
334 if (localHandler != null) {
335 for (Long chatId : localHandler.getReceiverChatIds()) {
336 if (!sendTelegram(chatId, message, args)) {
344 @RuleAction(label = "send a photo", description = "Send a picture using the Telegram API.")
345 public boolean sendTelegramPhoto(@ActionInput(name = "chatId") @Nullable Long chatId,
346 @ActionInput(name = "photoURL") @Nullable String photoURL,
347 @ActionInput(name = "caption") @Nullable String caption) {
348 return sendTelegramPhoto(chatId, photoURL, caption, null, null);
351 @RuleAction(label = "send a photo", description = "Send a picture using the Telegram API.")
352 public boolean sendTelegramPhoto(@ActionInput(name = "chatId") @Nullable Long chatId,
353 @ActionInput(name = "photoURL") @Nullable String photoURL,
354 @ActionInput(name = "caption") @Nullable String caption,
355 @ActionInput(name = "username") @Nullable String username,
356 @ActionInput(name = "password") @Nullable String password) {
357 if (photoURL == null) {
358 logger.warn("Photo URL not defined; unable to retrieve photo for sending.");
361 if (chatId == null) {
362 logger.warn("chatId not defined; action skipped.");
365 String lowercasePhotoUrl = photoURL.toLowerCase();
366 TelegramHandler localHandler = handler;
367 if (localHandler != null) {
368 final SendPhoto sendPhoto;
369 if (lowercasePhotoUrl.startsWith("http")) {
370 logger.debug("Http based URL for photo provided.");
371 HttpClient client = localHandler.getClient();
372 if (client == null) {
375 Request request = client.newRequest(photoURL).method(HttpMethod.GET).timeout(30, TimeUnit.SECONDS);
376 if (username != null && password != null) {
377 AuthenticationStore auth = client.getAuthenticationStore();
378 URI uri = URI.create(photoURL);
379 auth.addAuthenticationResult(
380 new BasicResult(HttpHeader.AUTHORIZATION, uri, "Basic " + Base64.getEncoder()
381 .encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8))));
384 // API has 10mb limit to jpg file size, without this it can only accept 2mb
385 FutureResponseListener listener = new FutureResponseListener(request, 10 * 1024 * 1024);
386 request.send(listener);
387 ContentResponse contentResponse = listener.get();
388 if (contentResponse.getStatus() == 200) {
389 byte[] fileContent = contentResponse.getContent();
390 sendPhoto = new SendPhoto(chatId, fileContent);
392 if (contentResponse.getStatus() == 401
393 && contentResponse.getHeaders().get(HttpHeader.WWW_AUTHENTICATE).contains("igest")) {
394 logger.warn("Download from {} failed due to no BASIC http auth support.", photoURL);
396 logger.warn("Download from {} failed with status: {}", photoURL,
397 contentResponse.getStatus());
399 sendTelegram(chatId, caption + ":Download failed with status " + contentResponse.getStatus());
402 } catch (InterruptedException | ExecutionException e) {
403 logger.warn("Download from {} failed with exception: {}", photoURL, e.getMessage());
406 } else if (lowercasePhotoUrl.startsWith("file:")
407 || PHOTO_EXTENSIONS.stream().anyMatch(lowercasePhotoUrl::endsWith)) {
408 logger.debug("Read file from local file system: {}", photoURL);
409 String temp = photoURL;
410 if (!lowercasePhotoUrl.startsWith("file:")) {
411 temp = "file://" + photoURL;
414 sendPhoto = new SendPhoto(chatId, Path.of(new URL(temp).getPath()).toFile());
415 } catch (MalformedURLException e) {
416 logger.warn("Malformed URL: {}", photoURL);
420 logger.debug("Base64 image provided; converting to binary.");
421 final String photoB64Data;
422 if (photoURL.startsWith("data:")) { // support data URI scheme
423 String[] photoURLParts = photoURL.split(",");
424 if (photoURLParts.length > 1) {
425 photoB64Data = photoURLParts[1];
427 logger.warn("The provided base64 string is not a valid data URI scheme");
431 photoB64Data = photoURL;
433 InputStream is = Base64.getDecoder()
434 .wrap(new ByteArrayInputStream(photoB64Data.getBytes(StandardCharsets.UTF_8)));
436 byte[] photoBytes = is.readAllBytes();
437 sendPhoto = new SendPhoto(chatId, photoBytes);
438 } catch (IOException e) {
439 logger.warn("Malformed base64 string: {}", e.getMessage());
443 if (caption != null) {
444 sendPhoto.caption(caption);
446 if (localHandler.getParseMode() != null) {
447 sendPhoto.parseMode(localHandler.getParseMode());
449 return evaluateResponse(localHandler.execute(sendPhoto));
454 @RuleAction(label = "send a photo", description = "Send a Picture using the Telegram API.")
455 public boolean sendTelegramPhoto(@ActionInput(name = "photoURL") @Nullable String photoURL,
456 @ActionInput(name = "caption") @Nullable String caption,
457 @ActionInput(name = "username") @Nullable String username,
458 @ActionInput(name = "password") @Nullable String password) {
459 TelegramHandler localHandler = handler;
460 if (localHandler != null) {
461 for (Long chatId : localHandler.getReceiverChatIds()) {
462 if (!sendTelegramPhoto(chatId, photoURL, caption, username, password)) {
470 @RuleAction(label = "send a photo", description = "Send a Picture using the Telegram API.")
471 public boolean sendTelegramPhoto(@ActionInput(name = "photoURL") @Nullable String photoURL,
472 @ActionInput(name = "caption") @Nullable String caption) {
473 return sendTelegramPhoto(photoURL, caption, null, null);
476 @RuleAction(label = "send animation", description = "Send an Animation using the Telegram API.")
477 public boolean sendTelegramAnimation(@ActionInput(name = "animationURL") @Nullable String animationURL,
478 @ActionInput(name = "caption") @Nullable String caption) {
479 TelegramHandler localHandler = handler;
480 if (localHandler != null) {
481 for (Long chatId : localHandler.getReceiverChatIds()) {
482 if (!sendTelegramAnimation(chatId, animationURL, caption)) {
490 @RuleAction(label = "send animation", description = "Send an Animation using the Telegram API.")
491 public boolean sendTelegramAnimation(@ActionInput(name = "chatId") @Nullable Long chatId,
492 @ActionInput(name = "animationURL") @Nullable String animationURL,
493 @ActionInput(name = "caption") @Nullable String caption) {
494 if (animationURL == null) {
495 logger.warn("Animation URL not defined; unable to retrieve video for sending.");
498 if (chatId == null) {
499 logger.warn("chatId not defined; action skipped.");
502 TelegramHandler localHandler = handler;
503 if (localHandler != null) {
504 final SendAnimation sendAnimation;
505 if (animationURL.toLowerCase().startsWith("http")) {
506 // load image from url
507 logger.debug("Animation URL provided.");
508 HttpClient client = localHandler.getClient();
509 if (client == null) {
512 Request request = client.newRequest(animationURL).method(HttpMethod.GET).timeout(30, TimeUnit.SECONDS);
514 // 50mb limit to file size
515 FutureResponseListener listener = new FutureResponseListener(request, 50 * 1024 * 1024);
516 request.send(listener);
517 ContentResponse contentResponse = listener.get();
518 if (contentResponse.getStatus() == 200) {
519 byte[] fileContent = contentResponse.getContent();
520 sendAnimation = new SendAnimation(chatId, fileContent);
522 logger.warn("Download from {} failed with status: {}", animationURL,
523 contentResponse.getStatus());
524 sendTelegram(chatId, caption + ":Download failed with status " + contentResponse.getStatus());
527 } catch (InterruptedException | ExecutionException e) {
528 logger.warn("Download from {} failed with exception: {}", animationURL, e.getMessage());
532 String temp = animationURL;
533 if (!animationURL.toLowerCase().startsWith("file:")) {
534 temp = "file://" + animationURL;
536 // Load video from local file system
537 logger.debug("Read file from local file system: {}", animationURL);
539 sendAnimation = new SendAnimation(chatId, Path.of(new URL(temp).getPath()).toFile());
540 } catch (MalformedURLException e) {
541 logger.warn("Malformed URL, should start with http or file: {}", animationURL);
545 if (caption != null) {
546 sendAnimation.caption(caption);
548 if (localHandler.getParseMode() != null) {
549 sendAnimation.parseMode(localHandler.getParseMode());
551 return evaluateResponse(localHandler.execute(sendAnimation));
556 @RuleAction(label = "send video", description = "Send a Video using the Telegram API.")
557 public boolean sendTelegramVideo(@ActionInput(name = "videoURL") @Nullable String videoURL,
558 @ActionInput(name = "caption") @Nullable String caption) {
559 TelegramHandler localHandler = handler;
560 if (localHandler != null) {
561 for (Long chatId : localHandler.getReceiverChatIds()) {
562 if (!sendTelegramVideo(chatId, videoURL, caption)) {
570 @RuleAction(label = "send video", description = "Send a Video using the Telegram API.")
571 public boolean sendTelegramVideo(@ActionInput(name = "chatId") @Nullable Long chatId,
572 @ActionInput(name = "videoURL") @Nullable String videoURL,
573 @ActionInput(name = "caption") @Nullable String caption) {
574 final SendVideo sendVideo;
575 if (videoURL == null) {
576 logger.warn("Video URL not defined; unable to retrieve video for sending.");
579 if (chatId == null) {
580 logger.warn("chatId not defined; action skipped.");
583 TelegramHandler localHandler = handler;
584 if (localHandler != null) {
585 if (videoURL.toLowerCase().startsWith("http")) {
586 logger.debug("Video http://URL provided.");
587 HttpClient client = localHandler.getClient();
588 if (client == null) {
591 Request request = client.newRequest(videoURL).method(HttpMethod.GET).timeout(30, TimeUnit.SECONDS);
593 // 50mb limit to file size
594 FutureResponseListener listener = new FutureResponseListener(request, 50 * 1024 * 1024);
595 request.send(listener);
596 ContentResponse contentResponse = listener.get();
597 if (contentResponse.getStatus() == 200) {
598 byte[] fileContent = contentResponse.getContent();
599 sendVideo = new SendVideo(chatId, fileContent);
601 if (contentResponse.getStatus() == 401
602 && contentResponse.getHeaders().get(HttpHeader.WWW_AUTHENTICATE).contains("igest")) {
603 logger.warn("Download from {} failed due to no BASIC http auth support.", videoURL);
605 logger.warn("Download from {} failed with status: {}", videoURL,
606 contentResponse.getStatus());
608 sendTelegram(chatId, caption + ":Download failed with status " + contentResponse.getStatus());
611 } catch (InterruptedException | ExecutionException e) {
612 logger.warn("Download from {} failed with exception: {}", videoURL, e.getMessage());
616 String temp = videoURL;
617 if (!videoURL.toLowerCase().startsWith("file:")) {
618 temp = "file://" + videoURL;
620 // Load video from local file system with file://path
621 logger.debug("Read file from local file: {}", videoURL);
623 sendVideo = new SendVideo(chatId, Path.of(new URL(temp).getPath()).toFile());
624 } catch (MalformedURLException e) {
625 logger.warn("Malformed URL, should start with http or file: {}", videoURL);
629 if (caption != null) {
630 sendVideo.caption(caption);
632 if (localHandler.getParseMode() != null) {
633 sendVideo.parseMode(localHandler.getParseMode());
635 return evaluateResponse(localHandler.execute(sendVideo));
640 // legacy delegate methods
641 /* APIs without chatId parameter */
642 public static boolean sendTelegram(ThingActions actions, @Nullable String format, @Nullable Object... args) {
643 return ((TelegramActions) actions).sendTelegram(format, args);
646 public static boolean sendTelegramQuery(ThingActions actions, @Nullable String message, @Nullable String replyId,
647 @Nullable String... buttons) {
648 return ((TelegramActions) actions).sendTelegramQuery(message, replyId, buttons);
651 public static boolean sendTelegramPhoto(ThingActions actions, @Nullable String photoURL, @Nullable String caption) {
652 return ((TelegramActions) actions).sendTelegramPhoto(photoURL, caption, null, null);
655 public static boolean sendTelegramPhoto(ThingActions actions, @Nullable String photoURL, @Nullable String caption,
656 @Nullable String username, @Nullable String password) {
657 return ((TelegramActions) actions).sendTelegramPhoto(photoURL, caption, username, password);
660 public static boolean sendTelegramAnimation(ThingActions actions, @Nullable String animationURL,
661 @Nullable String caption) {
662 return ((TelegramActions) actions).sendTelegramVideo(animationURL, caption);
665 public static boolean sendTelegramVideo(ThingActions actions, @Nullable String videoURL, @Nullable String caption) {
666 return ((TelegramActions) actions).sendTelegramVideo(videoURL, caption);
669 public static boolean sendTelegramAnswer(ThingActions actions, @Nullable String replyId, @Nullable String message) {
670 return ((TelegramActions) actions).sendTelegramAnswer(replyId, message);
673 public static boolean deleteTelegramQuery(ThingActions actions, @Nullable String replyId) {
674 if (actions instanceof TelegramActions telegramActions) {
675 return telegramActions.deleteTelegramQuery(replyId);
677 throw new IllegalArgumentException("Instance is not a TelegramActions class.");
681 /* APIs with chatId parameter */
683 public static boolean sendTelegram(ThingActions actions, @Nullable Long chatId, @Nullable String format,
684 @Nullable Object... args) {
685 return ((TelegramActions) actions).sendTelegram(chatId, format, args);
688 public static boolean sendTelegramQuery(ThingActions actions, @Nullable Long chatId, @Nullable String message,
689 @Nullable String replyId, @Nullable String... buttons) {
690 return ((TelegramActions) actions).sendTelegramQuery(chatId, message, replyId, buttons);
693 public static boolean sendTelegramPhoto(ThingActions actions, @Nullable Long chatId, @Nullable String photoURL,
694 @Nullable String caption) {
695 return ((TelegramActions) actions).sendTelegramPhoto(chatId, photoURL, caption, null, null);
698 public static boolean sendTelegramPhoto(ThingActions actions, @Nullable Long chatId, @Nullable String photoURL,
699 @Nullable String caption, @Nullable String username, @Nullable String password) {
700 return ((TelegramActions) actions).sendTelegramPhoto(chatId, photoURL, caption, username, password);
703 public static boolean sendTelegramAnimation(ThingActions actions, @Nullable Long chatId,
704 @Nullable String animationURL, @Nullable String caption) {
705 return ((TelegramActions) actions).sendTelegramVideo(chatId, animationURL, caption);
708 public static boolean sendTelegramVideo(ThingActions actions, @Nullable Long chatId, @Nullable String videoURL,
709 @Nullable String caption) {
710 return ((TelegramActions) actions).sendTelegramVideo(chatId, videoURL, caption);
713 public static boolean sendTelegramAnswer(ThingActions actions, @Nullable Long chatId, @Nullable String replyId,
714 @Nullable String message) {
715 return ((TelegramActions) actions).sendTelegramAnswer(chatId, replyId, message);
718 public static boolean sendTelegramAnswer(ThingActions actions, @Nullable String chatId, @Nullable String replyId,
719 @Nullable String message) {
720 if (actions instanceof TelegramActions telegramActions) {
721 if (chatId == null) {
724 return telegramActions.sendTelegramAnswer(Long.valueOf(chatId), replyId, message);
726 throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
730 public static boolean sendTelegramAnswer(ThingActions actions, @Nullable Long chatId, @Nullable String callbackId,
731 @Nullable Long messageId, @Nullable String message) {
732 return ((TelegramActions) actions).sendTelegramAnswer(chatId, callbackId, messageId, message);
735 public static boolean sendTelegramAnswer(ThingActions actions, @Nullable String chatId, @Nullable String callbackId,
736 @Nullable String messageId, @Nullable String message) {
737 if (actions instanceof TelegramActions telegramActions) {
738 if (chatId == null) {
741 return telegramActions.sendTelegramAnswer(Long.valueOf(chatId), callbackId,
742 messageId != null ? Long.parseLong(messageId) : null, message);
744 throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
749 public void setThingHandler(@Nullable ThingHandler handler) {
750 this.handler = (TelegramHandler) handler;
754 public @Nullable ThingHandler getThingHandler() {