Asking the phone a question usually means copying the same sequence into every automation: send a Companion notification, wait for mobile_app_notification_action, match the button, and decide what a timeout means. This pack is that sequence as one script. You configure the buttons once. Any automation calls the script, waits, and reads a response: which button, a timeout, or a dismiss.
Entity ids and notify targets are blueprint inputs. Do not publish which phone or which lock a button runs.
This is the question. Nagging repeatable alert is the loop that keeps pushing while a sensor stays wrong. Quiet-hours notification hub is the router for who hears a message and when. Call this script when the next step depends on the answer.
What problem it solves
You want “yes / no / later” on the lock screen, a deadline after which the house continues without an answer, and the answer handed back to the automation that asked — including a second question that is still waiting.
How it works
- One script, many callers — import the blueprint, create a script, pick the default phone and the default button titles. A caller can override the title, the message, the device, and the timeout for that run. Leave a button title empty and that button is omitted, so the same script can ask with one, two, or three buttons.
- Platform payload — Android and iOS do not use the same notification keys. The script builds the payload for the phone you targeted. Android options include the channel, importance, a persistent notification, and lock-screen visibility. iOS options include the interruption level and a destructive (red) button. Channel importance on Android is fixed the first time that channel name is used; a new channel name is how you change it.
- Its own tag — each run gets a tag and button ids that belong to that run. Two automations can be waiting at the same time, and a tap on one does not satisfy the other.
- Wait — if any button runs actions, or a timeout is set, the script waits for the Companion action event, for a swipe-away, or for the timeout. The timeout accepts seconds or a duration. On timeout it can clear the notification and run the timeout actions you configured.
- Reply — the script stops and returns
replyto the caller:button_1,button_2,button_3,timeout,dismissed, orsent.sentmeans the notification went out and this run was not waiting (no button actions and no timeout). The caller branches onreply. Button actions configured inside the blueprint still run for the tap itself. - Dismiss — a swipe-away is reported as
dismissedon Android. iOS does not deliver that swipe to Home Assistant.
A button whose only job is to open a link, on Android, opens the link and does not run that button’s actions and does not stop the timeout. That is how the Companion app treats link buttons.
Hardware notes
- Companion app. iOS or Android, logged into this Home Assistant. The phone has to be able to reach Home Assistant, or the tap never becomes an event.
- No extra devices. Locks, lights, and scripts you already have are what the caller runs after it reads
reply. They are inputs on the calling automation. - Home Assistant 2024.10 or newer. The script’s response variable is what makes the reply visible to the caller.
Snippet
The pack ships a script blueprint. The caller passes text and reads answer.reply:
actions:
- action: script.actionable_notification
data:
title: !input prompt_title
message: !input prompt_message
timeout: !input timeout_seconds
response_variable: answer
- choose:
- conditions:
- condition: template
value_template: "{{ answer.reply == 'button_1' }}"
sequence: !input confirm_actions
- conditions:
- condition: template
value_template: "{{ answer.reply == 'button_2' }}"
sequence: !input decline_actions
- conditions:
- condition: template
value_template: "{{ answer.reply == 'timeout' }}"
sequence: !input timeout_actions
Anything the caller omits falls back to the defaults set on the script. button_3 and dismissed are the same kind of branch when you configure a third button or you care about a swipe.
Setup outline
- Install the Companion app on the phone and confirm a normal notification arrives.
- Import the blueprint and create a script. Set the default device, two button titles (for example Confirm and Dismiss), and a default timeout.
- Write a one-off automation that calls the script with a test title and a one-minute timeout. Tap Confirm. In the automation trace,
answer.replyshould bebutton_1. - Run it again and wait out the timeout without tapping.
replyshould betimeout, and the notification should clear if you enabled that option. - Point a real automation at the same script. Keep the phone-specific defaults in the script; pass title, message, and timeout from the caller.
Troubleshooting
- Buttons do nothing. In Developer Tools → Events, listen for
mobile_app_notification_actionand tap a button. If no event arrives, the phone cannot reach Home Assistant. If the event arrives with a different action id, the script and the phone are on different tags — run a single test call and read its trace. - The caller always sees
sent. This run had no button actions and no timeout, so the script returned as soon as the notification was handed to Companion. Set a timeout or give a button an action. - Android opens a link and the script keeps waiting. That button is a link button. Links do not complete the wait. Use an action button when the tap should return
button_1. - Swipe does nothing on iOS. Dismiss detection is an Android event. Use a button, or the timeout, on iOS.
- Importance never changes. Android locked it to the first channel name. Set a new channel name in the script and send once so the phone creates the new channel.
- Two prompts answer each other. The calls share a tag. The pack’s per-run tag is what keeps them apart; an older hand-written notification that reuses one hard-coded tag will still collide with itself.
Credits
Based on the community blueprint Actionable mobile notification and gorlix/Gorlix-Home-Assistant-Blueprint. This write-up is an original caller-and-reply overview, not a paste of that blueprint.