New Telegram Binding - Tester and Feedback welcome

Ok, already uploadet it.
But be aware. Like I said my Java is a little rusty and there is definitely much work todo

Binding:

Action:

For now Iā€™m just trying to get feedback on whether the beaten path is the right one.

Iā€™m interested in such a binding/action for Telegram, especially useful to send reminders, like in your example, to ā€œtake the trash outā€ or the like.
However,I think it will be nicer to get the reply from the custom keyboard returned by the action, not through the binding.
Something like:

var String json_keyboard = '{"inline_keyboard":[[{"text":"Erledigt","callback_data":"trash_done"},{"text":"Erinnere mich nochmal.","callback_data":"trash_later"}]]}'
var String reply = sendTelegram("BiergartenBot", "%s und %s solltest du noch raus stellen.", json_keyboard, gCal_Abfall_Event1_Summary.state.toString, gCal_Abfall_Event2_Summary.state.toString)
if(reply == "trash_done"){
        Abfall_Steht_An.postUpdate(OFF)
    }

What do you think?
Wouldnā€™t it be easier to write rules?

LATER EDIT:
But some timeout will be needed, otherwise the action will wait indefinitelyā€¦

About the binding nowā€¦
Seems to work pretty well, however I have some observations:

  • lastMessageDate maybe should return DateTime.
  • lastMessageUsername is not populated, it remains empty (NULL)

First of all: Thank you for the feedback!

If I understand you correctly, you want the rule to wait for an answer to happen. Unfortunately I donā€™t think that this is how rules in OpenHAB are intended to work.
Plus: The Telegram API also splits sending and receiving messages. Afaik there is no method for sending a new message that also returns a possible answer.
And I think there is a good reason why:
There could be minutes or even ours between the message send from the Bot and someone sending an answer (thought a button or not). You probably donā€™t want the rule to wait for such a long time but you want to get and work with the answer, even if it comes half a day later.
I think the binding also should work without the action.

But I totaly agree with you, that the current implementation isnā€™t very good either. I will definitely try to find a better solution and I will have your idea in mind.

Valid point. I will definitely look into this.

It is only populated if you have an username set in Telegram. Since its optional to have one it can be NULL. Could you check if you have a username set please? In the Telegram App you can set one under ā€œSettingsā€ in the Hamburger menu. The second row should be your username. (Android, iOS may vary)

Hey, update here since November 2018. How is it going? Canā€™t wat to try that extention!

We are working on it :slight_smile: Iā€™m trying to support Belgadon with the binding.

What we did so far is to migrate the actions provided by the OH1 telegram action module to the OH2 framework and to make use of the TelegramBots API instead of using a http client directly which provides a better abstraction and saves us some code. Now, itā€™s not necessary anymore to use both the OH1 action to send messages and the OH2 binding to receive replies from the user.

I would like to present my proposal here to have a base for further discussions. I currently see two use-cases:

1. Use-case: your bot wants to send you a message (and wants an answer from the user)
This is very similar to what Belgadon already presented. I will just shows how it would look in a real working example.

Letā€™s say we have the following items

String telegramMessage "Telegram Message" { channel = "telegram:telegramBot:620b3747:lastMessageText" }
String telegramReplyId "Telegram Reply Id" { channel = "telegram:telegramBot:620b3747:replyId" }
Switch PresenceAnyone "Anyone [MAP(presence.map):%s]" <presence>

and this is our first rule:

rule "Nobody's at home"
when
   Item PresenceAnyone changed to OFF
then
    val actions = getActions("telegram","telegram:telegramBot:620b3747")
   actions.sendTelegram("MyOH2Bot", "No one is at home, but some lights are still on. Do you want me to turn off the lights?", "Reply_Lights", "Yes", "No")
end

Notice that the third arguments ā€œReply_Lightsā€ is quite important because it acts as a connection between the sent message and the answer (we will see later)

The other arguments define the button names that will be shown. The alternative of using variable arguments would be to use exactly one argument like ā€œ[ Yes ] [ No ]ā€ and to split that internally with String operations.

After this is send, it looks like this:

Then, we have a second rule

rule "Reply handler for lights"
when
    Item telegramReplyId received update Reply_Lights
then
    val actions = getActions("telegram","telegram:telegramBot:620b3747")

    if (telegramMessage.state.toString == "Yes")
    {
        gLights.sendCommand(OFF)
        actions.sendTelegramAnswer("MyOH2Bot", telegramReplyId.state.toString, "Ok, lights are *off* now.") 
    }
    else
    {
        actions.sendTelegramAnswer("MyOH2Bot", telegramReplyId.state.toString, "Ok, I'll leave them *on*.")
    }
end

Here, the ā€œReply_Lightsā€ is again used in the rule to know for what request the Yes/No answer belongs to.

After the user pressed one of the buttons, the reply markup is removed and the answer is provided:

I pushed the changes for this prototype to Belgadons repository.

2. Use-case: Providing commands

This is not yet implemented, but I think it would be useful if the user could send commands to the bot via /sendcommand Bedroomlight ON
or to get a status: /status TemperatureLivingRoom with reply ā€œThe temperature in the ā€œLiving Roomā€ is 21Ā°Cā€
With /help or /list we could show the user a list of available commands and items.

The UI of the telegram client can even show you a list of available commands and you just have to tap on one of them (see Commands).

3 Likes

Wow, it sounds good. :grinning:
@ZzetT Any plans to offer in next time a jar file with your changes to test the binding?

Iā€™m interested in this! Right now I canā€™t really think of a use-case for bots for my home (almost everything is automated and ā€˜automaticallyā€™ controlled), but this is a really good way for controlling your home fast.

Hey Alex, sounds greatā€¦ Very nice work. Canā€™t wait to try it!

Just to let you know: OH is in a bit of movement at the moment. And the OH1 actions must be migrated over in a not so far future. If the new binding is capable of replacing the OH1 action, please submit a PR ASAP and Iā€™ll prioritize the review.

One question though: Is this binding already providing OH2 actions (like the MQTT binding does?
See: https://github.com/openhab/openhab2-addons/blob/master/addons/binding/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/action/MQTTActions.java)

Cheers, David

Yes, in my opinion the idea is to replace the OH1 Telegram actions completly. However, we still need some time I think to test it a bit more, to write documentations and make it ā€œreadyā€. (Itā€™s our first binding that we develop).
What exactly do you have in mind? By what time should we have it ready for review?
I guess you want to avoid the migration effort for the OH1 actions, right?

However, there is one thing were Iā€™m not sure if we can replace it completly. The OH1 Telegram actions support and API where you can download a picture from a passwort protected location:

sendTelegramPhoto(String group, String photoURL, String caption, String username, String password)

But this is not supported by the library we are using here (since we are not directly using a HttpClient anymore). Not sure if this is a big problem.Ok, in the worst case, we have to use a HttpClient to download the picture first and to pass it to the TelegramBot Lib.

Yes, it is. Thatā€™s also why I was asking a few things in this thread (Actions).

1 Like

Take your time. But aiming at 2.5 would be sweet (around June).
And yes, with having this binding there is no point in converting the telegram OH1 action.

Awesome.

Thanks,
David

I have a general question to the OH architects.

Since we are using an external java library (TelegramBots) to simplify the implementation, this comes with the following costs:

  1. it uses an Apache Http Client (see DefaultAbsSender.java), but this comment seems to ā€œforbidā€ this?
  2. Since the library is based on a Long polling approach, it uses at least two threads (see DefaultBotSession.java for implementation details), but the Coding guidelines explicitly state ā€œCreation of threads must be avoided.ā€
  3. the license of the libary itself is MIT but it depends on other libraries like Jackson for xml processing based on Apache License 2.0

Do you see any problems with one of those points?

  1. Not cool. Ideally some shim adapter classes are used. If we have the http usage under full control, https certificates can be managed in a central place and so on.
  2. Not a problem. If there are alternatives like websockets etc those are preferred of course.
  3. Eclipse, Apache and MIT are all accepted licenses.

Cheers, David

Sorry for the long delay, but it took some time to rewrite the Telegram library so that it uses a Jetty client instead of an Apache client.

If you want to try it, just download the following jar and put it into your addons folder: https://github.com/Belgadon/openhab2-addons/releases/download/2.4.0.M5_telegramBot1/org.openhab.binding.telegram-2.4.0-SNAPSHOT.jar

You can find an example on how to use it in one of my previous posts. Iā€™ll update the documentation soon.

6 Likes

Thanks, very good work.

I am testing the binding and so far it has been very useful, about using ā€œ/commandsā€ would be great. Thanks again

Hi, I have to comment that when I donā€™t use the rule that contains the action for a few hours, when the rule is executed for the first time it doesnā€™t send the message to telegram until that rule is executed for second time. can you check it? thanks in advance

Is there a PR made to the openhab2-addons repo already? :slight_smile:
We recently merged a new xmpp client and mail client and telegram would be nice to have as well.

1 Like

I am using " sendTelegram(ā€œbotnameā€,ā€œmessage to sendā€) " is this correct with the new binding ?

Just I am getting the error

[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Virtual Send Telegram': An error occurred during the script execution: index=2, size=2

from my previously used telegram sending rule

Update :
found the cause when updating to this version I removed both
action.telegram 1.13.0 and binding.telegram (previous version)

and in error did not re install the action.telegram with binding.telegram 2.4.0

Please see my post from New Telegram Binding - Tester and Feedback welcome - #19 by ZzetT Compared to the old Telegram binding you have to write it in the following way:

val actions = getActions("telegram","telegram:telegramBot:(your bot id)")
actions.sendTelegram(ā€œbotnameā€,ā€œmessage to sendā€)

Ok, Iā€™ll update the documentation first and then will make a PR.

3 Likes