Particle.variable() use in a webhook post request?

Hi,

i can’t figure out how to use a particle.variable in a webhook.
The variable is stored from code to the cloud and can be read with CLI command.

Is it possible to use particle.variable() in a webhook ?
I need this since my bearer key is way above 255 but less than 622 chars long

here is the webhook:

{ 
"eventName": "event",
"url": "https://URL",
"requestType": "POST",
"headers": {
	"Content-Type": "application/json",
	"Authorization": "Bearer {{AccessToken}}",
	"Host": "HOST"
},
"form": {
	"description": "{{description}}",
},
"mydevices": true
}

And here is the code in build:

String AccessToken;

void setup() {
//  particle serial monitor
Serial.begin(115200);

Particle.variable("AccessToken", AccessToken);

// Lets listen for the hook response
Particle.subscribe("hook-response/webhook", gotData, MY_DEVICES);

// Lets give ourselves 10 seconds before we actually start the program.
// That will just give us a chance to open the serial monitor before the program sends the request
for(int i=0;i<10;i++) {
    Serial.println("waiting " + String(10-i) + " seconds before we publish");
    delay(1000);
}

// Let's request the weather, but no more than once every 60 seconds.
Serial.println("Requesting Access token!");

// publish the event that will trigger our Webhook
Particle.publish("webhook", NULL, 60, PRIVATE);
}

int functionXYZ(String xyz) {
Particle.publish("webhook", NULL, 60, PRIVATE);
}

void loop() {
}

// This function will get called when weather data comes in
void gotWeatherData(const char *name, const char *data) {

String str = String(data); 

AccessToken = tryExtractString(str, "access_token\":\"","\",\"token_type\"");

Serial.println("Received Bearer key: \"" + AccessToken + "\"");

Particle.publish("event", "{ \"description\": \"TESTING-LIKE-NEVER-BEFORE\" }", 60, PRIVATE);

}

I came up with a workaround that could maybe work…

Splitting the received access_token into max 255 byte “chunks” and then,
using 2 publish variable Calls in the json parameter like this:

...
"Authorization": "Bearer {{AccessTokenPart1}{AccessTokenPart2}}",
...

Is this possible, or is there a better way ?

Naah. That didn’t work… Since the whole custom data part of particle.publish is 255bytes… argh.

Is there any way to pass over 255 long stings to be used inside a webhook ?

optional data (up to 255 bytes)

looks like publish() is pretty clear on that.

What are you trying to do? If you are triggering a webhook to access a 3rd party API, the webhook contains the authorization information, not the call to the webhook.

@BulldogLowell
I have a webhook1 that has stored client_id and client_secret inside the webhook. Those are unchanged and can be stored in webhook (no problem).
But the response from webhook1 is a an accestoken string which length is approx 350 bytes.
The ~350byte accestoken is changing so that cannot be put inside the webhook, or it can be, but its to much work to maintain.

So what i’m trying to do is -> get the ~350 byte accesstoken into a webhook (which apparently is not supported (max 255bytes)).
I was in the hope of that the particle.variable() could be used to be “fed” into the webhook, but it apparently is not supported ?

Can you say, is it likely that particle.variable()'s could be read into a webhook in future ?
Or is it even possible to implement ? => it sounds it could be doable, but is it ?

Do i have any other workaround for this one ?

so you knock on the door of the server with client_id and client_secret. Server then provides access token.

It is returning the access token in a JSON object? You can and have successfully parsed that returned token into a buffer on your Photon?

Now you want another webhook to poll the server with the proper credentials including the access token?

Is that what you want to do?

Exactly @BulldogLowell

I need to make a webhook that is in the following format:

{ 
"eventName": "Event",
"url": "https://url.dot.com/path/action",
"requestType": "POST",
"headers": {
	"Content-Type": "application/json",
	"Authorization": "Bearer {{AccessToken}}", // NOTE, AccessToken ~350Bytes
	"Host": "url.dot.com"
},
"form": {
	"language": "En",
	"description": "{{description}}",
	"party": {
		"firstname": "Particle",
		"surname": "Photon",
		"email": "mail@host.com"
	}
},
"mydevices": true

}

And i want some data to be written also in the form: section of the request.
The amount of data to passed with particle.publish is although quite minimalistic but could work for now. But if i want to send images or other huge data -> i need to switch to the https-client library.

If you think i should switch to the https library even in this case where i need just small amount of data to passed in addition to the access_token, could you share an example based on my example below:

unsigned char httpRequestContent[] = “”;“POST %s HTTP/1.1\r\n”
“User-Agent: MatrixSSL/” MATRIXSSL_VERSION “\r\n”
“Authorization: Bearer “+AccessToken+”\r\n”
“Host: https://host.com/clientapi/v1/organization\r\n
“Content-Type: applcation/json\r\n”
“Content-Length: %d\r\n\r\n%s”;

The " + AccessToken +" doesn’t work (i tested it > wont build) and i dont know how to append the AccessToken into the request string since the https library was quite complex and with cloud ide its quite hard to find things in the library.

@BulldogLowell, Any suggestions how to handle over 255byte long access tokens ?
This would meen much to us if this would work since we want simple implementation of IoT without the need to change our existing implementation.

If it works with longer access tokens, we only need to write code and flash the particle photon and we would be “almost” done with the project :wink:

I like the idea of using a Particle.variable in the webhook, but why can’t you simply store the access_token in the hook?

Thanks!
David

AFAIGathered because it keeps changing frequently and permanently recreating the webhook just for a mutating token seems laborious.

Hmm, if the token is constantly changing, then we should look into support for generating it on the fly on the cloud. We do this for Azure tokens, and Google Cloud tokens, so it’s not unheard of.

But I’ll think about how we can use particle variables in hooks. :slight_smile:

Thanks!
David

2 Likes

That would be very nice @Dave !
That would allow people to make 10 times 622 bytes of “dynamic” data in a hook and that would be just great!
Or what ever was the amount of variables one device can interact in particle cloud… i think it was 10.

ps, i read somewhere that you shouldn’t rely on long lasting access tokens for the sake of security, but rather assume that they will “die” quite fast after receiving it and i think it sound logical.

But mean while waiting for possible solution to the variables in a web hook. Could you maybe help me out with the https-client library and pinpoint me where to look for if i want to create a similar POST request that is described in the hook earlier in this post. It would also do and be even better IF it allows me to send eg. images and other large data in the requests.

I mentioned that the request is gather in this code “snippet”

unsigned char httpRequestContent[] = "";"POST %s HTTP/1.1\r\n"
"User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
"Authorization: Bearer ..."\r\n"
"Host: https://host.com/clientapi/v1/organization\r\n"
"Content-Type: applcation/json\r\n"
"Content-Length: %d\r\n\r\n%s";

I’m not seeing how i can add the accestoken into this array ?
The AccesToken variable is a String in my case.
I tried also with

"Authorization: Bearer " AccessToken "\r\n"

But no go. Also tried to put some commas -> …Bearer ", AccessToken "\r\n"
This was alsi a no go…

we should look into support for generating it on the fly on the cloud. We do this for Azure tokens,

The long token i'm receiving is coming from Azure. What do you mean by -> "...we do this for Azure..."
Do you mean it's already supported at some level ?

Hi @pZq,

Yup! If you’re connecting to Azure, you can let Azure generate the signed tokens for you:

    "azure_sas_token": {
        "key_name": "YOUR_KEY_NAME",
        "key": "YOUR_PASSWORD"
    },

I still need to document some new parameters, so this probably wasn’t obvious, sorry!

Thanks,
David

1 Like

The azure sas seems to need some implementation in the software in order work so this is not the best solution. I hope you get something out from the particle.variable -> webhook integration. It would be super cool!

@Dave, btw. when do you think you will be investigating the variables into webhook issue ?


HTTPS client:
I tried and got something to work with the httpsclient-particle library, but i cannot get any reply from the server and i cannot even say, do i do it correctly when i add up the final POST request including the 350byte long access token. The library is not that trivial to underestand…

If some-one has an example eg. sending data to thingspeak or similar, i would be happy if you could share how to make the post request.

now i do it like this: (these chars are globally defined) (why the first char-array has %% before some variabes is described at bottom of post, but in short its since i’m adding the accesstoken before the httpsclientconnection() function is called)

unsigned char httpRequestContentTmp[] = "POST %%s HTTP/1.1\r\n"
"User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
"Authorization: Bearer %s\r\n"
"Host: https://host.dot.com/clientapi/v1/Scope/Application\r\n"
"Content-Type: applcation/json\r\n"
"Content-Length: %%d\r\n\r\n%%s";

unsigned char httpsMsgData[] = "{"
"language: \"EN\","
"description: \"Description\","
"party: {"
    "firstname: \"First\","
    "surname : \"Surname\","
    "email : \"mail@somehost.com\""
"}"
"}";

unsigned char * httpRequestContent;

Then in a separate function

String str = String(data); 

// Parse Bearer token string and create a string Bearer key:...
AccessToken = tryExtractString(str, "access_token\":\"","\",\"token_type\"");
Serial.println("Received Bearer key: \"" + AccessToken + "\"");

snprintf ((char *)httpRequestContent, sizeof(httpRequestContent), (char *)httpRequestContentTmp, AccessToken.c_str());

Serial.println("Http request: \r\n\"" + httpRequestContent + "\"");

client.connect(host, g_port);

// unsigned char * requestContent, uint32 msg_len, const char * message
httpsClientConnection(httpRequestContent, sizeof(httpsMsgData), httpsMsgData);
httpsclientCleanUp();
client.stop();

The println of https request prompts nothing so something in the snprintf goes wrong…
In the sprintf i’m trying to append data in between the original post message. First i use the %%[datatype] for others than AccessToken to which i use %s. After the snprintf() function i hoped to have the post request in its “original” format with %[datatype] and the AccessToken within the request.

To the HTTPS client library:

Now i get the content to my azure server. But still doesn’t work as expected. Response is “an internal error”…
The problem was, that the sizeof(msgcontent) made the server side to wait for one never received byte. I fixed it with: sizeof(msgcontent)-1

And now it works. I had a quite bad typo in the request :smile:

“Content-Type: applcation/json\r\n” => “Content-Type: application/json\r\n”

One “i” saved the day + some other small byte tweeks…

1 Like

Hi @Dave, i’m still curious about the variables to webhook implementation.
Have you had time to think about it ?

I still would need it since the httpsclient-particle library contains the fard fault bug that will restart photon when second connection to host is tried to establish.

@Dave, @ScruffR, @BulldogLowell

Is there any reason why the particle.publish() data can be only 255bytes.
could it be extended and if not, why ?

I want to understand. I tried to check into you code but couldn’t find any other reason than its just coded to allow const char *data

-Peter

Hi @pZq,

Just limits to keep things inside a single packet, not use too much ram / bandwidth / etc. I’d love to see that limit increased a bit as well. :slight_smile:

Thanks,
David