Imap_content use TTS for trigger.event.data['text'] body part

I would like to use Alexa TTS to read out the first x of characters from the body of the email, or even better, between a start word and a end word.

Is there any way I can apply an operation on trigger.event.data[‘text’] to do this ? Or would I need to create a new sensor for it maybe?

I guess i could add another and | set email_tts = trigger.event.data[‘text’] and then call Alexa notify service ?

Appreciate any input on this!

  - trigger:
      - platform: event
        event_type: "imap_content"
    binary_sensor:
      - name: Smartlog_Confirmation
        auto_off: "00:05:00"
        state: |
         {% set email_test = trigger.event.data['sender'] is search('notifications@[email protected]') and 
         trigger.event.data['text'] | lower is search('Lucas|Incident') and
         trigger.event.data['date'] >= now() - timedelta(minutes=5) %} 
         {{ 'on' if email_test else 'off' }}  

You don’t need another sensor, you can trigger your automation directly off the event and use templates on any of the available variables.

Example Automation
alias: Notify - Alexa - New Email
description: ""
trigger:
  - platform: event
    event_type: imap_content
    event_data:
      initial: true
    variables:
      account: |-
        {% set user = trigger.event.data['username']|lower %}
        {% set a_list = {
        '[email protected]': "Drew's hotmail",
        '[email protected]': "Drew's Gmail",
        '[email protected]': "House Gmail"} %}
        {{ a_list.get(user) }}
      subject: "{{ trigger.event.data['subject'] }}"
      sender: "{{ trigger.event.data['sender']|lower }}"
      allow_list:
        - [email protected]
        - [email protected]
condition:
  - condition: template
    value_template: "{{ sender in allow_list }}"
  - condition: numeric_state
    entity_id: zone.home
    above: 0
  - condition: not
    conditions:
      - condition: state
        entity_id: person.a
        state: home
action:
  - service: notify.alexa_media_living_room_dot
    metadata: {}
    data:
      message: >
        New email in {{ account }} inbox <break time='150ms'/> from {{sender}}.
        {{['the subject is', 'its subject is', 'the title is', 'its title is'] | random }} <break time='50ms'/> 
        {{ subject }}.
mode: single

You could use the template from your example binary sensor either as a template condition either in the general condition block or in an If/Then or Choose action… it really depends on what you want.

You can use the regex_findall() to return something like that. If you need help with the regex query there are a few tools that others have shared elsewhere on the forum that I have found helpful:

  • AutoRegEx: AI regex helper. Like other AI resources, it can be hit or miss, but it seems less likely to “hallucinate” answers than less regimented outputs, so it’s usually worth trying. They don’t state explicitly but I think this is JS regex, which also limits it’s applicability in HA templates.
  • DebuggEx: More of a tester than a helper, can be set explicitly to Python regex.
1 Like

Cool. So for data I I guess I would have to add an extra string like :

text: "{{ trigger.event.data['text'] }}"

Under variables and then I can {{ text }} that to the Alexa ?

You don’t have to… but yes, you can set it up as a new entry under variables. Then you can use text in your TTS message filtered via Regex.

{{ text | regex_findall(find='(?<=Start Word).*?(?=\sEnd Word)', ignorecase=False)| first }}
1 Like

Many thanks, I’ll play around with this.

Sorry for digging this out, but: did that ever work for anyone? I’ve been doing quite some searching, and it seems that some can access trigger.event.data.text (or trigger.event.data['text']) just like that while others do a | base64_decode and others specify the length trigger.event.data['text'][0:20000] and none of the solutions work for me.

My automation is quite comparable to OP’s, and I can access subject, sender, username no problem but text is always empty, or tts.google_cloud_say at least seems to ignore it.

I feel like I’m missing something. :thinking:

Edit, my approach (with the variables, which I’ve added in a last ditch effort to get it working hehe):

alias: "[A] WiZ RGBW blink and Google TTS on mail (private)"
description: >-
  Blinks the desk lamp blue when a private email arrives.
trigger:
  - platform: event
    event_type: imap_content
    event_data:
      initial: true
    variables:
      subject: "{{ trigger.event.data['subject'] }}"
      text: "{{ trigger.event.data['text'] }}"
      sender: "{{ trigger.event.data['sender']|lower }}"
      username: "{{ trigger.event.data.username }}"
condition:
  - condition: template
    value_template: "{{ username == '[email protected]' }}"
action:
  - service: script.blink_wiz_rgbw_blue
  - service: tts.google_cloud_say
    data:
      entity_id: media_player.vlc_telnet
      message: >
        {% if trigger.event and trigger.event.data %}
          Neue private E-Mail von {{ sender }}:
          Betreff: {{ subject }}.
          Nachricht: {{ text }}
        {% else %}
          Neue private E-Mail erhalten, aber keine Details verfügbar.
        {% endif %}
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean.unread_mails_notice
mode: single

Edit2: I apologize if parts of that code don’t make much sense. I’m still somewhat new and still learning. And I really enjoy Home Assistant, it’s an incredible piece of software and quite a deep rabbit hole!

Yes

Are you sure the text is part of the event?

Since the original post, the body text is no longer included in the event by default. You need to either enable it in the IMAP integration or use the imap.fetch action to pull the data.

If you regularly receive emails where the body of the text is long enough to make the event over 32kB your only option is to disable the body text and use the fetch action.

One other possible issue is the script call. When you call a script directly, the automation will wait for the script to finish before continuing, and if the script errors the automation will stop. To avoid that either change the way you are running the script or be sure to specify continue_on_error: true in the automation.

1 Like

Thanks, that actually did the trick. I manually sent the imap.send action in the Developer tools, and in YAML mode, I saw the response_variable which made everything else quite obvious:

alias: "[A] WiZ RGBW blink and Google TTS on mail (private)"
description: >-
  Blinks the desk lamp blue when a private email arrives.
trigger:
  - platform: event
    event_type: imap_content
    event_data:
      initial: true
    variables:
      subject: "{{ trigger.event.data['subject'] }}"
      text: "{{ trigger.event.data['text'] }}"
      sender: "{{ trigger.event.data['sender']|lower }}"
      username: "{{ trigger.event.data.username }}"
      uid: "{{ trigger.event.data.uid }}"
      entry_id: "{{ trigger.event.data.entry_id }}"
condition:
  - condition: template
    value_template: "{{ trigger.event.data.username == '[email protected]' }}"
action:
  - service: script.blink_wiz_rgbw_blue
  - action: imap.fetch
    metadata: {}
    data:
      entry: "{{ entry_id }}"
      uid: "{{ uid }}"
    response_variable: fetched_data
  - service: tts.google_cloud_say
    data:
      entity_id: media_player.vlc_telnet
      message: >
        {% if fetched_data %}
          Neue private E-Mail von {{ sender }}:
          Betreff: {{ subject }}.
          Nachricht: {{ fetched_data['text'] | regex_replace('<[^>]*>', '') }}
        {% else %}
          Neue private E-Mail erhalten, aber keine Details verfügbar.
        {% endif %}
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean.unread_mails_notice

…and VLC received a file which was much longer than all my previous tries, and it indeed worked. Thanks, I’m so happy it’s working, now! :partying_face:

1 Like