Kestra webhooks and Home assistant
Welcome to another blog post on Kestra. Starting from where I left off last time, I'm going to try to fix a few little niggles I had with the time based triggers.
What if I want to watch something on plex after 1am but before 5am? How can I stop the job without doing much?
Webhooks
This is obviously where webhooks come in. Kestra has native support for webhooks, so this is actually quite straightforward. My home automation software, Home Assistant, also supports webhooks too. For this to work, I already have an automation which triggers when plex is started on my TV in home assistant. I won't be including that automation, but I will include all the relevent bits.
So, working backwards, I set up Kestra to recieve the webhook and based on the body of the request start the relevent job. The webhook flow looked like this:
id: webTrigger
namespace: ansible
description: Start tasks on a webhook
labels:
env: prod
project: trigger-wrapper
tasks:
- id: checkBody
type: io.kestra.plugin.core.flow.If
description: Trigger Condition based on body
condition: "{{ trigger.body.mode == 'stopped' }}"
then:
- id: call_start_unpackerr
type: io.kestra.plugin.core.flow.Subflow
namespace: ansible
flowId: start_unpackarr
wait: true
transmitFailed: false
else:
- id: call_stop_unpackerr
type: io.kestra.plugin.core.flow.Subflow
namespace: ansible
flowId: stop_unpackarr
wait: true
transmitFailed: false
triggers:
- id: wbTrigger
type: io.kestra.plugin.core.trigger.Webhook
description: Plex webhook
key: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
If you need to debug this trigger, adding a task of
- id: returnData
type: io.kestra.plugin.core.debug.Return
format: "v1: {{ trigger.body }}"
At the start can be a big help.
So what does this flow do?
Well it sets up the trigger (id of wbTrigger) with a key of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - This is not actually my key and you would want something random and unique here. The output from this command may help you, if you get stuck:
tr -dc A-Za-z0-9 </dev/urandom | head -c 32; echo
The tasks run my start or stop flows based on the body of the webhook. In this case, a variable called 'mode'. This is sent in JSON from Home assistant. Once set up, give it a quick go to verify everything is working. Once happy, lets look at the home assistant side of things.
Home Assistant!
Setting up rest commands requires access to the under lying files. You can break your config this way, so be careful. To minimise the chances of that, I use a separate file for my rest commands, which also allows my to reload them indepentently of home assistant.
So, first off, create a file in file editor called rest_commands.yaml. You want to give the following content:
kestra_stop_unpackerr:
url: "http://kestra.host:7080/api/v1/executions/webhook/ansible/webTrigger/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
method: put
content_type: "application/json"
payload: "{ \"mode\": \"playing\"}"
kestra_start_unpackerr:
url: "http://kestra.host:7080/api/v1/executions/webhook/ansible/webTrigger/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
method: put
content_type: "application/json"
payload: "{ \"mode\": \"stopped\" }"
The format of the url is:
http://<kestra host>:<kestra port>/api/v1/executions/webhook/<namespace>/<flowid>/<key>
NB, the flow id id the id of the entire flow, not the trigger's id.
Once set up, add this to your home assistant config file with the line
rest_command: !include rest_command.yaml
Reload home assistant and you should now be able to call the services "RESTful Command: kestra_start_unpackerr" and "RESTful Command: kestra_stop_unpackerr".
Give them a quick test, and you should see the container start and stop on command.
If you have any errors, the home assistant logs are very helpful, as are Kestras. Don't think about swpaping the escaped double quotes for single ones, Kestra doesn't accept that.
But now, you have an extensible way to start and stop your jobs via webhooks.