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)

In our prior articles, we have learnt how to set up a Zigbee sensor network at home using Home Assistant, a Synology NAS, Docker, some Xiaomi Aqara sensors and a few other bits and bobs. 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. 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 for Home Assistant. To name a few: Amazon Simple Notification Service, Azure Service Bus, Facebook Messenger, Discord, Google Hangouts, Slack, Twilio ... 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 (and the contributed telegram and Β home-assistant 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 and Privacy Policies 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.

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, their own proprietary protocol, whose security has been debated in a few occasions - Telegram's own FAQ 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 )

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. In summary, you will have to talk to BotFather (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 or Telegram webhooks. 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 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 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.

I then use the alert 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 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:on tells the alert integration what state corresponds to an active alarm. In our case the on state for the binary sensor.
  • The repeat element will repeat the message again after 10, 15 and finally 30 minutes if not acknowledged.
  • skip_first means 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 is home, 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).
  • data is an optional parameter to send additional attributes to your notifier. In this case, we use the inline_keyboard element (which is part of the supported payloads 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_ack to the bot when tapped.
  • Finally, the notifiers are 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 - or also Fire off the Siren, issue the Action Stations command ... 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). 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.id from 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 and the media player 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 )

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. Plenty of others are also there for other areas. For UK Transport to work, you will need to grab an API Key (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). 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_command is 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 )

Let's add a new binary sensor

- platform: workday
  country: UK

This uses the workday 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: