SMTP to MQTT Add-on

No problem, glad to hear it is working for you. :slight_smile:

sorry for my question but I’m not very expert … I configured everything and from the log I see the test email that my Reolink camera sends … but then how can I see the notification via Homeassistant? I would like to see the image of the motion that is sent to me. i don’t understand what i have to do after configuring the addon

It’s not a complete, turn-key solution, rather it is a way to get the information into home assistant then you have to figure out how you want to use it.

I assume you have the Mosquitto MQTT addon going and the email is published to it?

If so then home assistant can define sensors directly from MQTT topics, home assistant can also define automations that use MQTT topics as their triggers. There’s endless things that can be done once its published to MQTT.

I’ll give you an example of how I currently use it. I read the docs on notifications with attachments & decided to try it myself…

First thing I made sure to turn on ‘Save Attachments’ in this addon. This will save any attachments to the file system, by default under /share/smtp2mqtt/.

Next thing I made sure to configure the media_source integration and add a second folder, like so:

media_dirs:
    local: /media
    smtp2mqtt: /share/smtp2mqtt

The first one is the default, it’s just there for verbosity, the second is the one I need. This goes into the main configuration.yaml, under the main homeassistant: section (be sure to restart after adding it).

The next thing I did was define an automation to send a notification to my android phone and attach the image from the email to it, but I had to do it in yaml because it is a little too complex for the GUI:

alias: Reolink Motion Notification
description: Notify's my phone when there is motion detected from the cameras
trigger:
  - platform: mqtt
    topic: smtp2mqtt/[email protected]
condition:
  - condition: template
    value_template: "{{ trigger.payload_json.mime_parts | length > 1 }}"
  - condition: template
    value_template: "{{ trigger.payload_json.mime_parts[1].best_guess == 'attachment' }}"
action:
  - service: notify.mobile_app_[my_device]
    data:
      title: Reolink Camera
      message: "{{ trigger.payload_json.headers.subject }}"
      data:
        image: >-
          {{trigger.payload_json.mime_parts|selectattr('saved_file_name','defined')|map(attribute='saved_file_name')|first|replace('/share','/media')}}
mode: single

This isn’t perfect and the image will be cropped by the phone to a 2:1 but it works, pretty well, and should give you ideas about other ways you can use this.

Good luck!

Thanks for your huge help. I will try to configure everything…just one last thing about the Log. I think there is some error even though I seem to receive the email.

 warn("Requiring AUTH while not requiring TLS "
auth_required == True but auth_require_tls == False
2023-02-23 16:29:58,452 - smtp2mqtt - INFO - main thread - dummy-authenticating whatever credentials are offered...
Session.login_data is deprecated and will be removed in version 2.0
2023-02-23 16:29:58,546 - smtp2mqtt - INFO - ca2db341 - Message from [email protected]
2023-02-23 16:29:58,548 - smtp2mqtt - DEBUG - ca2db341 - Message data (truncated): From: ""<[email protected]>
To: <[email protected]>
Subject: =?UTF-8?B?VGVzdCBlLW1haWw=?=
Mime-Version: 1.0
Content-Type: multipart/mixed;
    boundary=PartBoundary12345678

--PartBoundary12345678
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

SWYgeW91IHJlY2VpdmUgdGhpcyBlLW1haWwgeW91IGhhdmUgc3VjY2Vzc2Z1bGx5IHNldCB1cCBhbmQgdGVzdGVkIHRoZSBlLW1haWwgYWxlcnQgZnJvbSB5b3VyIElQQw==

--PartBoundary12345678--

2023-02-23 16:29:58,600 - smtp2mqtt - DEBUG - ca2db341 - got message header From: [email protected]
2023-02-23 16:29:58,600 - smtp2mqtt - DEBUG - ca2db341 - got message header To: [email protected]
2023-02-23 16:29:58,601 - smtp2mqtt - DEBUG - ca2db341 - got message header Subject: Test e-mail
2023-02-23 16:29:58,601 - smtp2mqtt - DEBUG - ca2db341 - got message header Mime-Version: 1.0
2023-02-23 16:29:58,602 - smtp2mqtt - DEBUG - ca2db341 - got message header Content-Type: multipart/mixed; boundary="PartBoundary12345678"
2023-02-23 16:29:58,607 - smtp2mqtt - DEBUG - ca2db341 - got body header Content-Type: text/plain; charset="utf-8"
2023-02-23 16:29:58,607 - smtp2mqtt - DEBUG - ca2db341 - got body header Content-Transfer-Encoding: base64
2023-02-23 16:29:58,612 - smtp2mqtt - DEBUG - ca2db341 - stored [If you receive this e-mail you have successfully set up and tested the e-mail alert from your IPC] as the content
2023-02-23 16:29:58,615 - smtp2mqtt - DEBUG - ca2db341 - Publishing [{"uuid": "ca2db341", "headers": {"from": "[email protected]", "to": "[email protected]", "subject": "Test e-mail", "mime-version": "1.0", "content-type": "multipart/mixed; boundary=\"PartBoundary12345678\""}, "mime_parts": [{"best_guess": "message body", "headers": {"content-type": "text/plain; charset=\"utf-8\"", "content-transfer-encoding": "base64"}, "content": "If you receive this e-mail you have successfully set up and tested the e-mail alert from your IPC"}, {"best_guess": "message body", "headers": {"content-type": "text/plain; charset=\"utf-8\"", "content-transfer-encoding": "base64"}, "content": "If you receive this e-mail you have successfully set up and tested the e-mail alert from your IPC"}]}] to smtp2mqtt/[email protected]
2023-02-23 16:29:59,551 - smtp2mqtt - ERROR - ca2db341 - Failed publishing
Traceback (most recent call last):
  File "/app/smtp2mqtt.py", line 152, in mqtt_publish
    publish.single(
  File "/usr/lib/python3.10/site-packages/paho/mqtt/publish.py", line 240, in single
    multiple([msg], hostname, port, client_id, keepalive, will, auth, tls,
  File "/usr/lib/python3.10/site-packages/paho/mqtt/publish.py", line 176, in multiple
    client.connect(hostname, port, keepalive)
  File "/usr/lib/python3.10/site-packages/paho/mqtt/client.py", line 914, in connect
    return self.reconnect()
  File "/usr/lib/python3.10/site-packages/paho/mqtt/client.py", line 1044, in reconnect
    sock = self._create_socket_connection()
  File "/usr/lib/python3.10/site-packages/paho/mqtt/client.py", line 3685, in _create_socket_connection
    return socket.create_connection(addr, timeout=self._connect_timeout, source_address=source)
  File "/usr/lib/python3.10/socket.py", line 824, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
  File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name does not resolve
2023-02-23 16:29:59,571 - smtp2mqtt - DEBUG - ca2db341 - SKIP relaying the original email

OK, you’re getting there… :slight_smile:

Looks like your camera is configured correctly and this addon is working, however it is having trouble publishing to MQTT.

Do you have an MQTT broker running & available? It’s common to just install the Mosquitto addon. If you have that then you’ll need to look at its config and make note of the username and password you configured for it, then come back to the config for this addon and enter those in the appropriate fields, then restart it & try again.

If you don’t have the Mosquitto addon then you’ll need some kind of MQTT broker on your network and you’ll need to enter its host/IP in the config of this addon so it knows where to publish, along with any username & password, etc.

Regardless of which MQTT broker you use, you’ll also need the MQTT integration (so home assistant can incorporate MQTT events & utilize them).

It’s been a while since I have installed the MQTT integration but if I remember right, when you use the Mosquitto addon, installing and configuring the MQTT integration is pretty painless (you may need to make note of that username & password again).

Now I think I have no more errors. I have mqtt installed on docker in debian. I had to enter the home assistant’s ip address. the username and password were already correct

2023-02-23 17:01:53,382 - smtp2mqtt - INFO - main thread - dummy-authenticating whatever credentials are offered...
Session.login_data is deprecated and will be removed in version 2.0
2023-02-23 17:01:53,472 - smtp2mqtt - INFO - f1ef10d7 - Message from [email protected]
2023-02-23 17:01:53,473 - smtp2mqtt - DEBUG - f1ef10d7 - Message data (truncated): From: ""<[email protected]>
To: <[email protected]>
Subject: =?UTF-8?B?VGVzdCBlLW1haWw=?=
Mime-Version: 1.0
Content-Type: multipart/mixed;
    boundary=PartBoundary12345678

--PartBoundary12345678
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

SWYgeW91IHJlY2VpdmUgdGhpcyBlLW1haWwgeW91IGhhdmUgc3VjY2Vzc2Z1bGx5IHNldCB1cCBhbmQgdGVzdGVkIHRoZSBlLW1haWwgYWxlcnQgZnJvbSB5b3VyIElQQw==

--PartBoundary12345678--

2023-02-23 17:01:53,508 - smtp2mqtt - DEBUG - f1ef10d7 - got message header From: [email protected]
2023-02-23 17:01:53,509 - smtp2mqtt - DEBUG - f1ef10d7 - got message header To: [email protected]
2023-02-23 17:01:53,510 - smtp2mqtt - DEBUG - f1ef10d7 - got message header Subject: Test e-mail
2023-02-23 17:01:53,511 - smtp2mqtt - DEBUG - f1ef10d7 - got message header Mime-Version: 1.0
2023-02-23 17:01:53,512 - smtp2mqtt - DEBUG - f1ef10d7 - got message header Content-Type: multipart/mixed; boundary="PartBoundary12345678"
2023-02-23 17:01:53,520 - smtp2mqtt - DEBUG - f1ef10d7 - got body header Content-Type: text/plain; charset="utf-8"
2023-02-23 17:01:53,521 - smtp2mqtt - DEBUG - f1ef10d7 - got body header Content-Transfer-Encoding: base64
2023-02-23 17:01:53,530 - smtp2mqtt - DEBUG - f1ef10d7 - stored [If you receive this e-mail you have successfully set up and tested the e-mail alert from your IPC] as the content
2023-02-23 17:01:53,536 - smtp2mqtt - DEBUG - f1ef10d7 - Publishing [{"uuid": "f1ef10d7", "headers": {"from": "[email protected]", "to": "[email protected]", "subject": "Test e-mail", "mime-version": "1.0", "content-type": "multipart/mixed; boundary=\"PartBoundary12345678\""}, "mime_parts": [{"best_guess": "message body", "headers": {"content-type": "text/plain; charset=\"utf-8\"", "content-transfer-encoding": "base64"}, "content": "If you receive this e-mail you have successfully set up and tested the e-mail alert from your IPC"}, {"best_guess": "message body", "headers": {"content-type": "text/plain; charset=\"utf-8\"", "content-transfer-encoding": "base64"}, "content": "If you receive this e-mail you have successfully set up and tested the e-mail alert from your IPC"}]}] to smtp2mqtt/[email protected]
2023-02-23 17:01:53,546 - smtp2mqtt - DEBUG - f1ef10d7 - SKIP relaying the original email

That looks good to me.

Your emails should be publishing to that MQTT broker now.

All you need is to make sure home assistant is aware of the broker (via the MQTT integration) and then you should be able to start defining sensors, automations, etc. that utilize the topic being published to.

everything works perfectly!! thanks for your patience

No problem, glad to hear it is working for you :slight_smile:

thanks again for the help! I have only two things to ask… the first is that I find the smtp2 folder on media which is always full of images that I have to delete after every day but this is not a big problem… the problem is that when I get the notification on the phone and I open it directs me to the home screen of the home assistant app and therefore I have to go manually to the media folder and look for the file corresponding to the date and time but which with the presence of so many files is difficult to find … there is no is there a way to open the notification and direct me to the full screen image?

I researched this a little, found this post:

How to open /media image via relative URL in clickAction?

So I added a ‘clickAction’ in my automation, just below the ‘image’ that was already there, like so:

data:
    image: >-
      {{trigger.payload_json.mime_parts|selectattr('saved_file_name','defined')|map(attribute='saved_file_name')|first|replace('/share','/media')}}
    clickAction: >-
      {{trigger.payload_json.mime_parts|selectattr('saved_file_name','defined')|map(attribute='saved_file_name')|first|replace('/share','/media')}}

And it looked like it was going to work, but then all I got was a ‘401 unauthorized’ which is what they OP was saying in that post.

So then I followed the open issues on it:

https://github.com/home-assistant/android/issues/2684

https://github.com/home-assistant/android/pull/3232

And it looks like they put a fix into the current beta release of the Android app:

https://github.com/home-assistant/android/releases/tag/beta-3232-aaef2549

I downloaded the .apk for that beta & tried it, still didn’t work.

So at this time it looks like there are provisions for doing something like this, but it doesn’t currently work, sorry.

As for cleaning up the share folder with all the images, I have a scheduled automation that runs a Shell Command service nightly.

The shell command itself is simple:

find /share/smtp2mqtt/ -maxdepth 1 -type f -mtime +1 -exec rm {} \;

This seems to work well, keeps the files trimmed down to about a couple days’ worth.

Ok thanks!I hope this problem is solved because it would be a very useful thing

is there a possibility to rename the files in order to be more recognizable? for example ordering them with a starting number…it’s really hard to find the picture by phone because they are ordered randomly

Apologies for taking so long to reply to this, been very busy lately.

I did think about this for a bit & decided against modifying the add-on to re-name since others may want something different and it could get out of hand trying to find a way to make it generic enough for everyone.

Instead I had another thought - I believe it would be relatively simple to use the Shell Command integration to rename the files after they are written to disk.

It could be an action in the automation to call a shell command that simply does an mv from the current file name to whatever file name you wish.

Probably do that early-on, then reference the new file name in the notification service (since the old file name won’t exist anymore after the mv).

So, it looks like my camera updated its firmware and I can get smtp to Gmail to work. However, when I try this addon I’m getting some errors. The camera throws the same error 400, but there’s some new stuff in the logs now:

/usr/lib/python3.10/site-packages/aiosmtpd/smtp.py:372: UserWarning: Requiring AUTH while not requiring TLS can lead to security vulnerabilities!
  warn("Requiring AUTH while not requiring TLS "
auth_required == True but auth_require_tls == False
('192.168.168.125', 61559) unrecognised: e#

Is there anything I can do to hopefully get this working?

1 Like

I’m getting the exact same problem. I tried to configure this add-on with with my Reolink Argos Eco camera but every time I send a test email, I get a 400 error and this is the only message in the logs.

I found the problem with my Reolink Argos Eco camera.

It turns out that the camera sends an SMTP “HELO” message instead of “EHLO”. The SMTP library used by this add-on(“aiosmtpd”), considers the “HELO” not to be extended_smtp and later rejects the “AUTH LOGIN” command from the camera.

I don’t think there is an easy workaround other than modifying the “aiosmtpd” lib to force the extended_smtp mode for “HELO” as well.

Thank you for digging into the aiosmtp library & uncovering the difference between EHELO and HELO, that helps!

I can see in the code of the aiosmtp library where it is doing what you say, I can also see where it may be possible to override the HELO handler in this add-on to ‘turn on’ the extended smtp features, which may possibly be a work-around.

However, I am limited on time. I will try to make an effort in the next week or-so, no guarantees.

In the meantime, I’ll re-iterate my usual go-to - I know the password field in the camera web UI is marked required but I own several different Reolink devices and they all let me both test & save email settings when I leave that field blank and I am able to use this add-on with ‘SMTP Auth Required’ turned off, with no issues.

Could you please try again to leave the password field blank? Don’t forget to turn off SMTP auth in the add-on configuration as well.

Thanks again for doing the research!

I ran into this same HELO vs EHLO issue trying to use this add-on for a Cummins standby generator that sends events as emails.
As suggested the problem was fixed by adding the following method to SMTP2MQTTHandler:

    async def handle_HELO(self, server, session, envelope, hostname):
        session.extended_smtp = True
        session.host_name = server.hostname
        status = '250 {}'.format(server.hostname)
        return status

Good evening, I need help, I’ve been trying for a long time but I can’t get the images from my camera to publish on mqtt… With PowerShell Test I can publish but when my camera send image email I get the following error:

2024-03-21 23:16:02,254 - smtp2mqtt - DEBUG - d397f285 - SKIP publish attachment data
2024-03-21 23:16:02,255 - smtp2mqtt - INFO - d397f285 - Saving attachment to /share/smtp2mqtt/[email protected]/d397f285_6129747_2024032123160201.jpg
2024-03-21 23:16:02,261 - smtp2mqtt - DEBUG - d397f285 - SKIP publish attachment data
2024-03-21 23:16:02,261 - smtp2mqtt - INFO - d397f285 - Saving attachment to /share/smtp2mqtt/[email protected]/d397f285_None
(‘192.168.1.11’, 46242) SMTP session exception
Traceback (most recent call last):
File “/usr/lib/python3.10/site-packages/aiosmtpd/smtp.py”, line 741, in _handle_client
await method(arg)
File “/usr/lib/python3.10/site-packages/aiosmtpd/smtp.py”, line 1460, in smtp_DATA
status = await self._call_handler_hook(‘DATA’)
File “/usr/lib/python3.10/site-packages/aiosmtpd/smtp.py”, line 473, in _call_handler_hook
status = await hook(self, self.session, self.envelope, *args)
File “/app/smtp2mqtt.py”, line 127, in handle_DATA
f.write(attachment.get_content())
TypeError: a bytes-like object is required, not ‘str’ <