Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[telegram] Telegram Binding initial contribution #5677

Merged
merged 52 commits into from Nov 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ef12318
migrated Telegram binding to maven and bnd build system
ZzetT May 13, 2019
7f6b31c
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
a571fc3
added documentation, removed unnecessary comments
ZzetT Jun 1, 2019
9103cc6
added examples to README, fixed static code checks
ZzetT Jun 2, 2019
e8f6439
removed bnd import
ZzetT Jun 2, 2019
4974df7
* added third party lib info
Jun 3, 2019
29c4fd4
used original line endings for pom.xml
Jun 3, 2019
8a93122
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
55a2ad8
removed bnd import
ZzetT Jun 2, 2019
f39e1c3
added telegram library with updated pom.xml/feature.xml
Jun 15, 2019
7d05806
set two packages to optional
Jul 2, 2019
1cf6ebc
use only external dependencies
J-N-K Jul 8, 2019
0b4bc3f
migrated Telegram binding to maven and bnd build system
ZzetT May 13, 2019
458c5b7
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
25baa82
added documentation, removed unnecessary comments
ZzetT Jun 1, 2019
ef10030
added examples to README, fixed static code checks
ZzetT Jun 2, 2019
ace7310
removed bnd import
ZzetT Jun 2, 2019
810d4f1
* added third party lib info
Jun 3, 2019
ba9b8f7
used original line endings for pom.xml
Jun 3, 2019
b37b9d9
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
2b9965c
removed bnd import
ZzetT Jun 2, 2019
5e48a0d
Merge pull request #2 from J-N-K/with_lib
ZzetT Jul 22, 2019
cb3a13c
updated pom.xml/feature.xml to use osgiify version of telegram library
Jul 22, 2019
e995693
replaced used telegram library with the java-telegram-bot-api from pe…
Oct 21, 2019
5286109
Update README.md
ZzetT Oct 23, 2019
2540f8a
Update README.md
ZzetT Oct 23, 2019
9e7775f
fixed dispose of thing handler
Oct 23, 2019
258bd75
migrated Telegram binding to maven and bnd build system
ZzetT May 13, 2019
68b8987
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
a21f458
added documentation, removed unnecessary comments
ZzetT Jun 1, 2019
96ea40e
added examples to README, fixed static code checks
ZzetT Jun 2, 2019
a992ad5
removed bnd import
ZzetT Jun 2, 2019
a60684b
* added third party lib info
Jun 3, 2019
76e5e2e
used original line endings for pom.xml
Jun 3, 2019
b28c9ee
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
ffb3e8f
removed bnd import
ZzetT Jun 2, 2019
f243f0a
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
e3fc847
removed bnd import
ZzetT Jun 2, 2019
3eab296
added importpackage to solve "unresolved requirements/missing import"…
ZzetT May 15, 2019
24e7a7c
removed bnd import
ZzetT Jun 2, 2019
bcbdc27
added telegram library with updated pom.xml/feature.xml
Jun 15, 2019
47cf69a
set two packages to optional
Jul 2, 2019
129da81
use only external dependencies
J-N-K Jul 8, 2019
2852a0b
replaced used telegram library with the java-telegram-bot-api from pe…
Oct 21, 2019
10a8323
Update README.md
ZzetT Oct 23, 2019
bb6633c
Update README.md
ZzetT Oct 23, 2019
510c29f
fixed dispose of thing handler
Oct 23, 2019
0e277c9
Merge branch 'master' of https://github.com/ZzetT/openhab2-addons
Oct 24, 2019
63ea1fc
Squashed commit of the following:
Oct 24, 2019
df29fd6
Merge branch 'master' of https://github.com/ZzetT/openhab2-addons
Oct 24, 2019
fefd570
- changed channels to read-only
Nov 5, 2019
7e9c349
incporated finding from Hilbrand:
Nov 6, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -169,6 +169,7 @@
/bundles/org.openhab.binding.systeminfo/ @svilenvul
/bundles/org.openhab.binding.tado/ @dfrommi
/bundles/org.openhab.binding.tankerkoenig/ @dolic @JueBag
/bundles/org.openhab.binding.telegram/ @ZzetT
/bundles/org.openhab.binding.tellstick/ @jarlebh
/bundles/org.openhab.binding.tesla/ @kgoderis
/bundles/org.openhab.binding.toon/ @jongj
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Expand Up @@ -835,6 +835,11 @@
<artifactId>org.openhab.binding.tankerkoenig</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.telegram</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.tellstick</artifactId>
Expand Down
49 changes: 49 additions & 0 deletions bundles/org.openhab.binding.telegram/.classpath
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
23 changes: 23 additions & 0 deletions bundles/org.openhab.binding.telegram/.project
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.openhab.binding.telegram</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
25 changes: 25 additions & 0 deletions bundles/org.openhab.binding.telegram/NOTICE
@@ -0,0 +1,25 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab2-addons
ZzetT marked this conversation as resolved.
Show resolved Hide resolved

== Third-party Content

Java Telegram Bot API
* License: Apache License 2.0
* Project: https://github.com/pengrad/java-telegram-bot-api
* Source: https://github.com/pengrad/java-telegram-bot-api

okhttp
* License: Apache License 2.0
* Project: https://square.github.io/okhttp/
* Source: https://github.com/square/okhttp
267 changes: 267 additions & 0 deletions bundles/org.openhab.binding.telegram/README.md
@@ -0,0 +1,267 @@
# Telegram Binding

The Telegram binding allows sending and receiving messages to and from Telegram clients (https://telegram.org), by using the Telegram Bot API.

# Prerequisites

As described in the Telegram Bot API, this is the manual procedure needed in order to get the necessary information.

1. Create the Bot and get the Token

- On a Telegram client open a chat with BotFather.
- Send `/newbot` to BotFather and fill in all the needed information. The authentication token that is given will be needed in the next steps.

2. Create the destination chat

- Open a chat with your new Bot and send any message to it. The next step will not work unless you send a message to your bot first.

3. Get the chatId

- Open a browser and invoke `https://api.telegram.org/bot<token>/getUpdates` (where `<token>` is the authentication token previously obtained)
- Look at the JSON result to find the value of `id`. That is the chatId. Note that if using a Telegram group chat, the group chatIds are prefixed with a dash that must be included in the config file. (e.g. bot1.chatId: -22334455)

4. Test the bot

- Open this URL in your web browser, replacing <token> with the authentication token and <chatId> with the chatId:
- `https://api.telegram.org/bot<token>/sendMessage?chat_id=<chatId>&text=testing`
- Your Telegram-bot should send you a message with the text: `testing`

**Notice:** By default your bot will only receive messages that either start with the '/' symbol or mention the bot by username (or if you talk to it directly). However, if you add your bot to a group you must either talk to BotFather and send the command "/setprivacy" and then disable it or you give admin rights to your bot in that group. Otherwise you will not be able to receive those messages.

## Supported Things

**telegramBot** - A Telegram Bot that can send and receive messages.

The Telegram binding supports the following things which origin from the latest message sent to the Telegram bot:

* message text
* message date
* full name of sender (first name + last name)
* username of sender
* 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)

Please note that the things cannot be used to send messages. In order to send a message, an action must be used instead.

## Thing Configuration

**telegramBot** parameters:

| Property | Default | Required | Description |
|-------------------------|---------|:--------:|----------------------------------------------------------------------------------------------|
| `chatIds` | | Yes | Comma-separated list of chat ids |
| `botToken` | | Yes | authentication token |
| `parseMode` | None | No | Support for formatted messages, values: Markdown or HTML. |

## Channels

| Channel Type ID | Item Type | Description |
|--------------------------------------|-----------|-----------------------------------------------------------------|
| lastMessageText | String | The last received message |
| lastMessageDate | DateTime | The date of the last received message (UTC) |
| lastMessageName | String | The full name of the sender of the last received message |
| lastMessageUsername | String | The username of the sender of the last received message |
| chatId | String | The id of the chat of the last received meesage |
| replyId | String | The id of the reply which was passed to sendTelegram() as replyId argument. This id can be used to have an unambiguous assignment of the users reply to the message which was sent by the bot |


## Rule Actions

This binding includes a rule action, which allows to send Telegram messages from within rules.

```
val telegramAction = getActions("telegram","telegram:telegramBot:<uid>")
```

where uid is the Thing UID of the Telegram thing (not the chat id!).


Once this action instance is retrieved, you can invoke the `sendTelegram' method on it:

```
telegramAction.sendTelegram("Hello world!")
```

The following actions are supported.
Each of the actions returns true on success or false on failure.

### Actions to send messages to all configured chats

These actions will send a message to all chat ids configured for this bot.

| Action | Description |
|----------------------------|--------------|
| sendTelegram(String message) | Sends a message. |
| sendTelegram(String format, Object... args) | Sends a formatted message (See https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html for more information).
| sendTelegramQuery(String message, String replyId, String... buttons) | Sends a question to the user that can be answered via the defined buttons. The replyId can be freely choosen and is sent back with the answer. Then, the id is required to identify what question has been answered (e.g. in case of multiple open questions). The final result looks like this: ![Telegram Inline Keyboard](doc/queryExample.png). |
| sendTelegramAnswer(String replyId, String message) | Sends a message after the user has answered a question. You should *always* call this method after you received an answer. It will remove buttons from the specific question and will also stop the progress bar displayed at the client side. If no message is necessary, just pass `null` here. |
| sendTelegramPhoto(String photoURL, String caption) | Sends a picture. The URL can be specified using the http, https, and file protocols or a base64 encoded image. |

### Actions to send messages to a particular chat

Just put the chat id (must be a long value!) as the first argument to one of the above mentioned APIs:

```
telegramAction.sendTelegram(1234567L, "Hello world!")
```

## Full Example

### Send a text message to telegram chat

telegram.rules

```java
rule "Send telegram with Fixed Message"
when
Item Foo changed
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
telegramAction.sendTelegram("item Foo changed")
end
```

### Send a text message with a formatted message

telegram.rules

```java
rule "Send telegram with Formatted Message"
when
Item Foo changed
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
telegramAction.sendTelegram("item Foo changed to %s and number is %.1f", Foo.state.toString, 23.56)
end
```

### Send an image to telegram chat

`http`, `https`, and `file` are the only protocols allowed or a base64 encoded image.

telegram.rules

```java
rule "Send telegram with image and caption from image accessible by url"
when
Item Light_GF_Living_Table changed
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
telegramAction.sendTelegramPhoto("http://www.openhab.org/assets/images/openhab-logo-top.png",
"sent from openHAB")
end
```

telegram.rules

```java
rule "Send telegram with image without caption from image accessible by url"
when
Item Light_GF_Living_Table changed
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
telegramAction.sendTelegramPhoto("http://www.openhab.org/assets/images/openhab-logo-top.png",
null)
end
```

To send a base64 jpeg or png image:

telegram.rules

```java
rule "Send telegram with base64 image and caption"
when
Item Light_GF_Living_Table changed
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
var String base64Image = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAS1BMVEUAAABAQEA9QUc7P0Y0OD88QEY+QUhmaW7c3N3w8PBlaG0+QUjb29w5PUU3O0G+vsigoas6P0WfoKo4O0I9QUdkZ2w9Qkg+QkkkSUnT3FKbAAAAGXRSTlMACJbx//CV9v//9pT/7Ur//+z/SfD2kpMHrnfDaAAAAGhJREFUeAHt1bUBAzAMRFGZmcL7LxpOalN5r/evLIlgGwBgXMhxSjP64sa6cdYH+hLWzYiKvqSbI4kQeEt5PlBealsMFIkAAgi8HNriOLcjduLTafWwBB9n3p8v/+Ma1Mxxvd4IAGCzB4xDPuBRkEZiAAAAAElFTkSuQmCC"
telegramAction.sendTelegramPhoto(base64Image, "battery of motion sensor is empty")
end
```

To send an image that resides on the local computer file system:

telegram.rules

```java
rule "Send telegram with local image and caption"
when
Item Light_GF_Living_Table changed
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
telegramAction.sendTelegramPhoto("file://C:/mypicture.jpg", "sent from openHAB")
end
```

To send an image based on an Image Item:

telegram.rules

```java
rule "Send telegram with Image Item image and caption"
when
Item Webcam_Image changed
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
telegramAction.sendTelegramPhoto(Webcam_Image.state.toFullString, "sent from openHAB")
end
```

To receive a message and react on that:

telegram.items

```php
String telegramMessage "Telegram Message" { channel = "telegram:telegramBot:2b155b22:lastMessageText" }
```

telegram.rules

```java
rule "Receive telegram"
when
Item telegramMessage received update "lights off"
then
gLights.sendCommand(OFF)
end
```

To send a question with two alternatives and a reply from the bot:

telegram.items

```php
String telegramReplyId "Telegram Reply Id" { channel = "telegram:telegramBot:2b155b22:replyId" }
```

telegram.rules

```java
rule "Send telegram with question"
when
Item Presence changed to OFF
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")
telegramAction.sendTelegramQuery("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


rule "Reply handler for lights"
when
Item telegramReplyId received update Reply_Lights
then
val telegramAction = getActions("telegram","telegram:telegramBot:2b155b22")

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

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.