signal-cli-rest-api icon indicating copy to clipboard operation
signal-cli-rest-api copied to clipboard

Home assistant warning "JSON result was not a dictionary or list with 0th element a dictionary"

Open silentnyte opened this issue 2 years ago • 15 comments
trafficstars

The problem

I am using https://github.com/haberda/hassio_addons/tree/master/signal_messenger and https://www.home-assistant.io/integrations/signal_messenger/. Everything seems to work okay but I am getting constant warning messages "JSON result was not a dictionary or list with 0th element a dictionary". I think that this is occurring when REST returns a blank message "[]".

Is there a way to stop this?

Are you using the latest released version?

  • [X] Yes

Have you read the troubleshooting page?

  • [X] Yes

What type of installation are you running?

Home Assistant Signal Addon

In which mode are you using the docker container?

Native Mode

What's the architecture of your host system?

arm64

Additional information

configuration.yaml

rest:

  • resource: "http://192.168.1.1:8080/v1/receive/+11235551234" headers: Content-Type: application/json sensor:
    • name: "Signal message received" value_template: "" #this will fetch the message json_attributes_path: $[0].envelope json_attributes:
      • source #source phone number attribute.

notify:

  • platform: signal_messenger name: signal url: "http://192.168.1.1:8080" number: "+11235551234" recipients:
    • "+11235551234"

silentnyte avatar Jul 11 '23 19:07 silentnyte

If I understood it correctly, your assumption is, that it happens when the receive endpoint returns nothing, right?

Do you also see the same error in the log, when you call the receive via curl? e.g: curl -X GET -H "Content-Type: application/json" 'http://192.168.1.1:8080/v1/receive/+11235551234'

bbernhard avatar Jul 13 '23 19:07 bbernhard

When I execute the curl command it returns [] 99% of the time unless I am currently send or receiving a message.

silentnyte avatar Jul 21 '23 12:07 silentnyte

I have exact same issue. I can read the message via curl if I evoke it just after sending the message, otherwise it returns []

jasku-ha avatar Jul 25 '23 10:07 jasku-ha

+1 on this for me too

developersteve avatar Aug 13 '23 10:08 developersteve

If I understood it correctly, this is an error message from Home Assistant and not from the REST API, right?

bbernhard avatar Aug 15 '23 10:08 bbernhard

Yes this is a warning message from Home assistant because the REST API is returning an empty array "[]".

Not sure where the best place to fix this is. Should HA ignore empty returns or the API not return empty? What are your thoughts?

silentnyte avatar Aug 15 '23 12:08 silentnyte

I do not have much experience with the Home Assistant REST API component, but to me that looks like an issue that needs to be fixed in HA. IMHO, an empy array is a perfectly fine payload, in case there's no data available. I guess, you need to adapt your HA rest sensor slightly, so that it can deal with the empty array. Unfortunately, I do not have enough knowledge about the HA rest sensor, but you could post the question in the Home Assistant user forum :)

bbernhard avatar Aug 15 '23 16:08 bbernhard

In my case I've been calling the /v1/receive/number endpoint directly to see what sort of response I'd be expecting, the test messages I'm sending to the number i'm checking are not being shown as read and I'm only getting a [] response.

developersteve avatar Aug 19 '23 12:08 developersteve

Was there any solution to this or a an answer somewhere on the HA community?

fbbln avatar Feb 03 '24 14:02 fbbln

Here was my solution using jinja filters, it avoids the 0th element access so no errors in the logs. Also avoids errors from attempting to process "receiptMessages". Restricting messages from a single source number is implemented with the selectattr() filter instead of separate sensor or sensor attribute.

rest:
    scan_interval: 10
    resource: "http://<IP>:8080/v1/receive/+12345678900"
    headers:
      Content-Type: application/json
    sensor:
        - name: "Signal message received"
          value_template: "{{ value_json | selectattr('envelope.source', 'eq', '+198765432100') | default('') | map(attribute='envelope.dataMessage.message') | first | default('')  }}"

...and if you were looking to pass the signal message onto voice Assistant, here is an automation for that:

alias: Signal Process Received Message
description: Pass text from incoming signal message to assist pipeline
trigger:
  - platform: state
    entity_id:
      - sensor.signal_message_received
condition:
  - condition: not
    conditions:
      - condition: state
        entity_id: sensor.signal_message_received
        state: unavailable
      - condition: state
        entity_id: sensor.signal_message_received
        state: unknown
      - condition: state
        entity_id: sensor.signal_message_received
        state: ""
action:
  - service: conversation.process
    metadata: {}
    data:
      agent_id: homeassistant
      text: "{{ states('sensor.signal_message_received') }}"
    response_variable: signal_reply
  - service: notify.notify_signal
    data:
      message: "{{signal_reply.response.speech.plain.speech }}"
variables:
  signal_reply: null
mode: single

mulcmu avatar Apr 26 '24 22:04 mulcmu

Here was my solution using jinja filters, it avoids the 0th element access so no errors in the logs. Also avoids errors from attempting to process "receiptMessages". Restricting messages from a single source number is implemented with the selectattr() filter instead of separate sensor or sensor attribute.

Interesting. As I have no experience with this - which part is it that avoids the log errors?

nurunet avatar May 01 '24 20:05 nurunet

The [0] from the sample code is what is problematic when there are no messages to retrieve and an empty list is returned.

json_attributes_path: $[0].envelope

The selectattr() doesn't trigger an error when processing an empty list.

mulcmu avatar May 03 '24 23:05 mulcmu

This almost almost works, but you lose the source as and attribute of the rest response. :(

FYI you can change your example to this to use a list of allowed from your secrets file.

input_select:
  allowed_numbers:
    options: !secret allowed_numbers

rest:
    scan_interval: 10
    resource: "http://<IP>:8080/v1/receive/+12345678900"
    headers:
      Content-Type: application/json
    sensor:
        - name: "Signal message received"
          value_template: "{{ value_json | selectattr('envelope.source', 'in', states('input_select.allowed_numbers')) | default('') | map(attribute='envelope.dataMessage.message') | first | default('')  }}"

silentnyte avatar May 10 '24 23:05 silentnyte

FYI you can change your example to this to use a list of allowed from your secrets file.

How do you store a list of numbers as a secret?

nurunet avatar May 11 '24 14:05 nurunet

allowed_numbers:
  - "+1234567890"
  - "+1987654321"

silentnyte avatar May 11 '24 22:05 silentnyte