Trying to template filter a imap sensor value_template with base64

So i have this imap_email_content sensor and the email it returns is in base64. So i was trying to pass the body content to | base64 but i can’t seem to figure out where to place the base64_decode. I tried behind body | base64_decode directly, encase it with (), with {} behind, none of it seems to work.

  - platform: imap_email_content
    name: Dominos
    server: imap.gmail.com
    #search: SUBJECT dominos pizza order confirmation
    port: 993
    username: !secret x_google
    password: !secret x_google_pw
    folder: Inbox
    senders:
      - [email protected]
    value_template: >-
      {% if (body is search('sorting your order')) and 
      (now() - (strptime(date, "%a, %d %b %Y %H:%M:%S %z")) < timedelta(minutes=5)) %}
        order
      {% else %}
        no_order
      {% endif %}

Many thanks for any tips/pointers.

The IMAP integration has been updated and YAML configuration was removed in 2023.4. I think the likely issue is not the base_64 conversion, but the time comparison. The date variable is now a datetime object instead of a string.

IMAP content is now available using trigger-based template sensors. To maintain your outputs and auto-reset you will need to add a second trigger. Another option would be to create a binary sensor instead and use the auto_off configuration variable.

template:
  - trigger:
      - platform: event
        event_type: "imap_content"
        event_data:
          sender: "[email protected]"
        id: "custom_event"
      - platform: template
        id: timeout
        value_template: >
          {{ now() - states.sensor.dominos.last_changed >= timedelta(minutes=5) }}
    sensor:
      - name: Dominos
        state: > 
          {% if trigger.id == 'custom_event' and 
          trigger.event.data['text'] | base64_decode | lower is search('sorting your order') %}
            order
          {% elif trigger.id == 'timeout' %}
            no_order
          {% endif %}

Thank you, much appreciated.

So when you say YAML configuration is removed, it means i can’t use the imap_email_content platform as a sensor anymore? But template.yaml configuration is ok? Is that not also YAML configured ? Or can i now configure this via the gui ?

I guess it all still works unofficially as i had no errors on the configuration part yet but will be removed at some point?

Some questions:

  1. How can i add multiple senders like i could with the old imap_content_email configuration?
  2. Interested in the binary_sensor as well, would you have an example of that ?

Thank you again.
atv

As with many other integrations that were formerly YAML-only, the IMAP has been transitioned over the past few months to GUI. YAML Configuration of the IMAP integration was removed in 2023.4 any sensors you had configured prior to that should have been transitioned automatically.

New IMAP sensors can be added via the Integrations page in Settings. New content sensors should be configured as trigger-based template sensors or binary sensors.

It is specifically the IMAP integration I commented on, not all YAML.

Currently (2023.5) you should receive a Repair notification on restart if you add a content sensor to your YAML configuration. The Repair may give you the option of adding a template sensor that contains a generated template based on the YAML content sensor configuration.

There are at least two ways (I don’t know enough about the inner workings of Event triggers to know if one is significantly better than the other).

Option 1: Two triggers
template:
  - trigger:
      - platform: event
        event_type: "imap_content"
        event_data:
          sender: "[email protected]"
      - platform: event
        event_type: "imap_content"
        event_data:
          sender: "[email protected]"
....
Option 2: Filter with Templates
...
    sensor:
      - name: Mail from Sender1 or Sender2
        state: > 
          {% set current = this.state | default('no mail', 1) %}
          {% if trigger.event.data['sender'] in ['[email protected]', '[email protected]'] %}
            {{ trigger.event.data['subject'] }}
          {% else %}
            {{ current }}
          {% endif %}
        attributes:
          Message: "{{ trigger.event.data['text'] }}"
          Server: "{{ trigger.event.data['server'] }}"
          Sender: "{{ trigger.event.data['sender'] }}"
template:
  - trigger:
      - platform: event
        event_type: "imap_content"
        event_data:
          sender: [email protected]
    binary_sensor:
      - name: Dominos
        auto_off: "00:05:00"
        state: > 
          {% set current = this.state|default('off', 1) %}
          {% if trigger.event.data['text'] | base64_decode | lower is search('sorting your order') %}
            on
          {% else %}
            {{ current }}
          {% endif %}

Many thanks, super helpful.

I was thinking rather then setting multiple triggers, would there be a way to process all emails coming from a single domain? I currently have the problem that i get many emails from school for example, all with their own email address. Could i do something like :

sender: *@school.com

Or could i not add multiple sender fields to one trigger?

Also, i’m guessing the difference between a content sensor and a IMAP sensor is that email just gets email, whereas a content sensor acts upon the content inside?

As I understand, this is part of what has changed. In the past the basic IMAP sensor and content sensors were configured separately and functioned separately. Currently, the IMAP sensors’ configurations (specifically the Search field) you create in the UI limit the emails that come into HA and are responsible for firing all imap_content events which can be picked up by the trigger-based template sensors.

I don’t think the event trigger configuration allows for setting a wildcard like that, but there are ways to do it.

Option 1: Filter within the template
{% if trigger.event.data['sender'] is search('@school.com') %}
Option 2: Configure a specific IMAP Sensor

The search criteria of your IMAP sensor can be set to only include specific domains (example: UnSeen UnDeleted FROM "@school.com"). Like sender, search can be used to limit the event trigger listener:

template:
  - trigger:
      - platform: event
        event_type: "imap_content"
        event_data:
          search: UnSeen UnDeleted FROM "@school.com"

Interesting. So with option 2, i’m guessing the sender and search are mutually exclusive? As in one or the other?

I haven’t tested it for this use, but you should be able to use multiple criteria from the Event data for a more specific template sensor.

1 Like

I’m thinking it won’t make sense to have a sender and a search to filter on domain but i guess there might be use cases for it.

I’ll test around with it and post if it works.

Many many thanks for your help.

Agreed. Maybe if you wanted to set a special sensor just for emails from your kid’s teacher you would just piggy-back off the school domain based IMAP…?

1 Like

Hi. What does this do??

auto_off: “00:05:00”

I have a subject that is very long. How to trigger if certain words is included??

Subject: I only want to trigger if THIS WORD is in subject

Is this valid??

        state: > 
          {% set current = this.state|default('off', 1) %}
          {% if trigger.event.data['subject'] is include
          "THIS WORD"
          %}
            on
          {% else %}
            {{ current }}
          {% endif %}

No. You want:

{% if "THIS WORD" in trigger.event.data['subject'] %}

The Template Editor is your friend:

It turns the trigger-based binary sensor off after the specified amount of time without requiring a second trigger.

template:
  - trigger:
      - platform: event
        event_type: "imap_content"
        event_data:
          search: UnSeen UnDeleted FROM "@school.com"

I dont think this method works… I’ve tried it over and over and can’t get the search to work under event_data. I’ve tried full email addresses wth FROM, and BODY searches. It works if I put it into the IMAP configuration of the integration, but then all the mails are searched by that single criteria and I have probably 12 different criteria I’m trying to search from one sender alone.

I haven’t retested it since the post in May, but it did work at that time.

Yes that is the method… notice that the description of that option in my earlier post is “Configure a specific IMAP Sensor”. In order to use the IMAP search as a means to sort incoming imap_content events you must configure multiple instances of the IMAP integration with their own IMAP search criteria.

Although it’s cumbersome since i have so many searches, it does work. I created multiple entries for the same mailbox in my imap integration and then seperate trigger/sensor groups for each one. It works great. I was trying to see if I could write a script to programatically generate the triggers and sensors using a template, but was unsuccessfull, but at least I have the functionality I was needing. I feel like there is some good opportunity to enhance the IMAP sensor to make it’s usability a lot more comprehensive. It’s such a great integration. Thank you!