[webhook] New, very simple binding for listening incomming http requests

I haven’t used the SSE tester yet.
Can you trigger that light item by browser?
What does the log say when you try to trigger the item by browser?

I can switch the light via the ui, no problem. And i see the state-change both in the sse-stream and the events.log

Using http://10.0.0.75:8080/webhook/CMD?myItem2=OFF in my browser just gives me a blank page

I previously used the example-code many posts above and there was no response too. Am i missing something? Do i have to install something else?

If your browser stays blank that is normal. Does your item AKU_Schaltaktor_… switches from OFF to ON if you send now the ON command?

Is your item connected to another thing-channel or just the webhook one?

The item (light) is linked to the the KNX-channel (group-address).

I can change the state of the light over the KNX-channel. The webhook does neither work on ON or OFF

Not sure if you can override a state when linked to KNX…
Just for testing purpose: could you create a seperate test item? Let’s try to get an easy and simple scenario which works and then you could step up and add more complexity.

Ok. Here is the problem:
Your thing ID is not “CMD” but e89a315de7.
The URL for your http request is:
http://10.0.0.75:8080/webhook/e89a315de7?myItem2=OFF

Ohh! How stupid! I misinterpret “CMD” as a command-call :smiley:
Yes, now this works! Kind of!
The item is switched on and off, but the light does not switch.

But thats ok! Switching ligths was not my goal, i have to use a rule anyway. For now i am switching a dummy-item and use a rule to switch the light :smiley:

If your item is linked to knx binding, maybe this binding does not allow to change the state of that channel item. Is this item of type contact or switch? Did you set it to read-only?
Do you see anything in the log, e.g. that knx resets the value of the item after you have changed it via webhook?

i think there is a difference: the switch in the ui sends a command, the webhook just switches a state:


2024-01-26 08:21:50.898 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'AKU_Schaltaktor_16fach_Licht_Loft_Ambiente_TV' received command OFF
2024-01-26 08:21:50.898 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'AKU_Schaltaktor_16fach_Licht_Loft_Ambiente_TV' predicted to become OFF
2024-01-26 08:21:50.899 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AKU_Schaltaktor_16fach_Licht_Loft_Ambiente_TV' changed from ON to OFF
2024-01-26 08:22:05.940 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'AKU_Schaltaktor_16fach_Licht_Loft_Ambiente_TV' received command ON
2024-01-26 08:22:05.940 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'AKU_Schaltaktor_16fach_Licht_Loft_Ambiente_TV' predicted to become ON
2024-01-26 08:22:05.940 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AKU_Schaltaktor_16fach_Licht_Loft_Ambiente_TV' changed from OFF to ON
2024-01-26 08:22:13.958 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AKU_Schaltaktor_16fach_Licht_Loft_Ambiente_TV' changed from ON to OFF

First tree lines were OFF from UI, followed by three lines ON by UI. Last line is OFF from webhook

Yes, you need to route it through a rule.
You could ping the developer . He might add to send a command to an item

Maybe a follow profile would help in you case - Items | openHAB

Thats totally fine for me!
Thank you!

Also, for rules you don’t really need an item channel. You may use a trigger channel as well - it is offered as well in this binding.

Good evening, one question about this binding, would the generated web hooks also be accessible via myopenhab.org, or only in the local OH instance?

Edit: already found the answer in the thread, seems like the web hooks are only available locally.

Actually it is possible - see [webhook] New, very simple binding for listening incomming http requests - #13 by Piotr_Bojko

Great, thanks, I’ll give that a try!

Hi, I have now been playing with the binding a bit and it works great, thanks @Piotr_Bojko for the work on it.

One question: I am trying to create a Webhook thing, that passes on all the parameter and body content to a Javascript for further processing. Goal is to have the thing generic and then be able to react in the Javascript to different requests, and also have the processing thread-safe (avoid that a new request already overwrites some channels while still processing an old request).

As first attempt I tried to pass on only the parameters, using the following code for a trigger channel:

  - id: trigger
    channelTypeUID: webhook:trigger-channel
    label: Trigger
    description: Trigger indicating a call.
    configuration:
      expression: return req.parameters;

When triggering a JavaScript from this channel, then event.event contains a string {name=[huhu],command=[ON]}, which are the two GET parameters I passed in. Does anyone know what format that is and how I could parse it in JavaScript? I tried JSON.parse, but that returns an error.

I also tried to create a JEXL array that contains both parameters and the body, using return [req.parameters, req.body]. The resulting JavaScript event.event is then of type string with value “[Ljava.lang.Object;@5e88b877”. Does anyone have an idea if this seemingly Java object turned JavaScript string can be used?

Any other idea how I could pass the complete parameters and body to a Javascript via a trigger channel?

I implemented a small proof-of-concept now, which allows me to pass multiple parameters via a JSON string from the JEXL to the trigger channel. Unfortunately I was not able to write generic JEXL code but have to write a separate statement for every parameter I want to pass on.

UID: webhook:Webhook:xxxxxxxxxx
label: Webhook
thingTypeUID: webhook:Webhook
configuration:
  expression: resp.status=200
channels:
  - id: lastCall
    channelTypeUID: webhook:lastCall-channel
    label: Last request
    description: Timestamp of the last request to the webhook.
    configuration: {}
  - id: trigger
    channelTypeUID: webhook:trigger-channel
    label: Trigger
    description: Trigger fires when the webhook is called.
    configuration:
      expression: >-
        {
          var json="{"; 
          if( ! empty( req.parameters.action ) )
          {
            json+="\"action\":\"" + req.parameters.action[0] + "\""; 
            if( ! empty( req.parameters.itemName ) ) { json+=",\"itemName\":\"" + req.parameters.itemName[0] + "\"" }; 
            if( ! empty( req.parameters.command ) )  { json+=",\"command\":\""  + req.parameters.command[0] +  "\"" }; 
          }
          return json + "}";
        }

The JavaScript that processes it implements two actions, “sendCommand” and “toggle”:

var input = JSON.parse( event.event );

var action = "action";
var itemName = "itemName";
var command = "command";

if( input[action] == "sendCommand" )
  {
    if( input[itemName] && input[command] ) items.getItem( input[itemName] ).sendCommand( input[command] )
    else console.warn( "Webhook: sendCommand was called but itemName or command was missing (" + itemName + "='" + input[itemName] + "', " + command + "='" + input[command] + "')." );
  }
else if( input[action] == "toggle" )
  {
    if( input[itemName] )
      {
        var item = items.getItem( input[itemName] );
        var state = item.state;
        
        if( state == "ON" ) item.sendCommand( "OFF" )
        else if( state == "OFF" ) item.sendCommand( "ON" )
        else console.warn( "Webhook: toggle was called for " + itemName + "='" + input[itemName] + "', but state was '" + state + "'." );
      }
    else console.warn( "Webhook: toggle was called but itemName was missing (" + itemName + "='" + input[itemName] + "')." );
  }
else
  console.warn( "Webhook: action is empty or invalid (" + action + "='" + input[action] + "')." );

I’d love to improve the JEXL code to make it generic. But I was not able to iterate over the req.parameters (for( item : req.parameters ) returns JEXL error : context is readonly), but even if that would work I don’t know how to access the parameter name AND value. Any ideas?

Next I am going to try to get it to work via myopenhab.org. :slight_smile:

Edit: myopenhab.org worked for me as well. I did not have to work via a session cookie, but used basic authentication with myopenhab.org username and password directly in the request.

The URL in my case is:

https://home.myopenhab.org/webhook/xxxxxxxxxx?action=toggle&itemName=xxx

But actually I realized in my case I d not need to go via myopenhab.org. I want to use this to control openHAB from my Garmin watch, and the Garmin watch goes via the phone, and on the phone I have Tailscale VPN connected to the local openHAB server.

event.payload

returns a json string. In your case

{"event":"ON","channel":"webhook:Webhook:xxxxx:huhu"}

Thanks, but I think using event.event is easier than extracting the data from another JSON, isn’t it? What I’d like to optimize is how I generate the JSON I am passing in the event data from the JEXL in the Webhook thing configuration.