[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.
|
||||
|
||||
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 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)
|
||||
* 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.
|
||||
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" ]
|
||||
```
|
||||
|
||||
## Channels
|
||||
## State Channels
|
||||
|
||||
| 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 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
|
||||
|
||||
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!")
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
### Send a text message to telegram chat
|
||||
|
|
|
@ -41,4 +41,9 @@ public class TelegramBindingConstants {
|
|||
public static final String LASTMESSAGEUSERNAME = "lastMessageUsername";
|
||||
public static final String CHATID = "chatId";
|
||||
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.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.TelegramException;
|
||||
import com.pengrad.telegrambot.UpdatesListener;
|
||||
import com.pengrad.telegrambot.model.CallbackQuery;
|
||||
import com.pengrad.telegrambot.model.Message;
|
||||
import com.pengrad.telegrambot.model.PhotoSize;
|
||||
import com.pengrad.telegrambot.model.Update;
|
||||
|
@ -70,13 +76,12 @@ import okhttp3.OkHttpClient;
|
|||
* @author Jens Runge - Initial contribution
|
||||
* @author Alexander Krasnogolowy - using Telegram library from pengrad
|
||||
* @author Jan N. Klug - handle file attachments
|
||||
* @author Michael Murton - add trigger channel
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class TelegramHandler extends BaseThingHandler {
|
||||
|
||||
@NonNullByDefault
|
||||
private class ReplyKey {
|
||||
|
||||
final Long chatId;
|
||||
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> receiverChatId = new ArrayList<>();
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(TelegramHandler.class);
|
||||
private @Nullable ScheduledFuture<?> thingOnlineStatusJob;
|
||||
|
||||
|
@ -247,6 +252,15 @@ public class TelegramHandler extends BaseThingHandler {
|
|||
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) {
|
||||
final TelegramBot localBot = bot;
|
||||
if (localBot == null) {
|
||||
|
@ -267,6 +281,7 @@ public class TelegramHandler extends BaseThingHandler {
|
|||
String replyId = null;
|
||||
|
||||
Message message = update.message();
|
||||
CallbackQuery callbackQuery = update.callbackQuery();
|
||||
|
||||
if (message != null) {
|
||||
chatId = message.chat().id();
|
||||
|
@ -278,6 +293,60 @@ public class TelegramHandler extends BaseThingHandler {
|
|||
// 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
|
||||
if (message.audio() != null) {
|
||||
lastMessageURL = getFullDownloadUrl(message.audio().fileId());
|
||||
|
@ -300,28 +369,43 @@ public class TelegramHandler extends BaseThingHandler {
|
|||
}
|
||||
|
||||
// process metadata
|
||||
lastMessageDate = message.date();
|
||||
lastMessageFirstName = message.from().firstName();
|
||||
lastMessageLastName = message.from().lastName();
|
||||
lastMessageUsername = message.from().username();
|
||||
} else if (update.callbackQuery() != null && update.callbackQuery().message() != null
|
||||
&& update.callbackQuery().message().text() != null) {
|
||||
String[] callbackData = update.callbackQuery().data().split(" ", 2);
|
||||
if (lastMessageURL != null || lastMessageText != null) {
|
||||
lastMessageDate = message.date();
|
||||
lastMessageFirstName = message.from().firstName();
|
||||
lastMessageLastName = message.from().lastName();
|
||||
lastMessageUsername = message.from().username();
|
||||
}
|
||||
} else if (callbackQuery != null && callbackQuery.message() != null
|
||||
&& callbackQuery.message().text() != null) {
|
||||
String[] callbackData = callbackQuery.data().split(" ", 2);
|
||||
|
||||
if (callbackData.length == 2) {
|
||||
replyId = callbackData[0];
|
||||
lastMessageText = callbackData[1];
|
||||
lastMessageDate = update.callbackQuery().message().date();
|
||||
lastMessageFirstName = update.callbackQuery().from().firstName();
|
||||
lastMessageLastName = update.callbackQuery().from().lastName();
|
||||
lastMessageUsername = update.callbackQuery().from().username();
|
||||
chatId = update.callbackQuery().message().chat().id();
|
||||
replyIdToCallbackId.put(new ReplyKey(chatId, replyId), update.callbackQuery().id());
|
||||
logger.debug("Received callbackId {} for chatId {} and replyId {}", update.callbackQuery().id(),
|
||||
chatId, replyId);
|
||||
lastMessageDate = callbackQuery.message().date();
|
||||
lastMessageFirstName = callbackQuery.from().firstName();
|
||||
lastMessageLastName = callbackQuery.from().lastName();
|
||||
lastMessageUsername = callbackQuery.from().username();
|
||||
chatId = callbackQuery.message().chat().id();
|
||||
replyIdToCallbackId.put(new ReplyKey(chatId, replyId), callbackQuery.id());
|
||||
|
||||
// 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 {
|
||||
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);
|
||||
|
@ -376,6 +460,10 @@ public class TelegramHandler extends BaseThingHandler {
|
|||
updateState(new ChannelUID(getThing().getUID(), channelName), state);
|
||||
}
|
||||
|
||||
public void triggerEvent(String channelName, String payload) {
|
||||
triggerChannel(channelName, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
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.")
|
||||
public boolean sendTelegramAnswer(@ActionInput(name = "chatId") @Nullable Long chatId,
|
||||
@ActionInput(name = "replyId") @Nullable String replyId,
|
||||
|
@ -121,32 +158,13 @@ public class TelegramActions implements ThingActions {
|
|||
if (localHandler != null) {
|
||||
String callbackId = localHandler.getCallbackId(chatId, replyId);
|
||||
if (callbackId != null) {
|
||||
AnswerCallbackQuery answerCallbackQuery = new AnswerCallbackQuery(
|
||||
localHandler.getCallbackId(chatId, replyId));
|
||||
logger.debug("AnswerCallbackQuery for chatId {} and replyId {} is the callbackId {}", chatId, replyId,
|
||||
localHandler.getCallbackId(chatId, replyId));
|
||||
// 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;
|
||||
}
|
||||
callbackId);
|
||||
}
|
||||
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);
|
||||
|
||||
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 sendTelegramAnswer(chatId, callbackId, messageId != null ? Long.valueOf(messageId) : null, message);
|
||||
}
|
||||
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
|
||||
public void setThingHandler(@Nullable ThingHandler handler) {
|
||||
this.handler = (TelegramHandler) handler;
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
<channel id="lastMessageUsername" typeId="lastMessageUsername"/>
|
||||
<channel id="chatId" typeId="chatId"/>
|
||||
<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>
|
||||
|
||||
<config-description>
|
||||
|
@ -114,4 +118,64 @@
|
|||
<state readOnly="true"/>
|
||||
</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>
|
||||
|
|
Loading…
Reference in New Issue