Creating grafana annotations with bearer by sendHttpPostRequest not possible

Hi,

i want to use a rule for creating annotations with bearer token.

first i tried this via shell which works:

curl -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -H "Content-Type: application/json" -X POST \-d '{"tags":["test"],"text":"your description"}' http://192.168.2.244:3000/api/annotations

im using actually oh 4.1.1. and want to do the same by rule without using exec.
so i tried to do same via javascript rule with sendHttpPostRequest but then i had problems:

var headers={"Authorization": "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Content-Type": "application/json"};

var  url = "http://192.168.2.244:3000/api/annotations"
var content = '{"tags":["test"],"text":"your description"}'
var HTTP=Java.type("org.openhab.core.model.script.actions.HTTP");
var result=HTTP.sendHttpPostRequest(url,"application/json", content,headers)

console.log(result);

can anyone help me to get out my problem how to use HTTP.sendHttpPostRequest successfully for this?

actually it tells:

2024-01-14 14:16:09.760 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '51c0f0ece4' failed: org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (sendHttpPostRequest) on org.openhab.core.model.script.actions.HTTP failed due to: no applicable overload found (overloads: [Method[public static java.lang.String org.openhab.core.model.script.actions.HTTP.sendHttpPostRequest(java.lang.String,java.lang.String,java.lang.String,java.util.Map,int)], Method[public static java.lang.String org.openhab.core.model.script.actions.HTTP.sendHttpPostRequest(java.lang.String,java.lang.String,java.lang.String,int)], Method[public static java.lang.String org.openhab.core.model.script.actions.HTTP.sendHttpPostRequest(java.lang.String,java.lang.String,java.lang.String)], Method[public static java.lang.String org.openhab.core.model.script.actions.HTTP.sendHttpPostRequest(java.lang.String,int)], Method[public static java.lang.String org.openhab.core.model.script.actions.HTTP.sendHttpPostRequest(java.lang.String)]], arguments: [http://192.168.2.244:3000/api/annotations (String), application/json (String), {"tags":["test"],"text":"your description"} (String), DynamicObject<JSOrdinary>@18281ef0 (DefaultLayout)])

I wrote a community post some time ago
I dont know if it still works like this but maybe you might be able to find something in there =)

Hi,
thank you very much - but i dont want to use dsl rules any more and want to use actual ecmascript. From my guessings i have a problem on the header-variable and im only a millimeter from getting it to work…

Actions like sendHttpPostRequest are implemented by openHAB so except in your they are accessed, using them is going to be the same across all rules languages.

It also shouldn’t be too challenging to translate from one language to another since the OH API remains the same. So the overall structure of errors and logic is going to be the same. The rest is just syntax differences. It’s closer to the difference between Spanish and Portuguese than Spanish and Mandarin.

Given this in Rules DSL (I’m ignoring the rule proforma stuff)

   logInfo("Rule triggered", "Rule \"test.rules: Testrule\" started")
    var String json =  '{
        "panelId":10,
        "dashboardId":' + DashboardID + ',
        "time":' + Long::toString(now.millis) + ',
        "tags":["Online"],
        "text":"Bettlampe offline"
    }'
    sendHttpPostRequest(url, "application/json", json)

It works be there following in ECMAScript 2022+.

console.info('Rule "test.rules: Testrule" started);
var JSON = '{
        "panelId":10,
        "dashboardId":' + DashboardID + ',
        "time":' + time.toZDT().toMillis()  + ',
        "tags":["Online"],
        "text":"Bettlampe offline"
    }';
actions.HTTP.sendHttpPostRequest(url, "application/json", json);

hi @rlkoshak ,
im agree with that what you’re writing.

Im meantime im a little bit further. Problem is not doing a postrequest. problem i have actually to use the parameters to add headers, which needed for authentification. This were not done by the rule which Felix had (he used old basic-auth) and so it is not transferable directly for me.
I can do posts without headers fin, but with them im getting the errors.
i also tried to add them also in the following way:

var headersMap = new java.util.HashMap();
headersMap.put("Authorization", "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

(and then using the variable headersMap in postrequest. But no luck)
Documentation says:
sendHttpPostRequest(String url, String contentType, String content, Map<String, String> headers, int timeout)

The JS Scripting add-on does an OK job converting between JS entities and Java entities. Did you try to build a JS map/dict for the headers?

var headers = { 'Authorization': 'Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'};

If that doesn’t work (in pretty sure it will in this case) you’ll need to import Java Hashmap using Java.type.

var Hashmap = Java.type('java.util.Hashmap');

Then you can create and populate it in the normal Java way.

yes, i did this but had no luck with that that was originally the first post

…this does not work and im getting “TypeError: Access to host class java.util.Hashmap is not allowed or does not exist.”

and my second variant i had:

var headersMap = new java.util.HashMap();
headersMap.put("Authorization", "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
var result=HTTP.sendHttpPostRequest(url,"application/json", content,headersMap);

also no luck. as soon as im using the fourth parameter in which usage i ever tried it did not work. And the problem is that old basic-auth as Felix it used 2 years ago is not usable for me. But the headers inclusive the bearer are valid for doing the request as i also confirmed in first post with the there written curl-request. So from my pint of view the way i gave the map-object seems to cause the problem or the way it is implemented in org.openhab.core.model.script.actions.HTTP , that i cannot say actually. Actually im hoping that someone can give me a hint on a problem of my code…

But you used Java.type to import HTTP instead of using what’s already available to you through actions.HTTP. I’m not sure the add-on is able to do the conversions when you bypass the library like that.

var headers={"Authorization": "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Content-Type": "application/json"};

var  url = "http://192.168.2.244:3000/api/annotations"
var content = '{"tags":["test"],"text":"your description"}'
var result=actions.HTTP.sendHttpPostRequest(url,"application/json", content,headers)

Typo, should be HashMap.

But did you have the Java.type? Nothing from Java is available to you unless you import it using Java.type. You have to import it before you can instantiate an instance of it using new.

Also, I don’t see you passing a timeout argument to the function call. The docs do not indicate that the timeout is optional when passing headers.

One also wonders if the HTTP binding wouldn’t be more appropriate for this in the first place.

It should either be the following which uses pure ECMAScript only:

var headers={"Authorization": "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Content-Type": "application/json"};

var  url = "http://192.168.2.244:3000/api/annotations"
var content = '{"tags":["test"],"text":"your description"}'
var result=actions.HTTP.sendHttpPostRequest(url,"application/json", content,headers, 5000)

or the following which imports and uses HashMap:

var HashMap = Java.type('java.util.HashMap');
var headers=new HashMap();
headers.put("Authorization", "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
headers.put("Content-Type", "application/json");

var  url = "http://192.168.2.244:3000/api/annotations";
var content = '{"tags":["test"],"text":"your description"}';
var result=actions.HTTP.sendHttpPostRequest(url,"application/json", content,headers, 5000);

As far as I can tell, you’ve tried other combinations but neither of these.

1 Like

Hi @rlkoshak

this works fine, thank you for your hint!
ok, the way “actions.HTTP.sendHttpPostRequest” i did not tried was my “error1” and as i also tried your code without the timeout-parameter it is also not working. So this was my “error2”
On every Thread im hearing from you i can learn a lot. Thank you!