Skip to content

Fix Telegram Bot send file to multiple targets, snapshots of HA cameras, variable templating, digest auth#7771

Merged
MartinHjelmare merged 10 commits into
home-assistant:devfrom
azogue:fix-callbacks
May 26, 2017
Merged

Fix Telegram Bot send file to multiple targets, snapshots of HA cameras, variable templating, digest auth#7771
MartinHjelmare merged 10 commits into
home-assistant:devfrom
azogue:fix-callbacks

Conversation

@azogue
Copy link
Copy Markdown
Member

@azogue azogue commented May 25, 2017

Description:

Fix some problems introduced with the changes in telegram_bot and notify.telegram of 0.45 and 0.45.1, and some enhancements:

  • Allow templating in url, file, caption, longitude, latitude fields.
  • Fix sending HA camera snapshots by retrying the HA API request (it returns some 500's before working for some cameras in Home Assistant, not all)
  • Fix send file to multiple locations
  • Easier inline keyboards from yaml files.
  • HttpDigest authentication for url’s

Related issues:

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#2714

Notification Examples for configuration.yaml:

telegram_bot:
  platform: polling
  api_key: !secret telegram_api
  allowed_chat_ids:
    - !secret telegram_bot_chat_id_admin
    - !secret telegram_bot_group

notify:
  - platform: telegram
    name: telegram_bot
    chat_id: !secret telegram_bot_chat_id_admin

script:
  # Telegram Bot component
  test_telegram_bot_location:
    alias: Test Telegram Bot multi-target location template
    sequence:
      - service: telegram_bot.send_location
        data:
          caption: 'Test location'
          target:
            - !secret telegram_bot_chat_id_admin
            - !secret telegram_bot_group
          latitude: '{{ states.device_tracker.iphone.attributes.latitude|float }}'
          longitude: '{{ states.device_tracker.iphone.attributes.longitude|float }}'
          disable_notification: true

  test_telegram_bot_document:
    alias: Test Telegram Bot multi-target document
    sequence:
      - service: telegram_bot.send_document
        data:
          caption: 'Test document'
          target:
            - !secret telegram_bot_chat_id_admin
            - !secret telegram_bot_group
          file: '/home/homeassistant/.homeassistant/home-assistant.log'
          disable_notification: true

  test_telegram_bot_image:
    alias: Test Telegram Bot multi-target image
    sequence:
      - service: telegram_bot.send_photo
        data:
          target:
            - !secret telegram_bot_chat_id_admin
            - !secret telegram_bot_group
          caption: 'Test image'
          url: 'http://localhost:8123{{ states.camera.ha_camera.attributes.entity_picture}}'
          disable_notification: true

  # Notify component
  test_notify_telegram_location:
    alias: Test notify.telegram location template
    sequence:
      - service: notify.telegram_bot
        data:
          message: "Not used here but needed..."
          data:
            location:
              latitude: '{{ states.device_tracker.iphone.attributes.latitude|float }}'
              longitude: '{{ states.device_tracker.iphone.attributes.longitude|float }}'

  test_notify_telegram_image:
    alias: Test notify.telegram multiple image
    sequence:
      - service: notify.telegram_bot
        data:
          message: "Not used here but needed..."
          data:
            photo:
              - url: 'https://upload.wikimedia.org/wikipedia/en/5/58/Penny_test.jpg'
                caption: 'Test img 1. C1'
              - url: 'http://localhost:8123{{ states.camera.ha_camera.attributes.entity_picture}}'
                caption: 'Test img 1. C2'

Checklist:

If user exposed functionality or configuration variables are added/changed:

  • Documentation added/updated in home-assistant.github.io
  • Tests have been done manually to verify that the new code works. (There aren't tests for the Telegram components)

azogue added 6 commits May 24, 2017 22:16
To make a row of InlineKeyboardButtons you pass:
- a list of tuples like: `[(text_b1, data_callback_b1), (text_b2, data_callback_b2), ...]
- a string like: `/cmd1, /cmd2, /cmd3`
- or a string like: `text_b1:/cmd1, text_b2:/cmd2`

Example:
```yaml
data:
   message: 'TV is off'
   disable_notification: true
   inline_keyboard:
     - TV ON:/service_call switch.turn_on switch.tv, Other:/othercmd
     - /help, /init
```
- Allow templating for caption, url, file, longitude and latitude fields
- Fix send a file to multiple targets
- Load data with some retrying for HA cameras, which return 500 one or two times sometimes (generic cams, always!).
- Doc in services for new inline keyboards yaml syntax: `Text button:/command`
@mention-bot
Copy link
Copy Markdown

@azogue, thanks for your PR! By analyzing the history of the files in this pull request, we identified @fabaff, @sander76 and @MartinHjelmare to be potential reviewers.

kwargs = dict(service.data)
_render_template_attr(kwargs, ATTR_MESSAGE)
_render_template_attr(kwargs, ATTR_TITLE)
_render_template_attr(kwargs, ATTR_URL)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a for loop here.

_LOGGER.warning("BAD TARGET %s, using default: %s",
try:
chat_ids = [int(t) for t in target
if int(t) in self.allowed_chat_ids]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chat ids in target have already been validated and coerced to integers.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true, this is old, I'm going to simplify it

try:
chat_ids = [int(t) for t in target
if int(t) in self.allowed_chat_ids]
if len(chat_ids) > 0:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if chat_ids:

if len(chat_ids) > 0:
return chat_ids
_LOGGER.warning("Unallowed targets: %s", target)
except (ValueError, TypeError):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When could this happen? Both target and allowed chat ids have been validated as list of integers before this.

return chat_ids
_LOGGER.warning("Unallowed targets: %s", target)
except (ValueError, TypeError):
_LOGGER.warning("Bad target data: %s, using default: %s",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the warning about default be included in the above warning instead? The warning here should never happen.

params = self._get_msg_kwargs(kwargs)
caption = kwargs.get(ATTR_CAPTION)
func_send = self.bot.sendPhoto if is_photo else self.bot.sendDocument
file = load_data(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pick another variable name than file. It's reserved in python.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is still here. 😉

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed! 😓



def load_data(url=None, file=None, username=None, password=None):
def load_data(url=None, file=None, username=None, password=None,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pick another parameter name than file. It's reserved in python.

params["auth"] = HTTPDigestAuth(username, password)
else:
params["auth"] = HTTPBasicAuth(username, password)
req = requests.get(url, **params)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now there's no request without authentication. Is that intended?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

authentication params are included only when are present:

params = {"timeout": 15}
if username is not None and password is not None:
    if authentication == HTTP_DIGEST_AUTHENTICATION:
        params["auth"] = HTTPDigestAuth(username, password)
    else:
        params["auth"] = HTTPBasicAuth(username, password)

What do you mean?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct. I missed that point, sorry.

- Don't use `file` as variable name.
- For loop
- Simplify filter allowed `chat_id`s.
@azogue azogue changed the title Fix callbacks Fix Telegram Bot send file to multiple targets, snapshots of HA cameras, variable templating, digest auth May 26, 2017
Copy link
Copy Markdown
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@azogue
Copy link
Copy Markdown
Member Author

azogue commented May 26, 2017

@MartinHjelmare, sorry, I found one more when testing the examples in the doc.

@UltraSub
Copy link
Copy Markdown

Nice! Is there any chance this will go into a 45.2 release?

@MartinHjelmare
Copy link
Copy Markdown
Member

@azogue Ready to merge?

@azogue
Copy link
Copy Markdown
Member Author

azogue commented May 26, 2017

Yes!

@MartinHjelmare MartinHjelmare merged commit 910020b into home-assistant:dev May 26, 2017
@balloob balloob mentioned this pull request Jun 2, 2017
@azogue azogue deleted the fix-callbacks branch June 4, 2017 12:02
@home-assistant home-assistant locked and limited conversation to collaborators Sep 4, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

5 participants