Skip to content

openHAB and Telegram Bot

openHAB 2 comes with a Telegram binding which allows to run a Telgram Bot. This bot can both send messages to users and groups, and can receive commands and respond to them. That's useful: your home automation system can send all kind of details to your mobile phone.

For this to make it work it needs a couple things:

First of all a mobile phone with the Telegram app on it. You can either have the bot message you directly, but this only works for one person. Or you create a group, and have the bot send the messages to the group instead. Find out about the group ID here.

Then you need to create a Telegram Bot. Instructions are available here.

And everything needs to be hooked up in openHAB.


Let's start with installing the Telegram binding. As usual I use Ansible to install and deploy everything, instructions are available in some of these blog postings.

- name: Get list of available and installed extensions
    url: "http://{{ ansible_host }}:8080/rest/extensions"
  register: oh2_extensions
  changed_when: false

- name: Install extensions
    url: "http://{{ ansible_host }}:8080/rest/extensions/{{ item }}/install"
    method: POST
  when: "not (oh2_extensions.json|byattr('id', item))[0].installed"
    - binding-telegram
  register: oh2_install_extensions

Store the Bot Token in a text file (it's "credentials/telegram-bot.txt" in my case). Make sure only your user can read the file - anyone with access to the Token can control the bot. (chmod 0600 or 0660).


I use a couple different Telegram groups:

  • One for the family, the bot is sending important messages there 
  • One for more detailed messages I'm interested in (kind of a debugging channel)
  • A testing channel which I use to try out new features

The (negative) channel ids are stored in text files. The ids are loaded by Ansible when I deploy the "telegram.things" file:

Thing telegram:telegramBot:HA_Bot [ chatIds="{{ lookup('file', playbook_dir + '/credentials/telegram-ha-channel.txt') }}","{{ lookup('file', playbook_dir + '/credentials/telegram-ha-test-channel.txt') }}","{{ lookup('file', playbook_dir + '/credentials/telegram-ha-details-channel.txt') }}", botToken="{{ lookup('file', playbook_dir + '/credentials/telegram-bot.txt') }}", parseMode="Markdown" ]

Looks a bit long, because of the many Ansible Lookups. The deployed file in "/etc/openhab2/things/telegram.things" is much shorter:

Thing telegram:telegramBot:HA_Bot [ chatIds="-<channel main>","-<channel details>","-<channel test>", botToken="<token>", parseMode="Markdown" ]

Note: "HA_Bot" is the name of this bot. This name is required for all other activities with this bot.


The Binding provides a couple channels, I'm mostly interested in:

  • "lastMessageText": the last command sent by someone
  • "lastMessageDate": the time someone sent the last command
  • "chatId": the group or private chat someone sent a command to - the bot needs to reply to that

All channels defined as Items:

String		telegramLastMessage		"Telegram Bot Last Message"		{ channel = "telegram:telegramBot:HA_Bot:lastMessageText" }
String		telegramLastMessageURL		"Telegram Bot Last Message URL"		{ channel = "telegram:telegramBot:HA_Bot:lastMessageURL" }
DateTime	telegramlastMessageDate		"Telegram Bot Last Message Date"	{ channel = "telegram:telegramBot:HA_Bot:lastMessageDate" }
String		telegramLastMessageName		"Telegram Bot Last Message Sender"	{ channel = "telegram:telegramBot:HA_Bot:lastMessageName" }
String		telegramLastMessageUsername	"Telegram Bot Last Message Username"	{ channel = "telegram:telegramBot:HA_Bot:lastMessageUsername" }
String		telegramLastMessageChatId	"Telegram Bot Last Message chatId"	{ channel = "telegram:telegramBot:HA_Bot:chatId" }
String		telegramLastMessageReplyId	"Telegram Bot Last Message replyId"	{ channel = "telegram:telegramBot:HA_Bot:replyId" }


Once the bot is running, it can send messages on it's own:

    val telegramAction = getActions("telegram","telegram:telegramBot:HA_Bot")
    telegramAction.sendTelegram(Long::parseLong(TELEGRAM_CHANNEL_HA_DETAILS), "%s %s", "Telegram Bot", "online")

This will send a test message to the Telegram group defined in TELEGRAM_CHANNEL_HA_DETAILS.

For responding to messages, the bot needs to be triggered by an event. It's not useful to work on "lastMessageText", because a user can send the same message multiple times - in this case no change event is triggered. An update is triggered, but that's not helpful here. However with every message the "lastMessageDate" will change, and that can be used for a trigger:

rule "Telegram Bot receive test"
    Item telegramlastMessageDate received update
    if (telegramLastMessage.state.toString == "/test") {
        logInfo("Telegram Query Test", "Test")
        val telegramAction = getActions("telegram","telegram:telegramBot:HA_Bot")
        telegramAction.sendTelegram(Long::parseLong(telegramLastMessageChatId.state.toString), "Test received")

This example picks up a "/test" command, and sends a simple message back.


No Trackbacks


Display comments as Linear | Threaded

No comments

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
Form options