cURL Command Conundrum | Run Manually as a Script but Also Capture POST Response Values

Hello there!

I’ve been scratching my head all week around this one so I thought I’d reach out to you guys!

I’m attempting to knock up a script which interacts with UniFi Protect API in order to toggle a certain feature called ‘Share Livestream’. As this feature isn’t available through the UniFi integration (raised a Feature Request and has been denied), the only other method is via an API call/command.

There isn’t any documentation around the ‘proper’ API method of doing this so I’ve captured the required commands via the Web UI (using Firefox/Chrome Inspect).

There are two parts (commands) to using this feature over API …

Login/Authentication

Firstly a POST command is sent in the form of a ‘Login/Authenication’ in order to capture two critical tokens needed to run any further commands. The two tokens are ‘Bearer’ (Cookie) and ‘X-CSRF’. These values need to be stored in HA in order to be referenced later in the second part of the command so I’ve had to use a ‘Sensor Command Line’ entity to do this. Trying to capture both of these in one command was difficult so I’ve had to split it into two …

The ‘Bearer’ (Cookie) token/value is present within the body of the POST response (value under ‘deviceToken’) and captured using a ‘value_template’ of ‘{{ value_json.deviceToken }}’

platform: command_line
name: Unifi Protect Auth Token
scan_interval: 21600 
unique_id: db5660a6-2f3e-11ee-be56-0242ac120002
command: curl -k -v -X POST 'https://192.168.10.1/api/auth/login' -H 'Content-Type:application/json' -d '{"username":"UniAPI","password":"iReAdYoUrEmAiLs"}' 
value_template: >
  {{ value_json.deviceToken }}

The second token, ‘X-CSRF’, was a bit more difficult as this value is stored in the ‘Header’ response and not in the body unlike the ‘Bearer’. I used the ‘-s’ option along with ‘grep x-csrf-token’ within the cURL command in order to display the ‘X-CSRF’ value.

platform: command_line
name: Unifi Protect XCRSF Token
scan_interval: 21600 
unique_id: db5660a6-2f3e-2222-be56-0242ac120002
command: curl -k -s -i POST 'https://192.168.10.1/api/auth/login' -H 'Content-Type:application/json' -d '{"username":"UniAPI","password":"iReAdYoUrEmAiLs"}' | grep x-csrf-token
value_template: "{{ value|replace('x-csrf-token: ', '') }}"

Example of output

Although these commands are currently working, my main concern is that I’ve had to use a ‘Sensor Command Line’ entity in order to capture and store the required values which will trigger/replay the command either on startup/first boot of HA or within an allocated time frame (hence the ‘scan_interval’ value of 21600 - 6 hours). In an ideal scenario I want to run these manually.

Enable/Disable Feature (and also capture ‘URL’ value)

Once the ‘login’ details have been captured (two tokens) the next and main command is to toggle the ‘Share Livestream’ feature.

Enable

When the ‘Share Livestream’ feature is enabled, it essentially generates a random URL (provided/hosted by UniFi) which allows you to share and provide access to the camera feed externally without any authentication/local access. This value is shown/provided within the POST response of the command. Similar to the two token commands above, I’ve used a ‘Sensor Command Line’ entity in order to send the ‘Enable’ request and also capture the generated URL.

platform: command_line
name: Unifi Protect Enable Livestream
scan_interval: 21600 
unique_id: db5660a6-2f3e-11ee-3333-0242rrr20002
command: curl -k -L -X POST 'https://192.168.10.1/proxy/protect/api/cameras/{{ states.input_select.unifi_camera_ids }}/sharedStream' -H 'Content-Type:application/json' -d -H 'X-CSRF-Token:{{ states.sensor.abcunifi_protect_xcrsf_token }}' -H 'Authorization:{{ states.sensor.unifi_protect_auth_token }}'
value_template: >
  {{ value_json.shareLink }}

The issue again is with this needing to be setup as a ‘Sensor Command Line’ which will like the previous commands, will trigger/fire on startup/first boot of HA or within an allocated time frame and needs to be ran manually/on command.

Disable

I won’t go too much into this part as it’s the easier command with a simply DELETE request being sent including the two ‘Login/Auth’ tokens.

And finally to the issue/problem I’m trying to solve …

Can anyone recommend how I can setup these commands as scripts, still using the POST requests yet somehow capture and store the necessary values?

Apologies!

Yeh I’m going to try and see what I can do … My Python isn’t that great!