Home Assistant and Telegram Notifications with a Chatbot
Learn how to wire up your Home Assistant installation with Telegram to easily get notifications and create a chatbot for interacting with your smart home (with examples).
(Photo by LoboStudio Hamburg (opens in new tab))
In our prior articles, we have learnt how to set up a Zigbee sensor networ (opens in new tab)k at home using Home Assistant (opens in new tab), a Synology NAS, Docker, some Xiaomi Aqara sensors and a few other bits and bobs (opens in new tab). This gives you a significant and fairly extensible framework which you can iterate on and improve over time - in other words, something that you can easily work on during your weekends, evenings or other scraps of time you manage to reclaim for your new hobby š
In this article, we will look at hooking up our installation with a Telegram Bot. (opens in new tab) The bot will be used to interact with your Home Assistant installation, send commands and receive useful information based on the integrations and automations that have been set up.
Once the set up is done, I will show a couple of example automations:
- Get an alert when a door is opened while no one is at home.
- Send commute information on demand.
Letās start this!
Initial Considerations
Before we dive into the specifics, letās discuss a few aspects that are worth thinking about before you set up the integration.
Alternative messaging systems
Telegram is only one of the available integrations. There are a significant number of notification integrations (opens in new tab) for Home Assistant. To name a few: Amazon Simple Notification Service (opens in new tab), Azure Service Bus (opens in new tab), Facebook Messenger (opens in new tab), Discord (opens in new tab), Google Hangouts (opens in new tab), Slack (opens in new tab), Twilio (opens in new tab) ⦠Do consider the other alternatives depending on your needs and preferences.
Chatbot implementation
In the example we will look at, we will configure a Telegram Bot integration and then interact with it by using standard Home Assistant Automations and Alerts. This is OK to start but there may be more powerful ways to build up the chatbot rules as the complexity increases. For example, using Node Red (opens in new tab) (and the contributed telegram (opens in new tab) and home-assistant (opens in new tab) packages) to set up the rules in an easier visual flow seems to be a pretty popular alternative.
Security
Back in my first article, I stated that I wanted to keep the smart home automation internal/private as much as possible. By using an external notification service such as Telegram, we are agreeing to their Terms & Conditions (opens in new tab) and Privacy Policies (opens in new tab) and we need to be mindful of that.
We also need to be aware that although Telegram supports end-to-end encrypted communication in one-to-one chats between humans(*), they do not employ this for bots and they rely on HTTPS instead for the communication between your Telegram client and the Telegram server. This can be read in their own bot FAQ page (opens in new tab).
Messages, commands and requests sent by users are passed to the software running on your servers. Our intermediary server handles all encryption and communication with the Telegram API for you. You communicate with this server via a simple HTTPS-interface that offers a simplified version of the Telegram API. We call that interface our Bot API.
(*) The end-to-end encryption uses MProto (opens in new tab), their own proprietary protocol, whose security has been debated (opens in new tab) in a few occasions (opens in new tab) - Telegramās own FAQ (opens in new tab) is provided here for further reading and comparison.
To summarise, make sure you understand the various aspects and determine the conclusions that work for you. In my case, Iām currently happy to use a Telegram bot as long as I am not sending/exchanging what I class as overly sensitive information to it - such as a snapshot from my security cameras while Iām making homemade pasta in speedos š©².
Without further ado, letās dive straight into it!
( Photo by Taylor Vick (opens in new tab) )
Creating a Telegram Bot For Home Assistant
The first thing we need to do is to create a Telegram Bot. This is a fairly simple task that is well documented on the Telegram documentation page (opens in new tab). In summary, you will have to talk to BotFather (opens in new tab) (a bot) to create your bot. And here you have it, bots creating other bots and us humans lunging further forward to the technological Armageddon š¦¾š.
Use the /newbot command to create a new bot. The BotFather will ask you for a name and username, then generate an authorization token for your new bot.
The most important thing above is the authorization token. This is something you will want to keep protected since anyone in its possession can control your bot. It is also what youāll need to configure in Home Assistant in a jiffy.
Back to Home Assistant, you can hook in your newly minted bot as one of the supported integration methods: Telegram polling (opens in new tab) or Telegram webhooks (opens in new tab). I personally opted for the first one as it works without the need of exposing your Home Assistant installation to the public. Telegram recommends the second option, most likely because itās less taxing for them to issue event-based webhook calls instead of allowing clients (like us) to poll their systems to find out if something new happened, but for the time being they support both.
Hereās the configuration example from the HA documentation page for the polling solution:
# Example configuration.yaml entry
telegram_bot:
- platform: polling
api_key: TELEGRAM_AUTHORIZATION_TOKEN
allowed_chat_ids:
- 12345
- 67890
configuration.yaml
Replace TELEGRAM_AUTHORIZATION_TOKEN with the one created by BotFather above.
You also need to tell the bot which Telegram Chat IDs are allowed (with the allowed_chat_ids option) to talk to the bot and use it. In other words, you will be whitelisting only the persons authorised to play with your Home Assistant Telegram bot, as you donāt want some random people finding it and start flicking your living room lights to spook you out!
Start by adding yourself to the list, by finding your chat ID if you donāt know already. The easiest way to do this is to use your Telegram client and go to one of the available bots (such as @myidbot ) performing this task for you. Then issue the required command (in the example bot I provided, the command is /getid). The bot will reply with your numeric chat id, that you can use in the above configuration.
If you want to allow other people in your household to use the bot, make sure to repeat the process for them as well and add their Telegram Chat Id to the list.
Finally - letās define a couple of notification groups (opens in new tab) for your users. These will be referenced by the other automation rules.
notify:
- name: telegram_user_1
platform: telegram
chat_id: 12345
- name: telegram_user_2
platform: telegram
chat_id: 67890
configuration.yaml
Restart your Home Assistant installation and you should be good to go!
Sample Use Cases
(Disclosure: as an Amazon Associate I earn from qualifying purchases)
In this section, I will explain a few example automations that you can try out and use on your installation.
1) Event notification when everyone is out
When the house is empty you may want to be notified of specific occurrences in your sensor network. For example, if you are using door state sensors (open/close) you may want to be notified if a door is being opened while you are minding your own business elsewhereā¦ š©š¼āāļøšØš¾āāļø
In my case, I am using an Aqara Door/Window Sensors (opens in new tab) which I have installed on the main door. You can also install them on windows, cabinet doors or anything that you want to monitor.
This example is more complex of the two, but itās also fun, so we will start with it!
I have created a binary sensor for this:
binary_sensor:
- platform: template
sensors:
door_left_open:
friendly_name: "House Doors Safety"
value_template: >-
{{ ( is_state('binary_sensor.front_door_openclose', 'on')
or is_state('binary_sensor.rear_door_openclose', 'on')
or is_state('binary_sensor.garage_door_openclose','on')
) and is_state('group.household', 'not_home')
and is_state('input_boolean.silence_alarms','off') }}
device_class: safety
configuration.yaml
The template is fairly straightforward. The sensor is called door_left_open and gets triggered when one of the open/close sensors is triggered. Additionally, it only propagates (using the and conditions) if the household is not at home and the alarms have not been silenced (I want to have a way to override the alerts in certain scenarios). This last aspect is not fundamental and you can remove it should you find it confusing.
By defining the device_class as safety we are giving a semantic value to the variable, where a value of on means Unsafe and a value of off means Safe - which is appropriate for an alarm. Find out more about the available classes at the binary_sensor documentation page (opens in new tab).
I then use the alert (opens in new tab) integration to send an appropriate message out. The alert integration is quite handy as it abstracts away some aspects such as:
- Retrying the notification at defined intervals if not acknowledged
- Send a wrap-up message when the alert condition ceases
It also supports message templates (opens in new tab) so that you can for instance use markdown syntax to enhance your message, or include template variables. Hereās the example:
alert:
door_left_open_alarm:
name: "Warning: one of the door has been left *open*!"
done_message: "The doors *are now closed*"
entity_id: binary_sensor.door_left_open
state: 'on'
repeat:
- 10
- 15
- 30
can_acknowledge: true
skip_first: false
data:
inline_keyboard:
- 'Sound the Horn of Helm Hammerhand:/door_left_open_alarm_ack'
notifiers:
- telegram_user_1
- telegram_user_2
Quite a few things going on here so letās start from the top
name: this is the message that will be sent to the notifiers.done_message: this is the message that will be sent once the alarm condition ceases.entity_id: a reference to the entity being watched by this alert. We are listing our binary sensor.state:ontells the alert integration what state corresponds to an active alarm. In our case theonstate for the binary sensor.- The
repeatelement will repeat the message again after 10, 15 and finally 30 minutes if not acknowledged. skip_firstmeans that the first message will not be sent. This could be useful to avoid false positives. For example, if you come home and open your door, it may take some time for Home Assistant to realise (via the device trackers) that the household ishome, so it may still send an alert. You could instead skip the first notification and repeat it after 1-2 minutes (assuming that, before then, the device tracking did his job and marked the household at home).datais an optional parameter to send additional attributes to your notifier. In this case, we use theinline_keyboardelement (which is part of the supported payloads (opens in new tab) for sending a Telegram message). This will display an inline keyboard in Telegram with the text āSound the Horn of Helm Hammerhandā and send the command/door_left_open_alarm_ackto the bot when tapped.- Finally, the
notifiersare just the list of notification groups that need to be notified (in our scenario the two Telegram users). This is how Home Assistant knows that it needs to send the notification via the Telegram integration.
So far, all good. You should already have a functional Telegram alert which you can test by opening and closing your door under the right conditions. Letās finish this off by adding an automation that actually does something with the issued command. After all, if this is not a drill, we are probably dealing with someone nasty whom has just managed to crank open our homeās door. We must therefore Sound the Horn (opens in new tab) - or also Fire off the Siren (opens in new tab), issue the Action Stations command (opens in new tab) ⦠I could go on for a while here!
Letās create an automation rule for this:
alias: Telegram - aknowledge door left open alarm
trigger:
- event_data:
data: /door_left_open_alarm_ack
event_type: telegram_callback
platform: event
action:
- service: telegram_bot.answer_callback_query
data_template:
callback_query_id: '{{ trigger.event.data.id }}'
message: A message has been played to the intruder.
- service: tts.google_translate_say
entity_id: media_player.speaker
data:
message: "Warning! Door has been opened! Please leave immediately as the police will be called!"
This rule has an event as a trigger, telegram_callback (documented here (opens in new tab)). We want to match the command we sent to the bot /door_left_open_alarm_ack, and we want to execute a couple of actions in response:
- Firstly, we want to answer the callback so that the person who tapped the command in Telegram gets feedback. In this scenario, we use the value of
trigger.event.data.idfrom the event data payload to know who t0 send this message back to. We then also provide a message back to them. - Secondly, we want to spook our intruder š§āāļø As an example, Iām using another couple of integrations I configured (and not covered in this article), specifically the Google Translate Text-To-Speech integration (opens in new tab) and the media player (opens in new tab) speaker in my home. In short, the message will be translated into a lovely Google voice and played out to whoever is infringing on my private property, hopefully scaring them off in the process.
Iām sure you can think of countless variations here⦠let me know in the comments!
( Photo by Lasha Butikashvili (opens in new tab) )
2) Tell me about the next train to work
Thinking about it, your Home Assistant installation knows when you are at home, when you are not and when you just left it. It also knows what time of the day it is. Wouldnāt it be wonderful if it could send you useful information depending on that context?
Here in the United Kingdom, there is a useful service you can use which is already available within Home Assistant: UK Transport (opens in new tab). Plenty of others are also there for other areas (opens in new tab). For UK Transport to work, you will need to grab an API Key (opens in new tab) (free). Once you have it, you can set up a specific sensor which will query the transport API at defined intervals to gather information about certain train routes (buses are also supported):
# Example configuration.yaml entry for a single sensor
sensor:
- platform: uk_transport
app_id: YOUR_APP_ID
app_key: YOUR_APP_KEY
queries:
- mode: train
origin: EDB
destination: KGX
configuration.yaml
In the above example, we will be creating a sensor monitoring the Edinburgh (EDI) to London Kingās Cross (KGX) stations - admittedly, not your typical daily commuteā¦
The above configuration will create a special sensor named sensor.next_train_to_kgx with an attribute next_trains including the next 25 departing trains and several attributes for each train (find out more in the documentation (opens in new tab)). Letās expose some of these for our Telegram bot to use
sensor:
- platform: template
sensors:
next_train_to_kgx_origin:
friendly_name: 'Next EDI->KGX train origin'
value_template: "{{state_attr('sensor.next_train_to_kgx', 'next_trains')[0].origin_name}}"
next_train_to_kgx_estimated:
friendly_name: 'Next EDI->KGX train estimated'
value_template: "{{state_attr('sensor.next_train_to_kgx', 'next_trains')[0].estimated}}"
next_train_to_kgx_scheduled:
friendly_name: 'Next EDI->KGX train scheduled'
value_template: "{{state_attr('sensor.next_train_to_kgx', 'next_trains')[0].scheduled}}"
next_train_to_kgx_platform:
friendly_name: 'Next EDI->KGX train platform'
value_template: "{{state_attr('sensor.next_train_to_kgx', 'next_trains')[0].platform}}"
configuration.yaml
Here we created four more sensors next_train_to_kgx_origin, next_train_to_kgx_estimated, next_train_to_kgx_scheduled, next_train_to_kgx_platform which will pull some useful attributes for the first train available in the list.
Now, we will add an automation so that we can request this information on demand to our Telegram bot.
- alias: Send next work train information to bot
hide_entity: true
trigger:
platform: event
event_type: telegram_command
event_data:
command: '/trainwork'
action:
- service: telegram_bot.send_message
data_template:
target: '{{ trigger.event.data.user_id }}'
message: >
The next train to London KGX is in *{{ states('sensor.next_train_to_kgx') }} mins*
on platform *{{ states('sensor.next_train_to_kgx_platform') }}*
(Scheduled: {{ states('sensor.next_train_to_kgx_scheduled') }} / _Estimated: {{ states('sensor.next_train_to_kgx_estimated') }}_)
automations.yaml
Letās dig through it:
- The first part is similar to what weāve seen earlier. This automation triggers when a specific
telegram_commandis received by our bot:/trainwork - The action uses a
data_template, and create a formatted message that will be sent to the user who issued the command and provides the requested data about the next available train to Kingās Cross
Once the configuration is in place and loaded, you can test it by chatting to your Telegram bot and sending the /trainwork command, to observe the expected reply.
Of course, this could be made a bit smarter. After all, you could just use your phoneās voice assistant to achieve the same result without typing anything. Letās tweak this a little.
( Photo by George Hiles (opens in new tab) )
Letās add a new binary sensor
- platform: workday
country: UK
This uses the workday (opens in new tab) integration which automatically flags if the current day is a workday or not (please tweak the country code accordingly for your scenario)
Now, we can add a new automation. It will look the same as before, except for the trigger and condition section:
trigger:
- entity_id: person.paolo_tagliaferri
for: 00:00:10
platform: state
to: not_home
condition:
- condition: and
conditions:
- condition: state
entity_id: binary_sensor.workday_sensor
state: 'on'
- condition: time
after: '06:00:00'
before: '09:00:00'
We are now triggering the condition when the person we want to track is marked as not_home for at least 10 seconds (to avoid false positives).
The condition, which further filters the rule, requires that it must be a workday, and the time must be between 6 and 9 AM (which is a wide window for commuting - you can tweak as needed). In this way, as you leave your home to go to the station, you will get a reminder of the train times (and of any delays), but only during workdays.
Definitely, you wonāt get any on a Saturday, or on a Friday evening as you leave your home to go for a lovely pint š»
I hope you enjoyed the article and do please let me know in the comments section below about the great ideas I am sure you will implement with your chatbot. If you liked this article, you can look at the others in the series:
- Part 1: Run Home Assistant on Docker with Synology NAS (opens in new tab)
- Part 2: Zigbee Sensor Network with Home Assistant (opens in new tab)
- Part 3: Home Assistant data persistence and visualization with Grafana & InfluxDB (opens in new tab)
- Part 4: Home Assistant and Telegram Notifications with a Chatbot (this article)
- Part 5: Home Assistant, Google Assistant & Cloudflare (opens in new tab)