Virtual button press - API


#1

I am trying to invoke a virtual button press via API and keep getting 403 error - Access is forbidden. I have the key value inputted that is from the trigger_id of the virtual button and have the Authorization as Bearer with my api access token.

Any idea …


#2

This works within the workflow itself just fine. Only via invoking the API gives that error. I have tried generating new api access token and using it as well with NO success


#3

Anyone to help me out ?


#4

Could you please paste in the information about the request you are making? Clicking on the button in the user interface actually calls the exact same API call that you are trying to make manually (you can actually look in your browser network tab and see the request), so the fact that clicking the button in the user interface works correctly for you but your manual call does not probably means there is some issue with how you are forming or making the request.


Virtual Button Press with API
#5

In postman the POST request is made as below

https://api.losant.com/applications//flows//virtualButton

headers set
content-type, accept as application/json
Authorization as Bearer … the long string ey…

in the body …

{
“key”: “trigger_id of the workflow”,
“payload”: {
“BedTempTarget” : 60,
“BedTempActual” : 60.1,
“ToolTempTarget” : 210,
“ToolTempActual” : 210.1
}
}


#6

That looks like the correct form of request.

I double checked when our api would return a 403 - that error code is returned when either no authorization token is provided, or the authorization token does not have the proper scope. It sounds like you are creating an Application API Token to use for this call - what kind of scope(s) are are you creating the token with?


#7

I am not sure what you are asking about scope?

when I created the application, I also created the access keys and the application api token and that is the one I use in the Authorization parameter. I have used that way in many other applications successfully.


#8

I mean the permissions for the token. Is it a full access token? A readonly token? A token with custom permissions?


#9

I have set All permissions


#10

And to confirm, this is how you are setting up your Postman request?


#11

Yes, that is correct
Authorization Bearer …
Content-Type


#12

Are you able to make any other requests with the token you have? For instance, if you just make a GET request against https://api.losant.com/applications/YOUR_APP_ID/flows/YOUR_FLOW_ID, does that work?


#13

NO … none of the api works


#14

If you paste your auth token in the encoded box here: https://jwt.io/ does it successfully decode? and if so, what does it decode to?

I just did a double check - the only reasons the API would return a 403 would be if you were not sending the auth token with the request (or if the header was typo-ed) or if the token did not have proper permissions. Any other authentication errors would be a 401 response code.


#15

Looks like an invalid …


#16

The token is valid - you don’t have the required information to validate the signature :slight_smile: (you need a secret to validate the signature).

I went ahead and transcribed your token from the screenshot, and made the request myself, and it was successful. So there is nothing wrong with that token (although you should probably delete it and generate a new one, since you posted it here). Are you sure you have everything configured and spelled right in Postman? Is the checkbox next to the Authorization header checked, so postman will actually send it?

The following is how the request would look using curl, I also tested your token with curl for your application, workflow, and trigger, and it works as expected:

curl -X POST \
  https://api.losant.com/applications/YOUR_APP_ID/flows/YOUR_FLOW_ID/virtualButton \
  -H 'authorization: Bearer YOUR_AUTH_TOKEN' \
  -H 'content-type: application/json' \
  -d '{ "key": "YOUR_VIRTUAL_BUTTON_TRIGGER_ID", "payload": {} }'

#17

I deleted the token and regenerated a new one. It worked … cannot figure why it did not work before. But, when I try using the code below, it triggers the workflow, returns success, however it does not update the device state.

Within the workflow manually triggering, device state gets set. but bot via api.

workflow is very simple like below with just two nodes …

virtual button linked to device state

Application log does not get the data from the api made


#18

I have tried calling the virtual button press api via XMLHttpRequest with proper credentials and data payload with the key. It returns status of 200 and responseText as Success, but does not set the device state as in the workflow


#19

The API will return a 200 Success response regardless of if we were able to find a virtual button given the “key” you’re providing in that workflow. Can you paste the full request body, including the actual key and not a placeholder? The key is not considered sensitive information since you deleted that application token you put here earlier.


#20

here is the code snippet for a button press call I make using XMLHttpRequest to invoke the Virtual Button press.

<script>
function PrinterWorkflow(bTarget, bActual, tTarget, tActual)
{
	var urlwrkflow = "https://api.losant.com/applications/5b7895c3e8e3fa0007ca7759/flows/5b79fe8a1a83b0000773232d/virtualButton";
	var data1 = {};
	data1.key = "55b79fe8a1a83b0000773232d-fxtzMDVGWy~2_Ytaz7ECa";
	data1.payload = {};
	data1.payload.BedTempTarget = bTarget;
	data1.payload.BedTempActual = bActual;
	data1.payload.ToolTempTarget = tTarget;
	data1.payload.ToolTempActual = tActual;

	var wrkFlowData = JSON.stringify(data1); alert(wrkFlowData);

	var xhrwf = new XMLHttpRequest();
	xhrwf.open("POST", urlwrkflow, false);
	xhrwf.setRequestHeader ('Authorization', 'Bearer ....'); // catual token is placed there as Bearer ...
	xhrwf.setRequestHeader('Content-Type','application/json; charset=utf-8');
	xhrwf.setRequestHeader('Accept','application/json');
	xhrwf.onload = function () {
		if (xhrwf.readyState == 4 && xhrwf.status == "200") {
				alert("success");
		} else {
		//console.error(xhrwf.responseText);
		}
	}
	xhrwf.send(wrkFlowData);
}
</script>

I have removed the access token info purposely for this info