How to use Google Calendars' event notification as a trigger and then reference the event in your Actions like you would if you directly referenced it?

The tester does not work with Template conditions… especially in this case since there is no trigger event to populate the trigger variable used by this template.

You will have to go to the Developer Tools > States tool and check the attributes of the last notification sensor immediately after a calendar notification is received.

1 Like

@Didgeridrew your code seems to run without any issue for some weeks.
I was wondering if there’s a way to extend the functionality even further to make it act like an actual calendar notification, meaning that when it’s tapped it opens the event from that notification in the calendar app

I don’t use Pushover, so you’ll need to do a bit of experimenting…

For the HA companion app and Android devices, I would add a click action with an Android intent, but Pushover only seems to allow opening a url. The intent url may work if all your target devices are Android. Try the following:

  - service: notify.pushover
    data:
      message: |-
       {{ trigger.to_state.state }}
       {{ trigger.to_state.attributes['android.title'] }}
      url: 'intent://www.google.com/calendar/event#Intent;scheme=https;package=com.google.android.calendar;end'

If any of your targets are iOS, your best option is probably to just add the public url of the calendar.

hm upon changing the action to the version you presented the Pushover notifications for this Automation don’t fire anymore at all
And I’m pretty sure I added the code correctly this time

  action:
  - service: notify.pushover
    data:
      message: |-
       {{ trigger.to_state.state }}
       {{ trigger.to_state.attributes['android.title'] }}
      url: 'intent://www.google.com/calendar/event#Intent;scheme=https;package=com.google.android.calendar;end'

Considering one of my devices has iOS I tried just adding the URL in this simpified action:

  action:
  - service: notify.pushover
    data:
      message: |-
      test
      url: 'https://calendar.google.com/calendar/u/0?cid=YXJzNGw0bjEyM0BnbWFpbC5jb20'

but even that threw an error:
“Error running action
Error rendering data template: Result is not a Dictionary”

I also tried the variant that was in the Pushover documentation:

  action:
  - service: notify.pushover
    data:
      message: test
      data:
        url: https://calendar.google.com/calendar/u/0?cid=YXJzNGw0bjEyM0BnbWFpbC5jb20

which on iOS upon tapping the notification only causes the pushbullet app to open with the link there for me to tap again to open google calendar. I was hoping for the page to pop up from just tapping the notification though, just like how the actual calendar app would behave. Additionally, it opens the Google Calendar Website thereby clogging my tabs, not the Google Calendar App.

Lastly, I tried this variant:

service: notify.pushover
data:
  title: Kalender
  message: |-
    {{ trigger.to_state.state }}
    {{ trigger.to_state.attributes['android.title'] }}
  data:
    url: 'intent://www.google.com/calendar/event#Intent;scheme=https;package=com.google.android.calendar;end'

but my iOS device wasn’t able to open the link.

I didn’t find comprehensive documentation, nor actual package names, just some vague userposts so I also tried google calendar://calendar.google.com/calendar/u/0?cid=YXJzNGw0bjEyM0BnbWFpbC5jb20 and google_calendar://calendar.google.com/calendar/u/0?cid=YXJzNGw0bjEyM0BnbWFpbC5jb20 for the last line with no success

any further suggestions?

iOS stuff is outside my wheelhouse… have you looked into setting up a Siri Shortcut to launch the Calendar. You can fire Shortcuts via HA service call with additional data, so that might be an avenue to explore.

no, I’ll try it out
hm, seems like an app can’t be launched via siri shortcuts if they’re not listed there
I’d have to contact the developer about it or so

@Didgeridrew
I’ve been noticing a issue recently which I can’t exactly pinpoint because it doesn’t occur consistently
I think it’s probably something in my Galaxy S6s’ tasker configuration (because upon disabling all Profiles the issue disappeared) but everything is set up correctly so it must be a bug

The issue is that sometimes the Pushover notification just gets immediately canceled

Do you have any suggestions or know a way to set this calendar up which is less prone to bugs?

Update: I just quit using the Galaxy S6 and used a Pixel 3 + Galaxy S7 and iPhone 12 mini instead and the issue went away.

I noticed a new issue with @Didgeridrew 's automation: When I set two Calendar notifications at the same time only one of them triggers the automation. So, the other one isn’t mirrored.
It’s not even in Home Assistant’s History page.

The issue occurs on my Galaxy S7 and Pixel 3.

Make sure the automation mode is set to queued or parallel.

that didn’t do anything and I would’ve been surprised if it did since it’s not the automation not firing but actually the value not being reported by the HA Companion App.

@Didgeridrew
I actually found the reason for this happening and a workaround.
So, on Github, a guy working on HA says this seems to happen because the notifications are so close to one another that by the time we are able to send the data over to HA the database was already updated.

He suggests to use the Active Notification Count sensor as a workaround as that contains the notification title as an attribute.
So, I tried redoing the automation with that sensor, but I got stuck because for this sensor the attributes are different in that each notification has an individual number on the left side of the colon
chrome_2024-07-02_21-35-19

and I don’t know how to make templates for that. Would you help me out with that?

I tried a few things, and the closest thing I could get using that sensor is:

alias: Mobile - Calendar Notifications
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.YOURDEVICE_active_notification_count
    not_to:
      - unknown
      - unavailable
    not_from:
      - unknown
      - unavailable
condition:
  - condition: template
    value_template: "{{ trigger.to_state.state|int > trigger.from_state.state|int }}"
  - condition: template
    value_template: |
      {{ trigger.to_state.attributes|select('match','android.title_com.google.android.calendar_')|list|count > 0}}
action:
  - repeat:
      for_each: |
        {%- set ns = namespace(messages=[]) %} 
        {% for y in trigger.to_state.attributes |
        select('match','android.title_com.google.android.calendar_') %}
          {% set ns.messages = ns.messages + [(trigger.to_state.attributes).get(y)] %}
        {% endfor %}
        {{ ns.messages }}
      sequence:
        - service: notify.NOTIFIER
          metadata: {}
          data:
            message: "{{ repeat.item }}"   
mode: queued

FWIW, I found this method to be pretty unreliable in terms of timing. If you don’t have fast updates turned on, it seems almost random. However, I don’t use Google Calendar notifications the way you have described in previous post, so I may have been doing something incorrectly.

I also found that if you have two event notifications at the same time there doesn’t seem to be an easy way to get a notification for each one received… which is why I ended up splitting them and running them through a repeat in the automation above.

Thanks a lot for your effort.

Any idea why I get the error Automation is unavailable Actions: invalid template (TemplateSyntaxError: unexpected '}') for dictionary value @ data[0]['repeat']['for_each'] at the top of the automation’s page? I just copy-pasted your code with the name of my sensor in the trigger.

There was a typo at the end of the set statement… it should end with the %} delimiter not }}.
I have fixed it in the post above.

1 Like

I have fast updates enabled and get the notifications instantaneously, so far, but I’ve gotten 4 notifications for the same calendar event, minutes apart. This occured after 1 day of usage.

Look at the automation Traces and see if there’s anything you can use to discriminate between a desired notification and an undesired notification. Keep in mind that there may not be anything that will work, you may have reached the limits of what is possible while relying on the notifications.

Look at the automation Traces and see if there’s anything you can use to discriminate between a desired notification and an undesired notification

I wasn’t able to discriminate between those things, but I noticed that whenever the recurring Tasker “Running Tasks” notification appears the automation fires unintendedly.

Any idea how to prevent that?

In the Active Notification Count State Attributes it’s listed as eg.:
android.title_net.dinglisch.android.taskerm_2087247171: Running Tasks

By the way, I noticed another issue when using this automation: I sometimes get random double/triple notifications for events that have their notification set to one day prior.
For example, I got a notification for the 6 AM event 24h prior, as expected and then, out of the blue: another one at 00:02 AM and another one at 01:53 AM.
No idea how to troubleshoot this. Here are the Changed Variables of the triggers for the unexpected notifications though, in case that helps:

00:02 AM:

this:
  entity_id: automation.new_automation_3
  state: 'on'
  attributes:
    id: '1694887254940'
    last_triggered: '2024-07-30T19:50:04.885692+00:00'
    mode: queued
    current: 0
    max: 10
    friendly_name: Google Kalender Benachrichtigungen per Pushover spiegeln
  last_changed: '2024-07-26T15:29:13.348870+00:00'
  last_reported: '2024-07-30T19:50:05.326102+00:00'
  last_updated: '2024-07-30T19:50:05.326102+00:00'
  context:
    id: 01J42K2NAM16HSE7EPMA020NAG
    parent_id: 01J42K2NAK3E4AYX4CKV7N4A5D
    user_id: null
trigger:
  id: '0'
  idx: '0'
  alias: null
  platform: state
  entity_id: sensor.galaxy_s7_last_notification
  from_state:
    entity_id: sensor.galaxy_s7_last_notification
    state: ‎<U+202A>21:50–22:30 Uhr<U+202C>‎
    attributes:
      android.appInfo: ApplicationInfo{3e253a3 com.google.android.calendar}
      android.bigText: ‎<U+202A>21:50–22:30 Uhr<U+202C>‎
      android.icon: 2131231197
      android.infoText: 'null'
      android.largeIcon: 'null'
      android.progress: 0
      android.progressIndeterminate: false
      android.progressMax: 0
      android.remoteInputHistory: 'null'
      android.showChronometer: false
      android.showWhen: false
      android.subText: 'null'
      android.support.v4.app.extra.COMPAT_TEMPLATE: androidx.core.app.NotificationCompat$BigTextStyle
      android.template: android.app.Notification$BigTextStyle
      android.text: ‎<U+202A>21:50–22:30 Uhr<U+202C>‎
      android.title: ‎<U+202A>geh ins Bett mit Handy<U+202C>‎
      android.wearable.EXTENSIONS: >-
        {dismissalId=com.google.android.calendar|V2AEventKey|112888443644576480457|[email protected]|1tgh5eogi7ip7tp41nnh2esk2b_20240730T195000Z|1203290657|1722369000000|1,
        [email protected]¦com.google¦event}
      category: event
      channel_id: REMINDERS
      group_id: 'null'
      is_clearable: true
      is_ongoing: false
      package: com.google.android.calendar
      post_time: 1722369002777
      icon: mdi:bell-ring
      friendly_name: Galaxy S7 Last notification
    last_changed: '2024-07-30T19:50:04.883873+00:00'
    last_reported: '2024-07-30T19:50:04.883873+00:00'
    last_updated: '2024-07-30T19:50:04.883873+00:00'
    context:
      id: 01J42K2NAK3E4AYX4CKV7N4A5D
      parent_id: null
      user_id: null
  to_state:
    entity_id: sensor.galaxy_s7_last_notification
    state: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
    attributes:
      android.appInfo: ApplicationInfo{67b3879 com.google.android.calendar}
      android.bigText: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
      android.icon: 2131231197
      android.infoText: 'null'
      android.largeIcon: 'null'
      android.progress: 0
      android.progressIndeterminate: false
      android.progressMax: 0
      android.remoteInputHistory: 'null'
      android.showChronometer: false
      android.showWhen: false
      android.subText: 'null'
      android.support.v4.app.extra.COMPAT_TEMPLATE: androidx.core.app.NotificationCompat$BigTextStyle
      android.template: android.app.Notification$BigTextStyle
      android.text: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
      android.title: ‎<U+202A>Gelber Sack<U+202C>‎
      android.wearable.EXTENSIONS: >-
        {dismissalId=com.google.android.calendar|V2AEventKey|112888443644576480457|[email protected]|ej90q4gc31mjgdb0uschrjpdis_20240731T040000Z|-1912318519|1722312000000|1,
        [email protected]¦com.google¦event}
      category: event
      channel_id: REMINDERS
      group_id: 'null'
      is_clearable: true
      is_ongoing: false
      package: com.google.android.calendar
      post_time: 1722376922270
      icon: mdi:bell-ring
      friendly_name: Galaxy S7 Last notification
    last_changed: '2024-07-30T22:02:04.873662+00:00'
    last_reported: '2024-07-30T22:02:04.873662+00:00'
    last_updated: '2024-07-30T22:02:04.873662+00:00'
    context:
      id: 01J42TMBP958X2N0WS1GEMXKT7
      parent_id: null
      user_id: null
  for: null
  attribute: null
  description: state of sensor.galaxy_s7_last_notification

01:53:

this:
  entity_id: automation.new_automation_3
  state: 'on'
  attributes:
    id: '1694887254940'
    last_triggered: '2024-07-30T22:02:04.875284+00:00'
    mode: queued
    current: 0
    max: 10
    friendly_name: Google Kalender Benachrichtigungen per Pushover spiegeln
  last_changed: '2024-07-26T15:29:13.348870+00:00'
  last_reported: '2024-07-30T22:02:08.081640+00:00'
  last_updated: '2024-07-30T22:02:08.081640+00:00'
  context:
    id: 01J42TMBPA9XVPG2KY8TA6C19P
    parent_id: 01J42TMBP958X2N0WS1GEMXKT7
    user_id: null
trigger:
  id: '0'
  idx: '0'
  alias: null
  platform: state
  entity_id: sensor.galaxy_s7_last_notification
  from_state:
    entity_id: sensor.galaxy_s7_last_notification
    state: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
    attributes:
      android.appInfo: ApplicationInfo{67b3879 com.google.android.calendar}
      android.bigText: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
      android.icon: 2131231197
      android.infoText: 'null'
      android.largeIcon: 'null'
      android.progress: 0
      android.progressIndeterminate: false
      android.progressMax: 0
      android.remoteInputHistory: 'null'
      android.showChronometer: false
      android.showWhen: false
      android.subText: 'null'
      android.support.v4.app.extra.COMPAT_TEMPLATE: androidx.core.app.NotificationCompat$BigTextStyle
      android.template: android.app.Notification$BigTextStyle
      android.text: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
      android.title: ‎<U+202A>Gelber Sack<U+202C>‎
      android.wearable.EXTENSIONS: >-
        {dismissalId=com.google.android.calendar|V2AEventKey|112888443644576480457|[email protected]|ej90q4gc31mjgdb0uschrjpdis_20240731T040000Z|-1912318519|1722312000000|1,
        [email protected]¦com.google¦event}
      category: event
      channel_id: REMINDERS
      group_id: 'null'
      is_clearable: true
      is_ongoing: false
      package: com.google.android.calendar
      post_time: 1722376922270
      icon: mdi:bell-ring
      friendly_name: Galaxy S7 Last notification
    last_changed: '2024-07-30T22:02:04.873662+00:00'
    last_reported: '2024-07-30T22:02:04.873662+00:00'
    last_updated: '2024-07-30T22:02:04.873662+00:00'
    context:
      id: 01J42TMBP958X2N0WS1GEMXKT7
      parent_id: null
      user_id: null
  to_state:
    entity_id: sensor.galaxy_s7_last_notification
    state: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
    attributes:
      android.appInfo: ApplicationInfo{86c342a com.google.android.calendar}
      android.bigText: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
      android.icon: 2131231199
      android.infoText: 'null'
      android.largeIcon: 'null'
      android.progress: 0
      android.progressIndeterminate: false
      android.progressMax: 0
      android.remoteInputHistory: 'null'
      android.showChronometer: false
      android.showWhen: false
      android.subText: 'null'
      android.support.v4.app.extra.COMPAT_TEMPLATE: androidx.core.app.NotificationCompat$BigTextStyle
      android.template: android.app.Notification$BigTextStyle
      android.text: ‎<U+202A>06:00–07:00 Uhr<U+202C>‎
      android.title: ‎<U+202A>Gelber Sack<U+202C>‎
      android.wearable.EXTENSIONS: >-
        {dismissalId=com.google.android.calendar|V2AEventKey|112888443644576480457|[email protected]|ej90q4gc31mjgdb0uschrjpdis_20240731T040000Z|-1912318519|1722312000000|1,
        [email protected]¦com.google¦event}
      category: event
      channel_id: REMINDERS
      group_id: 'null'
      is_clearable: true
      is_ongoing: false
      package: com.google.android.calendar
      post_time: 1722383579579
      icon: mdi:bell-ring
      friendly_name: Galaxy S7 Last notification
    last_changed: '2024-07-30T22:02:04.873662+00:00'
    last_reported: '2024-07-30T23:53:02.596559+00:00'
    last_updated: '2024-07-30T23:53:02.596559+00:00'
    context:
      id: 01J430ZHC4TWTEX2RMNNKPYEWG
      parent_id: null
      user_id: null
  for: null
  attribute: null
  description: state of sensor.galaxy_s7_last_notification

Are you clearing notifications in a timely manner? If the notifications aren’t cleared they will still be available to be sent again when you get a new notification of any kind. That is one of the reasons I said that I found the method unreliable… you can try filtering out attributes that were part of the previous state object:

Filtered Attributes Example
alias: Mobile - Calendar Notifications
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.YOUR_DEVICE_active_notification_count
    from: null
    variables:
      new_attr_list: >
        {% set from_attr = trigger.from_state.attributes %} {% set from_keys =
        from_attr.keys() | list %} {% set ns = namespace( attr=[]) %} {%- for
        k,v in (trigger.to_state.attributes).items() if k not in from_keys  and
        k is match('android.*.google.android.calendar_') %}
          {% set ns.attr = ns.attr + [(k,v)] %}
        {%- endfor %}{{ (ns.attr) }}
      new_attr: "{{ dict.from_keys(new_attr_list) if new_attr_list != [] else none }}"
condition:
  - alias: Reject if new state is less than old
    condition: template
    value_template: "{{ trigger.to_state.state|int > trigger.from_state.state|int }}"
  - alias: Allow only if New is from Calendar
    condition: template
    value_template: "{{ false if new_attr is none else new_attr.keys()|count > 0 }}"
action:
  - repeat:
      for_each: >
        {%- set ns = namespace(messages=[]) %}  {%- for y in new_attr |
        select('match','android.title_com.google.android.calendar_') %}
          {% set ns.messages = ns.messages + [(trigger.to_state.attributes).get(y)] %}
        {%- endfor %} {{ ns.messages }}
      sequence:
        - service: notify.pushover
          metadata: {}
          data:
            message: "{{ repeat.item }}"
        - delay: 1
mode: queued

But there are still a number of ways that this method could produce false-positive notifications or fail to send true notifications. Surely there is a less convoluted, less error prone, or more controllable method than going from Google Calendar push notifications > your phone > Home Assistant > Pushover.

Google Calendar can send email notifications just as easily as it can send push notifications. Pushover seems to have a method to accept email messages and distribute them. Or if you really want HA to be part of it… have you tried using email notifications and an IMAP sensor like I asked about 9 months ago?