TooGoodToGo MQTT Bridge

simply search for toogoodtogo, they all start the same:

Cheers MaxW :+1:t2: :blush:
I did it before my message but the only I have are that one :


Maybe a mqtt problem ? Thx for your help :hugs:

Update: I delete my Mosquitto Integration, reboot HassOS, install again the Mosquitto borker and : DONE ! :+1:t2:

Good job @MaxW. Thanks :hugs:

Thank for the TGTG checker! reallynice…

i’ve setup the docker one (image: maxwinterstein/toogoodtogo-ha-mqtt-bridge
) …everything is ok but with an issue, even if i have the confg:
“every_n_minutes”: 10
it checks evere 30sec as i can see in the log…

any idea?

I have understood the question. I needed to download the last docker image with the new settings and options.

docker pull maxwinterstein/toogoodtogo-ha-mqtt-bridge:1.5.0

Now it recognize the every_n_minutes settings.

Thanks for this useful addon. I have added it to my Home Assistant and have created another implementation for the notification automations.
My automations do show a persistent notification via the Home Assistant Companion app as long there is stock available. By clicking the notification your TooGoodToGo app will directly open the right offer.

- id: toogoodtogo_stock_available
  alias: 'TooGoodToGo - Stock Available'
  description: 'TooGoodToGo - Stock Available'
  trigger:
    - platform: state
      entity_id:
        - sensor.toogoodtogo_xxx
        - sensor.toogoodtogo_yyy
        - sensor.toogoodtogo_zzz
  condition: "{{ trigger.to_state.state | int > 0 }}"
  mode: queued
  variables:
    stock: "{{ states(trigger.to_state.entity_id) }}"
    name: "{{ state_attr(trigger.to_state.entity_id, 'friendly_name') }}"
    picture: "{{ state_attr(trigger.to_state.entity_id, 'picture') }}"
    url: "{{ state_attr(trigger.to_state.entity_id, 'url') }}"
  action:
    - service: notify.mobile_app_xxx
      data:
        title: "TooGoodToGo stock"
        message: >
          {% set entityID = trigger.to_state.entity_id %}
          {% set names = state_attr(entityID,'friendly_name').split('-') %}
          {% set namesLength = names | length %}
          {% if namesLength > 2 %}
          {% set outName = names[1] + '-' + names[2] %}
          {% else %}
          {% set outName = names[1] %}
          {% endif %}
          {{ states(entityID) }}x{{ outName }} €{{ state_attr(entityID,'price') }}
        data:
          ttl: 0
          priority: high
          sticky: true
          channel: "TooGoodToGo"
          persistent: true
          tag: "{{ trigger.to_state.entity_id }}"
          image: "{{ picture }}"
          url: "{{ url }}"
          clickAction: "{{ url }}"
          actions:
            - action: "URI"
              title: "Open"
              uri: "{{ url }}"

- id: toogoodtogo_stock_gone
  alias: 'TooGoodToGo - Stock Gone'
  description: 'TooGoodToGo - Stock Gone'
  trigger:
    - platform: state
      entity_id:
        - sensor.toogoodtogo_xxx
        - sensor.toogoodtogo_yyy
        - sensor.toogoodtogo_zzz
      to: '0'
  mode: queued
  action:
    - service: notify.mobile_app_xxx
      data:
        message: "clear_notification"
        data:
          tag: "{{ trigger.to_state.entity_id }}"
2 Likes

VERY NICE !!!

1 Like

Since last update HA to 2021.7 I see this error:

2021-07-07 18:16:54 ERROR (MainThread) [homeassistant.components.mobile_app.notify] The length of [apns-collapse-id] header must not exceed [64] bytes. This message is generated externally to Home Assistant.
2021-07-07 18:16:55 ERROR (MainThread) [homeassistant.components.mobile_app.notify] The length of [apns-collapse-id] header must not exceed [64] bytes. This message is generated externally to Home Assistant.
2021-07-07 18:16:55 ERROR (MainThread) [homeassistant.components.mobile_app.notify] The length of [apns-collapse-id] header must not exceed [64] bytes. This message is generated externally to Home Assistant.
2021-07-07 18:24:30 ERROR (MainThread) [homeassistant.components.mobile_app.notify] The length of [apns-collapse-id] header must not exceed [64] bytes. This message is generated externally to Home Assistant.
2021-07-07 18:31:36 ERROR (MainThread) [homeassistant.components.mobile_app.notify] The length of [apns-collapse-id] header must not exceed [64] bytes. This message is generated externally to Home Assistant.

It is something with the notification. When a notification is send I get this error line.
What can this be? The image?

That error is caused by the message tag. The entity_id was used but these are too long for your favourites.

I have created a fix for this problem. You have to alter the tag from:
tag: "{{ trigger.to_state.entity_id }}"
to:
tag: "{{ 'tgtg' + state_attr(trigger.to_state.entity_id, 'url').split('/') | last }}"

The new tag will use the item id (prefixed with tgtg) as tag.

2 Likes

Thanks for the vast solution!

Maybe a good idea to say that this is build for Android notifications.
Some of the data part is not used for iOS users:

          priority: high
          sticky: true
          channel: "TooGoodToGo"
          persistent: true
          tag: "{{ trigger.to_state.entity_id }}"

GI,

I see this error pop up:

2021-11-02 15:04:39 f1c878cb-tgtg-ha-mqtt-bridge __main__[309] INFO Connecting mqtt
2021-11-02 15:04:39 f1c878cb-tgtg-ha-mqtt-bridge __main__[309] INFO Starting loop
2021-11-02 15:04:39 f1c878cb-tgtg-ha-mqtt-bridge __main__[309] DEBUG Loop run started
2021-11-02 15:04:39 f1c878cb-tgtg-ha-mqtt-bridge __main__[309] DEBUG Pushing message for HEMA - Amsterdam - Gelderlandplein (Magic Box) // 9325
Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "toogoodtogo_ha_mqtt_bridge/main.py", line 149, in loop
    if not check():
  File "toogoodtogo_ha_mqtt_bridge/main.py", line 62, in check
    price = shop["item"]["price"]["minor_units"] / pow(10, shop["item"]["price"]["decimals"])
KeyError: 'price'

What can this be?

Well, seems they changed something on their data structure.
Some others mentioned this nearly simultaneously on the repo.

It should be fixed with the newest version of the add-on :slight_smile:

1 Like

hi Max,

I can’t get it working. ( and i accepted the mails)
Is the last problem (2 nov already solved?)
And i don’t no if have the same problem.

Greatings Peter.

Add-on version: 1.9.2
You are running the latest version of this add-on.
System: Home Assistant OS 7.0 (amd64 / qemux86-64)
Home Assistant Core: 2021.12.3
Home Assistant Supervisor: 2021.12.2

Please, share the above information when looking for help
or support in, e.g., GitHub, forums or the Discord chat.

[cont-init.d] 00-banner.sh: exited 0.
[cont-init.d] 01-log-level.sh: executing…
[cont-init.d] 01-log-level.sh: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] done.
[13:40:18] INFO: Copy setings file
[13:40:18] INFO: Strating Bridge
2021-12-19 13:40:19 1e14b3fb-tgtg-ha-mqtt-bridge main[310] INFO Connecting mqtt
2021-12-19 13:40:19 1e14b3fb-tgtg-ha-mqtt-bridge main[310] INFO Starting loop
2021-12-19 13:40:19 1e14b3fb-tgtg-ha-mqtt-bridge main[310] DEBUG Logging in with credentials
Exception in thread Thread-3:
Traceback (most recent call last):
File “/usr/local/lib/python3.8/threading.py”, line 932, in _bootstrap_inner
self.run()
File “/usr/local/lib/python3.8/threading.py”, line 870, in run
self._target(*self._args, **self._kwargs)
File “toogoodtogo_ha_mqtt_bridge/main.py”, line 200, in loop
tgtg_client.login()
File “/usr/local/lib/python3.8/site-packages/tgtg/init.py”, line 139, in login
self.start_polling(first_login_response[“polling_id”])
File “/usr/local/lib/python3.8/site-packages/tgtg/init.py”, line 179, in start_polling
raise TgtgPollingError(
tgtg.exceptions.TgtgPollingError: Max retries (120 seconds) reached. Try again.

Never saw this message o.O

Is there still an issue?

I use docker. Where should I paste settings.local.json?
image

I use Add-On and i my log find this:

Add-on version: 2.4.0
You are running the latest version of this add-on.
System: Ubuntu 20.04.5 LTS (amd64 / qemux86-64)
Home Assistant Core: 2022.8.7
Home Assistant Supervisor: 2022.08.3
[cont-init.d] 00-banner.sh: exited 0.
[cont-init.d] 01-log-level.sh: executing…
[cont-init.d] 01-log-level.sh: exited 0.
[cont-init.d] toogoodtogo-ha-mqtt-bridge.sh: executing…
[17:16:06] INFO: Copy settings file
No saved tokens found.
Please make sure to check your email for the login request and answer quickly.
You can’t open it on a mobile phone where the TGTG app itself is installed.
[cont-init.d] toogoodtogo-ha-mqtt-bridge.sh: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] done.
[17:16:06] INFO: Strating Bridge…
2022-08-28 17:16:09 [INFO] Connecting mqtt
2022-08-28 17:16:09 [INFO] Starting loop
2022-08-28 17:16:09 [INFO] Logging in with credentials
Exception in thread Thread-3:
Traceback (most recent call last):
File “/usr/local/lib/python3.8/threading.py”, line 932, in _bootstrap_inner
self.run()
File “/usr/local/lib/python3.8/threading.py”, line 870, in run
self._target(*self._args, **self._kwargs)
File “/app/toogoodtogo_ha_mqtt_bridge/main.py”, line 294, in fetch_loop
tgtg_client.login()
File “/usr/local/lib/python3.8/site-packages/tgtg/init.py”, line 156, in login
self.start_polling(first_login_response[“polling_id”])
File “/usr/local/lib/python3.8/site-packages/tgtg/init.py”, line 203, in start_polling
raise TgtgPollingError(
tgtg.exceptions.TgtgPollingError: Max retries (120 seconds) reached. Try again.

cleanup set to false

EDIT: Any restart = login request.
So now i see in logs:

429, ‘Too many requests. Try again later.’

EDIT2:
OK, after few hours working good.
I would have a few configuration notes:

  1. In the configuration, change the host to your own where HA is installed (it was not so obvious for me), for example: from homeassistant to 192.168.1.200
  2. In order for the token to be saved correctly, before run addon you need to LOG OUT of the application (of course, we do the registration earlier) on your phone and then 2 emails come (the first with a request to log in and another with a code to enter)
    I suppose the bugs I am reporting are due to these two settings being incorrect.

Somehow the container is crashing after a few minutes. Is this a known bug?
I’m running it on my Raspbbery Pi 3

2022-09-02 10:24:49 [DEBUG] Pushing message for Aral Tankstelle (Abendangebot) // 781717
2022-09-02 10:24:49 [DEBUG] Message published: Autodiscover: True, State: True, Attributes: True
2022-09-02 10:24:49 [DEBUG] Pushing message for sßdländische Spezialität  // 781610
2022-09-02 10:24:49 [DEBUG] Message published: Autodiscover: True, State: True, Attributes: True
2022-09-02 10:24:49 [DEBUG] Pushing message for Restaurant // 18181
2022-09-02 10:24:49 [DEBUG] Message published: Autodiscover: True, State: True, Attributes: True
2022-09-02 10:24:49 [DEBUG] Pushing message for China (Abend) // 20538
2022-09-02 10:24:49 [DEBUG] Message published: Autodiscover: True, State: True, Attributes: True
2022-09-02 10:24:49 [DEBUG] Pushing message for Dat Backhus // 541719
2022-09-02 10:24:49 [DEBUG] Message published: Autodiscover: True, State: True, Attributes: True
2022-09-02 10:24:49 [DEBUG] known_shops.json exists at /data//known_shops.json
2022-09-02 10:24:49 [DEBUG] Loop run finished
2022-09-02 10:24:49 [INFO] Next run at 2022-09-02 10:33:01
2022-09-02 10:33:01 [DEBUG] Loop run started
2022-09-02 10:33:01 [INFO] Written tokens.json file to filesystem
Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 449, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 444, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.8/http/client.py", line 1347, in getresponse
    response.begin()
  File "/usr/local/lib/python3.8/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.8/http/client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.8/socket.py", line 669, in readinto
    return self._sock.recv_into(b)
  File "/usr/local/lib/python3.8/ssl.py", line 1241, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/local/lib/python3.8/ssl.py", line 1099, in read
    return self._sslobj.read(len, buffer)
ConnectionResetError: [Errno 104] Connection reset by peer
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 785, in urlopen
    retries = retries.increment(
  File "/usr/local/lib/python3.8/site-packages/urllib3/util/retry.py", line 550, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/local/lib/python3.8/site-packages/urllib3/packages/six.py", line 769, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 449, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 444, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.8/http/client.py", line 1347, in getresponse
    response.begin()
  File "/usr/local/lib/python3.8/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.8/http/client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.8/socket.py", line 669, in readinto
    return self._sock.recv_into(b)
  File "/usr/local/lib/python3.8/ssl.py", line 1241, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/local/lib/python3.8/ssl.py", line 1099, in read
    return self._sslobj.read(len, buffer)
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/app/toogoodtogo_ha_mqtt_bridge/main.py", line 303, in fetch_loop
    if not check():
  File "/app/toogoodtogo_ha_mqtt_bridge/main.py", line 46, in check
    shops = tgtg_client.get_items(page_size=400)
  File "/usr/local/lib/python3.8/site-packages/tgtg/__init__.py", line 246, in get_items
    response = self.session.post(
  File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 635, in post
    return self.request("POST", url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 547, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
2022-09-02 10:50:29 [ERROR] Watchdog handler fired! No pull in the last 25.666666666666668 minutes!
NoneType: None
[cont-finish.d] executing container finish scripts...
[cont-finish.d] 99-message.sh: executing... 
[cont-finish.d] 99-message.sh: exited 0.
[cont-finish.d] done.
[s6-finish] waiting for services.
[s6-finish] sending all processes the TERM signal.

Great automations, but after stocks are gone, I still have a notifications in the HA app (Android) with 0 available.
These notifications only disappeared after reboot the phone.
Am I missing something in the code?
EDIT: It turns out that it works fine today. In any case, I am watching to see if it starts to fail again.

Feature request: able to manual give a client_id

Hello everyone,
There has recently been a limit of 500 app notifications per day.
In my case, it ends around 6 pm :frowning:
Does anyone have an idea how to move the notifications (in the same format as now) to ntfy (I have my own server) which will bypass the limit?
I have added code to the automation:

  - service: notify.ntfy
    data:
      title: TooGoodToGo paczki dostępne
      message: '{% set entityID = trigger.to_state.entity_id %} {% set names = state_attr(entityID,''friendly_name'').split('' '') %} {% set namesLength = names | length %} {% if namesLength > 0 %} {%set outName = names[0] + '' '' + names[1] + '' '' + names[2] %} {% else %} {%set outName = names[1] %} {% endif %} {{states(entityID)}} x {{outName}} po {{state_attr(entityID,''price'')}}'
      data:
        topic: tgtg
        priority: 4
        tags: '{{ trigger.to_state.entity_id }}'
        attach: '{{ picture }}'
        click: '{{ url }}'
        actions:
          action: view
          label: Open
          url: '{{ url }}'
          clear: true

It works, but notifications are only in text form (no clickable links, no image):

Seemingly everything looks like in the ntfy documentation, but where is the error?