[telegram] Add event channels and Answer overload (#9251)
* Add event channels and Answer overload Signed-off-by: Michael Murton <6764025+CrazyIvan359@users.noreply.github.com>
This commit is contained in:
parent
88975dcd13
commit
51cb1aabd5
|
@ -41,7 +41,7 @@ Otherwise you will not be able to receive those messages.
|
||||||
|
|
||||||
**telegramBot** - A Telegram Bot that can send and receive messages.
|
**telegramBot** - A Telegram Bot that can send and receive messages.
|
||||||
|
|
||||||
The Telegram binding supports the following things which originate from the last message sent to the Telegram bot:
|
The Telegram binding supports the following state channels which originate from the last message sent to the Telegram bot:
|
||||||
|
|
||||||
* message text or URL
|
* message text or URL
|
||||||
* message date
|
* message date
|
||||||
|
@ -50,6 +50,8 @@ The Telegram binding supports the following things which originate from the last
|
||||||
* chat id (used to identify the chat of the last message)
|
* chat id (used to identify the chat of the last message)
|
||||||
* reply id (used to identify an answer from a user of a previously sent message by the binding)
|
* reply id (used to identify an answer from a user of a previously sent message by the binding)
|
||||||
|
|
||||||
|
There are also event channels that provide received messages or query callback responses as JSON payloads for easier handling in rules.
|
||||||
|
|
||||||
Please note that the binding channels cannot be used to send messages.
|
Please note that the binding channels cannot be used to send messages.
|
||||||
In order to send a message, an action must be used instead.
|
In order to send a message, an action must be used instead.
|
||||||
|
|
||||||
|
@ -105,7 +107,7 @@ or HTTP proxy server
|
||||||
Thing telegram:telegramBot:Telegram_Bot [ chatIds="ID", botToken="TOKEN", proxyHost="localhost", proxyPort="8123", proxyType="HTTP" ]
|
Thing telegram:telegramBot:Telegram_Bot [ chatIds="ID", botToken="TOKEN", proxyHost="localhost", proxyPort="8123", proxyType="HTTP" ]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Channels
|
## State Channels
|
||||||
|
|
||||||
| Channel Type ID | Item Type | Description |
|
| Channel Type ID | Item Type | Description |
|
||||||
|--------------------------------------|-----------|-----------------------------------------------------------------|
|
|--------------------------------------|-----------|-----------------------------------------------------------------|
|
||||||
|
@ -122,6 +124,52 @@ Either `lastMessageText` or `lastMessageURL` are populated for a given message.
|
||||||
If the message did contain text, the content is written to `lastMessageText`.
|
If the message did contain text, the content is written to `lastMessageText`.
|
||||||
If the message did contain an audio, photo, video or voice, the URL to retrieve that content can be found in `lastMessageURL`.
|
If the message did contain an audio, photo, video or voice, the URL to retrieve that content can be found in `lastMessageURL`.
|
||||||
|
|
||||||
|
## Event Channels
|
||||||
|
|
||||||
|
### messageEvent
|
||||||
|
|
||||||
|
When a message is received this channel will be triggered with a simplified version of the message data as the `event`, payload encoded as a JSON string.
|
||||||
|
The following table shows the possible fields, any `null` values will be missing from the JSON payload.
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|------------------|--------|---------------------------------------|
|
||||||
|
| `message_id` | Long | Unique message ID in this chat |
|
||||||
|
| `from` | String | First and/or last name of sender |
|
||||||
|
| `chat_id` | Long | Unique chat ID |
|
||||||
|
| `text` | String | Message text |
|
||||||
|
| `animation_url` | String | URL to download animation from |
|
||||||
|
| `audio_url` | String | URL to download audio from |
|
||||||
|
| `document_url` | String | URL to download file from |
|
||||||
|
| `photo_url` | Array | Array of URLs to download photos from |
|
||||||
|
| `sticker_url` | String | URL to download sticker from |
|
||||||
|
| `video_url` | String | URL to download video from |
|
||||||
|
| `video_note_url` | String | URL to download video note from |
|
||||||
|
| `voice_url` | String | URL to download voice clip from |
|
||||||
|
|
||||||
|
### messageRawEvent
|
||||||
|
|
||||||
|
When a message is received this channel will be triggered with the raw message data as the `event` payload, encoded as a JSON string.
|
||||||
|
See the [`Message` class for details](https://github.com/pengrad/java-telegram-bot-api/blob/4.9.0/library/src/main/java/com/pengrad/telegrambot/model/Message.java)
|
||||||
|
|
||||||
|
### callbackEvent
|
||||||
|
|
||||||
|
When a Callback Query response is received this channel will be triggered with a simplified version of the callback data as the `event`, payload encoded as a JSON string.
|
||||||
|
The following table shows the possible fields, any `null` values will be missing from the JSON payload.
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|---------------|--------|------------------------------------------------------------|
|
||||||
|
| `message_id` | Long | Unique message ID of the original Query message |
|
||||||
|
| `from` | String | First and/or last name of sender |
|
||||||
|
| `chat_id` | Long | Unique chat ID |
|
||||||
|
| `callback_id` | String | Unique callback ID to send receipt confirmation to |
|
||||||
|
| `reply_id` | String | Plain text name of original Query |
|
||||||
|
| `text` | String | Selected response text from options give in original Query |
|
||||||
|
|
||||||
|
### callbackRawEvent
|
||||||
|
|
||||||
|
When a Callback Query response is received this channel will be triggered with the raw callback data as the `event` payload, encoded as a JSON string.
|
||||||
|
See the [`CallbackQuery` class for details](https://github.com/pengrad/java-telegram-bot-api/blob/4.9.0/library/src/main/java/com/pengrad/telegrambot/model/CallbackQuery.java)
|
||||||
|
|
||||||
## Rule Actions
|
## Rule Actions
|
||||||
|
|
||||||
This binding includes a number of rule actions, which allow the sending of Telegram messages from within rules.
|
This binding includes a number of rule actions, which allow the sending of Telegram messages from within rules.
|
||||||
|
@ -172,6 +220,15 @@ Just put the chat id (must be a long value!) followed by an "L" as the first arg
|
||||||
telegramAction.sendTelegram(1234567L, "Hello world!")
|
telegramAction.sendTelegram(1234567L, "Hello world!")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Advanced Callback Query Response
|
||||||
|
|
||||||
|
This binding stores the `callbackId` and recalls it using the `replyId`, but this information is lost if openHAB restarts.
|
||||||
|
If you store the `callbackId`, `chatId`, and optionally `messageId` somewhere that will be persisted when openHAB shuts down, you can use the following overload of `sendTelegramAnswer` to respond to any Callback Query.
|
||||||
|
|
||||||
|
```
|
||||||
|
telegramAction.sendTelegramAnswer(chatId, callbackId, messageId, message)
|
||||||
|
```
|
||||||
|
|
||||||
## Full Example
|
## Full Example
|
||||||
|
|
||||||
### Send a text message to telegram chat
|
### Send a text message to telegram chat
|
||||||
|
|
|
@ -41,4 +41,9 @@ public class TelegramBindingConstants {
|
||||||
public static final String LASTMESSAGEUSERNAME = "lastMessageUsername";
|
public static final String LASTMESSAGEUSERNAME = "lastMessageUsername";
|
||||||
public static final String CHATID = "chatId";
|
public static final String CHATID = "chatId";
|
||||||
public static final String REPLYID = "replyId";
|
public static final String REPLYID = "replyId";
|
||||||
|
public static final String LONGPOLLINGTIME = "longPollingTime";
|
||||||
|
public static final String MESSAGEEVENT = "messageEvent";
|
||||||
|
public static final String MESSAGERAWEVENT = "messageRawEvent";
|
||||||
|
public static final String CALLBACKEVENT = "callbackEvent";
|
||||||
|
public static final String CALLBACKRAWEVENT = "callbackRawEvent";
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,15 @@ import org.openhab.core.types.UnDefType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
import com.pengrad.telegrambot.TelegramBot;
|
import com.pengrad.telegrambot.TelegramBot;
|
||||||
import com.pengrad.telegrambot.TelegramException;
|
import com.pengrad.telegrambot.TelegramException;
|
||||||
import com.pengrad.telegrambot.UpdatesListener;
|
import com.pengrad.telegrambot.UpdatesListener;
|
||||||
|
import com.pengrad.telegrambot.model.CallbackQuery;
|
||||||
import com.pengrad.telegrambot.model.Message;
|
import com.pengrad.telegrambot.model.Message;
|
||||||
import com.pengrad.telegrambot.model.PhotoSize;
|
import com.pengrad.telegrambot.model.PhotoSize;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
@ -70,13 +76,12 @@ import okhttp3.OkHttpClient;
|
||||||
* @author Jens Runge - Initial contribution
|
* @author Jens Runge - Initial contribution
|
||||||
* @author Alexander Krasnogolowy - using Telegram library from pengrad
|
* @author Alexander Krasnogolowy - using Telegram library from pengrad
|
||||||
* @author Jan N. Klug - handle file attachments
|
* @author Jan N. Klug - handle file attachments
|
||||||
|
* @author Michael Murton - add trigger channel
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class TelegramHandler extends BaseThingHandler {
|
public class TelegramHandler extends BaseThingHandler {
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
private class ReplyKey {
|
private class ReplyKey {
|
||||||
|
|
||||||
final Long chatId;
|
final Long chatId;
|
||||||
final String replyId;
|
final String replyId;
|
||||||
|
|
||||||
|
@ -106,9 +111,9 @@ public class TelegramHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Gson gson = new Gson();
|
||||||
private final List<Long> authorizedSenderChatId = new ArrayList<>();
|
private final List<Long> authorizedSenderChatId = new ArrayList<>();
|
||||||
private final List<Long> receiverChatId = new ArrayList<>();
|
private final List<Long> receiverChatId = new ArrayList<>();
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(TelegramHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(TelegramHandler.class);
|
||||||
private @Nullable ScheduledFuture<?> thingOnlineStatusJob;
|
private @Nullable ScheduledFuture<?> thingOnlineStatusJob;
|
||||||
|
|
||||||
|
@ -247,6 +252,15 @@ public class TelegramHandler extends BaseThingHandler {
|
||||||
return bot.getFullFilePath(bot.execute(new GetFile(fileId)).file());
|
return bot.getFullFilePath(bot.execute(new GetFile(fileId)).file());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addFileUrlsToPayload(JsonObject filePayload) {
|
||||||
|
filePayload.addProperty("file_url",
|
||||||
|
getFullDownloadUrl(filePayload.getAsJsonPrimitive("file_id").getAsString()));
|
||||||
|
if (filePayload.has("thumb")) {
|
||||||
|
filePayload.getAsJsonObject("thumb").addProperty("file_url", getFullDownloadUrl(
|
||||||
|
filePayload.getAsJsonObject("thumb").getAsJsonPrimitive("file_id").getAsString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int handleUpdates(List<Update> updates) {
|
private int handleUpdates(List<Update> updates) {
|
||||||
final TelegramBot localBot = bot;
|
final TelegramBot localBot = bot;
|
||||||
if (localBot == null) {
|
if (localBot == null) {
|
||||||
|
@ -267,6 +281,7 @@ public class TelegramHandler extends BaseThingHandler {
|
||||||
String replyId = null;
|
String replyId = null;
|
||||||
|
|
||||||
Message message = update.message();
|
Message message = update.message();
|
||||||
|
CallbackQuery callbackQuery = update.callbackQuery();
|
||||||
|
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
chatId = message.chat().id();
|
chatId = message.chat().id();
|
||||||
|
@ -278,6 +293,60 @@ public class TelegramHandler extends BaseThingHandler {
|
||||||
// chat
|
// chat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build and publish messageEvent trigger channel payload
|
||||||
|
JsonObject messageRaw = JsonParser.parseString(gson.toJson(message)).getAsJsonObject();
|
||||||
|
JsonObject messagePayload = new JsonObject();
|
||||||
|
messagePayload.addProperty("message_id", message.messageId());
|
||||||
|
messagePayload.addProperty("from",
|
||||||
|
String.join(" ", new String[] { message.from().firstName(), message.from().lastName() }));
|
||||||
|
messagePayload.addProperty("chat_id", message.chat().id());
|
||||||
|
if (messageRaw.has("text")) {
|
||||||
|
messagePayload.addProperty("text", message.text());
|
||||||
|
}
|
||||||
|
if (messageRaw.has("animation")) {
|
||||||
|
addFileUrlsToPayload(messageRaw.getAsJsonObject("animation"));
|
||||||
|
messagePayload.add("animation_url", messageRaw.getAsJsonObject("animation").get("file_url"));
|
||||||
|
}
|
||||||
|
if (messageRaw.has("audio")) {
|
||||||
|
addFileUrlsToPayload(messageRaw.getAsJsonObject("audio"));
|
||||||
|
messagePayload.add("audio_url", messageRaw.getAsJsonObject("audio").get("file_url"));
|
||||||
|
}
|
||||||
|
if (messageRaw.has("document")) {
|
||||||
|
addFileUrlsToPayload(messageRaw.getAsJsonObject("document"));
|
||||||
|
messagePayload.add("document_url", messageRaw.getAsJsonObject("document").get("file_url"));
|
||||||
|
}
|
||||||
|
if (messageRaw.has("photo")) {
|
||||||
|
JsonArray photoURLArray = new JsonArray();
|
||||||
|
for (JsonElement photoPayload : messageRaw.getAsJsonArray("photo")) {
|
||||||
|
JsonObject photoPayloadObject = photoPayload.getAsJsonObject();
|
||||||
|
String photoURL = getFullDownloadUrl(
|
||||||
|
photoPayloadObject.getAsJsonPrimitive("file_id").getAsString());
|
||||||
|
photoPayloadObject.addProperty("file_url", photoURL);
|
||||||
|
photoURLArray.add(photoURL);
|
||||||
|
}
|
||||||
|
messagePayload.add("photo_url", photoURLArray);
|
||||||
|
}
|
||||||
|
if (messageRaw.has("sticker")) {
|
||||||
|
addFileUrlsToPayload(messageRaw.getAsJsonObject("sticker"));
|
||||||
|
messagePayload.add("sticker_url", messageRaw.getAsJsonObject("sticker").get("file_url"));
|
||||||
|
}
|
||||||
|
if (messageRaw.has("video")) {
|
||||||
|
addFileUrlsToPayload(messageRaw.getAsJsonObject("video"));
|
||||||
|
messagePayload.add("video_url", messageRaw.getAsJsonObject("video").get("file_url"));
|
||||||
|
}
|
||||||
|
if (messageRaw.has("video_note")) {
|
||||||
|
addFileUrlsToPayload(messageRaw.getAsJsonObject("video_note"));
|
||||||
|
messagePayload.add("video_note_url", messageRaw.getAsJsonObject("video_note").get("file_url"));
|
||||||
|
}
|
||||||
|
if (messageRaw.has("voice")) {
|
||||||
|
JsonObject voicePayload = messageRaw.getAsJsonObject("voice");
|
||||||
|
String voiceURL = getFullDownloadUrl(voicePayload.getAsJsonPrimitive("file_id").getAsString());
|
||||||
|
voicePayload.addProperty("file_url", voiceURL);
|
||||||
|
messagePayload.addProperty("voice_url", voiceURL);
|
||||||
|
}
|
||||||
|
triggerEvent(MESSAGEEVENT, messagePayload.toString());
|
||||||
|
triggerEvent(MESSAGERAWEVENT, messageRaw.toString());
|
||||||
|
|
||||||
// process content
|
// process content
|
||||||
if (message.audio() != null) {
|
if (message.audio() != null) {
|
||||||
lastMessageURL = getFullDownloadUrl(message.audio().fileId());
|
lastMessageURL = getFullDownloadUrl(message.audio().fileId());
|
||||||
|
@ -300,28 +369,43 @@ public class TelegramHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// process metadata
|
// process metadata
|
||||||
lastMessageDate = message.date();
|
if (lastMessageURL != null || lastMessageText != null) {
|
||||||
lastMessageFirstName = message.from().firstName();
|
lastMessageDate = message.date();
|
||||||
lastMessageLastName = message.from().lastName();
|
lastMessageFirstName = message.from().firstName();
|
||||||
lastMessageUsername = message.from().username();
|
lastMessageLastName = message.from().lastName();
|
||||||
} else if (update.callbackQuery() != null && update.callbackQuery().message() != null
|
lastMessageUsername = message.from().username();
|
||||||
&& update.callbackQuery().message().text() != null) {
|
}
|
||||||
String[] callbackData = update.callbackQuery().data().split(" ", 2);
|
} else if (callbackQuery != null && callbackQuery.message() != null
|
||||||
|
&& callbackQuery.message().text() != null) {
|
||||||
|
String[] callbackData = callbackQuery.data().split(" ", 2);
|
||||||
|
|
||||||
if (callbackData.length == 2) {
|
if (callbackData.length == 2) {
|
||||||
replyId = callbackData[0];
|
replyId = callbackData[0];
|
||||||
lastMessageText = callbackData[1];
|
lastMessageText = callbackData[1];
|
||||||
lastMessageDate = update.callbackQuery().message().date();
|
lastMessageDate = callbackQuery.message().date();
|
||||||
lastMessageFirstName = update.callbackQuery().from().firstName();
|
lastMessageFirstName = callbackQuery.from().firstName();
|
||||||
lastMessageLastName = update.callbackQuery().from().lastName();
|
lastMessageLastName = callbackQuery.from().lastName();
|
||||||
lastMessageUsername = update.callbackQuery().from().username();
|
lastMessageUsername = callbackQuery.from().username();
|
||||||
chatId = update.callbackQuery().message().chat().id();
|
chatId = callbackQuery.message().chat().id();
|
||||||
replyIdToCallbackId.put(new ReplyKey(chatId, replyId), update.callbackQuery().id());
|
replyIdToCallbackId.put(new ReplyKey(chatId, replyId), callbackQuery.id());
|
||||||
logger.debug("Received callbackId {} for chatId {} and replyId {}", update.callbackQuery().id(),
|
|
||||||
chatId, replyId);
|
// build and publish callbackEvent trigger channel payload
|
||||||
|
JsonObject callbackRaw = JsonParser.parseString(gson.toJson(callbackQuery)).getAsJsonObject();
|
||||||
|
JsonObject callbackPayload = new JsonObject();
|
||||||
|
callbackPayload.addProperty("message_id", callbackQuery.message().messageId());
|
||||||
|
callbackPayload.addProperty("from", lastMessageFirstName + " " + lastMessageLastName);
|
||||||
|
callbackPayload.addProperty("chat_id", callbackQuery.message().chat().id());
|
||||||
|
callbackPayload.addProperty("callback_id", callbackQuery.id());
|
||||||
|
callbackPayload.addProperty("reply_id", callbackData[0]);
|
||||||
|
callbackPayload.addProperty("text", callbackData[1]);
|
||||||
|
triggerEvent(CALLBACKEVENT, callbackPayload.toString());
|
||||||
|
triggerEvent(CALLBACKRAWEVENT, callbackRaw.toString());
|
||||||
|
|
||||||
|
logger.debug("Received callbackId {} for chatId {} and replyId {}", callbackQuery.id(), chatId,
|
||||||
|
replyId);
|
||||||
} else {
|
} else {
|
||||||
logger.warn("The received callback query {} has not the right format (must be seperated by spaces)",
|
logger.warn("The received callback query {} has not the right format (must be seperated by spaces)",
|
||||||
update.callbackQuery().data());
|
callbackQuery.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateChannel(CHATID, chatId != null ? new StringType(chatId.toString()) : UnDefType.NULL);
|
updateChannel(CHATID, chatId != null ? new StringType(chatId.toString()) : UnDefType.NULL);
|
||||||
|
@ -376,6 +460,10 @@ public class TelegramHandler extends BaseThingHandler {
|
||||||
updateState(new ChannelUID(getThing().getUID(), channelName), state);
|
updateState(new ChannelUID(getThing().getUID(), channelName), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void triggerEvent(String channelName, String payload) {
|
||||||
|
triggerChannel(channelName, payload);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||||
return Collections.singleton(TelegramActions.class);
|
return Collections.singleton(TelegramActions.class);
|
||||||
|
|
|
@ -105,6 +105,43 @@ public class TelegramActions implements ThingActions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
|
||||||
|
public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
|
||||||
|
@ActionInput(name = "callbackId") @Nullable String callbackId,
|
||||||
|
@ActionInput(name = "messageId") @Nullable Long messageId,
|
||||||
|
@ActionInput(name = "message") @Nullable String message) {
|
||||||
|
if (chatId == null) {
|
||||||
|
logger.warn("chatId not defined; action skipped.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (messageId == null) {
|
||||||
|
logger.warn("messageId not defined; action skipped.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TelegramHandler localHandler = handler;
|
||||||
|
if (localHandler != null) {
|
||||||
|
if (callbackId != null) {
|
||||||
|
AnswerCallbackQuery answerCallbackQuery = new AnswerCallbackQuery(callbackId);
|
||||||
|
// we could directly set the text here, but this
|
||||||
|
// doesn't result in a real message only in a
|
||||||
|
// little popup or in an alert, so the only purpose
|
||||||
|
// is to stop the progress bar on client side
|
||||||
|
logger.debug("Answering query with callbackId '{}'", callbackId);
|
||||||
|
if (!evaluateResponse(localHandler.execute(answerCallbackQuery))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditMessageReplyMarkup editReplyMarkup = new EditMessageReplyMarkup(chatId, messageId.intValue())
|
||||||
|
.replyMarkup(new InlineKeyboardMarkup(new InlineKeyboardButton[0]));// remove reply markup from
|
||||||
|
// old message
|
||||||
|
if (!evaluateResponse(localHandler.execute(editReplyMarkup))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return message != null ? sendTelegram(chatId, message) : true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
|
@RuleAction(label = "send an answer", description = "Send a Telegram answer using the Telegram API.")
|
||||||
public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
|
public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
|
||||||
@ActionInput(name = "replyId") @Nullable String replyId,
|
@ActionInput(name = "replyId") @Nullable String replyId,
|
||||||
|
@ -121,32 +158,13 @@ public class TelegramActions implements ThingActions {
|
||||||
if (localHandler != null) {
|
if (localHandler != null) {
|
||||||
String callbackId = localHandler.getCallbackId(chatId, replyId);
|
String callbackId = localHandler.getCallbackId(chatId, replyId);
|
||||||
if (callbackId != null) {
|
if (callbackId != null) {
|
||||||
AnswerCallbackQuery answerCallbackQuery = new AnswerCallbackQuery(
|
|
||||||
localHandler.getCallbackId(chatId, replyId));
|
|
||||||
logger.debug("AnswerCallbackQuery for chatId {} and replyId {} is the callbackId {}", chatId, replyId,
|
logger.debug("AnswerCallbackQuery for chatId {} and replyId {} is the callbackId {}", chatId, replyId,
|
||||||
localHandler.getCallbackId(chatId, replyId));
|
callbackId);
|
||||||
// we could directly set the text here, but this
|
|
||||||
// doesn't result in a real message only in a
|
|
||||||
// little popup or in an alert, so the only purpose
|
|
||||||
// is to stop the progress bar on client side
|
|
||||||
if (!evaluateResponse(localHandler.execute(answerCallbackQuery))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Integer messageId = localHandler.removeMessageId(chatId, replyId);
|
Integer messageId = localHandler.removeMessageId(chatId, replyId);
|
||||||
if (messageId == null) {
|
|
||||||
logger.warn("messageId could not be found for chatId {} and replyId {}", chatId, replyId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
logger.debug("remove messageId {} for chatId {} and replyId {}", messageId, chatId, replyId);
|
logger.debug("remove messageId {} for chatId {} and replyId {}", messageId, chatId, replyId);
|
||||||
|
|
||||||
EditMessageReplyMarkup editReplyMarkup = new EditMessageReplyMarkup(chatId, messageId.intValue())
|
return sendTelegramAnswer(chatId, callbackId, messageId != null ? Long.valueOf(messageId) : null, message);
|
||||||
.replyMarkup(new InlineKeyboardMarkup(new InlineKeyboardButton[0]));// remove reply markup from
|
|
||||||
// old message
|
|
||||||
if (!evaluateResponse(localHandler.execute(editReplyMarkup))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return message != null ? sendTelegram(chatId, message) : true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -652,6 +670,24 @@ public class TelegramActions implements ThingActions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean sendTelegramAnswer(ThingActions actions, @Nullable Long chatId, @Nullable String callbackId,
|
||||||
|
@Nullable Long messageId, @Nullable String message) {
|
||||||
|
return ((TelegramActions) actions).sendTelegramAnswer(chatId, callbackId, messageId, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean sendTelegramAnswer(ThingActions actions, @Nullable String chatId, @Nullable String callbackId,
|
||||||
|
@Nullable String messageId, @Nullable String message) {
|
||||||
|
if (actions instanceof TelegramActions) {
|
||||||
|
if (chatId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ((TelegramActions) actions).sendTelegramAnswer(Long.valueOf(chatId), callbackId,
|
||||||
|
messageId != null ? Long.parseLong(messageId) : null, message);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Actions is not an instance of TelegramActions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setThingHandler(@Nullable ThingHandler handler) {
|
public void setThingHandler(@Nullable ThingHandler handler) {
|
||||||
this.handler = (TelegramHandler) handler;
|
this.handler = (TelegramHandler) handler;
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
<channel id="lastMessageUsername" typeId="lastMessageUsername"/>
|
<channel id="lastMessageUsername" typeId="lastMessageUsername"/>
|
||||||
<channel id="chatId" typeId="chatId"/>
|
<channel id="chatId" typeId="chatId"/>
|
||||||
<channel id="replyId" typeId="replyId"/>
|
<channel id="replyId" typeId="replyId"/>
|
||||||
|
<channel id="messageEvent" typeId="messageEvent"/>
|
||||||
|
<channel id="messageRawEvent" typeId="messageRawEvent"/>
|
||||||
|
<channel id="callbackEvent" typeId="callbackEvent"/>
|
||||||
|
<channel id="callbackRawEvent" typeId="callbackRawEvent"/>
|
||||||
</channels>
|
</channels>
|
||||||
|
|
||||||
<config-description>
|
<config-description>
|
||||||
|
@ -114,4 +118,64 @@
|
||||||
<state readOnly="true"/>
|
<state readOnly="true"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="messageEvent" advanced="true">
|
||||||
|
<kind>trigger</kind>
|
||||||
|
<label>Message Received</label>
|
||||||
|
<description>
|
||||||
|
<![CDATA[
|
||||||
|
Message encoded as JSON.<br />
|
||||||
|
Event payload could contain the following, but `null` values will not be present:
|
||||||
|
<ul>
|
||||||
|
<li>Long `message_id` - Unique message ID in this chat</li>
|
||||||
|
<li>String `from` - First and/or last name of sender</li>
|
||||||
|
<li>Long `chat_id` - Unique chat ID</li>
|
||||||
|
<li>String `text` - Message text</li>
|
||||||
|
<li>String `animation_url` - URL to download animation from</li>
|
||||||
|
<li>String `audio_url` - URL to download audio from</li>
|
||||||
|
<li>String `document_url` - URL to download file from</li>
|
||||||
|
<li>Array `photo_url` - Array of URLs to download photos from</li>
|
||||||
|
<li>String `sticker_url` - URL to download sticker from</li>
|
||||||
|
<li>String `video_url` - URL to download video from</li>
|
||||||
|
<li>String `video_note_url` - URL to download video note from</li>
|
||||||
|
<li>String `voice_url` - URL to download voice clip from</li>
|
||||||
|
</ul>
|
||||||
|
]]>
|
||||||
|
</description>
|
||||||
|
<event></event>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="messageRawEvent" advanced="true">
|
||||||
|
<kind>trigger</kind>
|
||||||
|
<label>Raw Message Received</label>
|
||||||
|
<description>Raw Message from the Telegram library as JSON.</description>
|
||||||
|
<event></event>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="callbackEvent" advanced="true">
|
||||||
|
<kind>trigger</kind>
|
||||||
|
<label>Query Callback Received</label>
|
||||||
|
<description>
|
||||||
|
<![CDATA[
|
||||||
|
Callback Query response encoded as JSON.<br />
|
||||||
|
Event payload could contain the following, but `null` values will not be present:
|
||||||
|
<ul>
|
||||||
|
<li>Long `message_id` - Unique message ID of the original Query message</li>
|
||||||
|
<li>String `from` - First and/or last name of sender</li>
|
||||||
|
<li>Long `chat_id` - Unique chat ID</li>
|
||||||
|
<li>String `callback_id` - Unique callback ID to send receipt confirmation to</li>
|
||||||
|
<li>String `reply_id` - Plain text name of original Query</li>
|
||||||
|
<li>String `text` - Selected response text from options give in original Query</li>
|
||||||
|
</ul>
|
||||||
|
]]>
|
||||||
|
</description>
|
||||||
|
<event></event>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="callbackRawEvent" advanced="true">
|
||||||
|
<kind>trigger</kind>
|
||||||
|
<label>Raw Callback Query Received</label>
|
||||||
|
<description>Raw Callback Query response from the Telegram library encoded as JSON.</description>
|
||||||
|
<event></event>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
</thing:thing-descriptions>
|
</thing:thing-descriptions>
|
||||||
|
|
Loading…
Reference in New Issue