Automatically pass non-null values to restful command?

I have a restful notify command setup in configuration.yaml to post template data as json to an external service:

notify:
  - name: ntfy
    platform: rest
    method: POST_JSON
    data:
        topic: "{{ data.topic }}"
        priority: "{{ data.priority | default('default') }}"
        tags: "{{ data.tags }}"
        icon: "{{ data.icon | default('') }}"
        attach: "{{ data.attach | default('') }}"
        click: "{{ data.click | default('') }}"
        actions: "{{ data.actions | default(null) }}"
    title_param_name: title
    message_param_name: message
    resource: https://server_address

The problem is that not all data fields are used, and the service being called doesn’t like the default values being provided. Ideally I should only provide data fields for which there is an actual value.

I’ve tried passing in the entire data object, but that fails as well:

notify:
  - name: ntfy
    platform: rest
    method: POST_JSON
    data: "{{ data }}"
    title_param_name: title
    message_param_name: message
    resource: https://server_address

Is there a way to pass in data fields only if they have values?

The alternative would be to turn it into a shell command and pass the json data directly in the request body. But, again, this requires direct access to the json data as a string. I don’t know how to access it in that form.

shell_command:
    ntfy: curl -d "{ data }" https://server_address

You can template the entire data field.

notify:
  - name: ntfy
    platform: rest
    method: POST_JSON
    data: >
      {% set info = {
        'topic': data.topic,
        'priority': data.priority | default(None),
        'tags': data.tags,
        'icon': data.icon | default(None),
        'attach': data.attach | default(None),
        'click': data.click | default(None),
        'actions': data.actions | default(None) } %}
     {{ dict.from_keys(info.items() | rejectattr('1', 'none') | list) }}
    title_param_name: title
    message_param_name: message
    resource: https://server_address
1 Like

That is amazing. I’ll have to look up what the dictionary bits at the end do, I assume removing empty entries? Thanks!

yep

1 Like

Strangely, I get an error from it.

2023-06-06 15:21:25.908 ERROR (MainThread) [homeassistant.config]
Invalid config for [notify.rest]: expected dict for dictionary value @ data['data'].
Got "{% set info = {\n  'topic': data.topic,\n  'priority': data.priority | default(None),\n  'tags': data.tags | default(None),\n  'icon': data.icon | default(None),\n  'attach': data.attach | default(None),\n  'click': data.click | default(None),\n  'actions': data.actions | default(None) } %}\n{{ dict.from_keys(info.items() | rejectattr('1', 'none') | list) }}\n".
(See /config/configuration.yaml, line 13).
Please check the docs at https://www.home-assistant.io/integrations/rest
notify:
  - name: ntfy
    platform: rest
    method: POST_JSON
    data: >
      {% set info = {
        'topic': data.topic,
        'priority': data.priority | default(None),
        'tags': data.tags | default(None),
        'icon': data.icon | default(None),
        'attach': data.attach | default(None),
        'click': data.click | default(None),
        'actions': data.actions | default(None) } %}
      {{ dict.from_keys(info.items() | rejectattr('1', 'none') | list) }}
    title_param_name: title
    message_param_name: message
    resource: https://server_address

If that’s the case, then the documentation is wrong or there’s an error in the template.

This is a bug it seems in the yaml validation.