Webhooks - Defining the request body as json array?

I’m trying to use webhooks to post data to some IoT dashboards like initialstate and ubidots via json.

With InitialState, I need to post to their REST api using a json array. Ubidot doesn’t require this, but it would be great as that way I can post two different variables in one webhook definition (say temperature and humidity) which may become more important if I hit against the webhook limits.

InitialState: http://docs.initialstateeventsapi.apiary.io/#reference/event-data/events/send-events
Ubidot bulk: http://ubidots.com/docs/api/v1_6/collections/post_variables_id_values.html#post-api-v1-6-collections-variables-id-values

I can create a webhook with the json as an array, but it looks like the request going to the API is a pre-defined dictionary combined with user’s defined values (tempF and humidity in my case) based off tests against requestbin.

I’m surprised that requests to 3rd parties were constructed this way as it contains debugging info that most likely won’t be used by them. In any case, is there a way to make web-hooks work with my use-case?


##Attempt to defined webhook request as Json array

{
    "eventName": "tempF",
    "url": "http://https://groker.initialstate.com/api/events",
    "requestType": "POST",
    "json": [{
        "key": "{{SPARK_CORE_ID}}_tempF",
        "value": "{{tempF}}"
    },
    {
        "key": "{{SPARK_CORE_ID}}_humidity",
        "value": "{{humidity}}"
    }],
    "mydevices": true
}

Expected request body:

[
{
   "key": "My_ID_tempF",
   "value": 76
},
{
   "key": "My_ID_humidity",
   "value": 65
}
]

Actual request body (sanitized):

{"0":{"key":"MY_CORE_ID_tempF","value":"75"},"1":{"key":"MY_CORE_ID_humidity","value":"59"},"event":"tempF","data":"{ \"tempF\": \"75\", \"humidity\": \"59\", \"epoch\": \"-1787744360\" }","published_at":"2015-06-02T07:49:34.186Z","coreid":"MY_CORE_ID"}

Hi @dreamnid,

Looking at the Webhooks documentation, it seems that a custom body request is not supported.

I was actually thinking about something similar in order to make the Particle <> Ubidots integration as seamless as possible and deployed a new endpoint specifically for Particle. Would you like to test it? it works like this:

1- Create a Webhook

Make this HTTP request from a tool like Postman or Hurl.it. Following these tests, we would integrate this request into Ubidots, so you don’t have to use an external tool:

POST https://api.particle.io/v1/webhooks?access_token=YOUR-PARTICLE-TOKEN
Content-Type: application/json

{
    "event": "ubidots",
    "url": "http://translate.ubidots.com:9080/particle/?ubi_token=YOUR-UBIDOTS-TOKEN",
    "requestType": "POST"
}

2- Flash your device

This code will send two analog inputs (A0 and A1) to Ubidots, every 10 seconds. In the spark.publish function, specify the event name “ubidots”, and a JSON string in the format {“variable_name”: value, “variable_name”: value, “variable_name”: value, … “variable_name”: value, }.

#define publish_delay 10000

unsigned int lastPublish = 0;

void setup() {
    //Serial.begin(9600);
}

void loop() {
    unsigned long now = millis();
    int temp = analogRead(A0);
    int hum = analogRead(A1);

    if ((now - lastPublish) < publish_delay) {
        // it hasn't been 10 seconds yet...
        return;
    }

    Spark.publish("ubidots", "{\"temperature\":" + String(temp) + ", \"humidity\":"+ String(hum) + "}");
    
    lastPublish = now;
}

Once flashed, you should see the “Spark.publish” events coming in, and the Ubidots webhook replying {“status”:“OK”}

What’s cool about this is you won’t have to create datasources or variables in Ubidots; they will be automatically created using the “core_id” and “variable_name”'s. This is great for provisioning several devices automatically (every device can have the same firmware, but will appear as a different data source inside Ubidots).

Here’s how the data looks inside Ubidots:

Please note that the data source has a tag with the “core_id”; this is how we differentiate each Core, so be careful about not changing it. The data source name can be change without problems:

The variable names should match the ones in your code. If you change them, then a new variable will be created.

3 Likes

Hey @dreamnid sorry I didn’t find this message until now! I’m one of the founders of Initial State, and I’ve actually done this before!

The webhook api from particle doesn’t seem to handle json arrays like you’d expect, as you’ve found, so I made the api flexible to accept a single data point via just a root json object instead, example using your data:

{
    "eventName": "tempF",
    "url": "https://groker.initialstate.com/api/events",
    "requestType": "POST",
    "json": {
        "key": "{{SPARK_CORE_ID}}_tempF",
        "value": "{{tempF}}"
    },
    "mydevices": true
}

obviously, this is a little less ideal because you can’t send multiple values at once, but hopefully particle will support proper json arrays soon!

1 Like

Hey David
I appreciate your help here in the forum, and directly. I have been struggling trying to get particle.io webhooks to work with InitialState and I’m hoping the collective community might be able to help point out where my mistake is.

Here is my webhook.json

{
  "eventName": "voltsUpdate",
  "url": "https://groker.initialstate.com/api/events",
  "requestType": "POST",
  "headers": {
    "Content-Type": "application/json",
    "X-IS-AccessKey": "my access key here",
    "X-IS-BucketKey": "my bucket key here",
    "Accept-Version": "0.0.2"
  },
  "json": {
      "key":      "{{SPARK_CORE_ID}}_volts",
      "value":    "{{SPARK_EVENT_VALUE}}",
      "iso8601":  "{{SPARK_PUBLISHED_AT}}"
  },
    "mydevices": true,
  "deviceid": "my device id here",
  "noDefaults": true

}

The output from particle subscribe mine is:

{"name":"voltsUpdate","data":"1.381714","ttl":"60","published_at":"2015-09-22T03:52:55.260Z","coreid":"my core id"}
{"name":"hook-sent/voltsUpdate","data":"undefined","ttl":"60","published_at":"2015-09-22T03:52:55.272Z","coreid":"my core id"}

I changed the url to point to requestb.in and everything looked ok. The posted body was:

{"key":"mycoreid_volts","value":"1.420386","iso8601":"2015-09-22T04:00:55.232Z"}

Any thoughts or suggestions on where I should look next?

Thanks in advance.

Just to follow up on my own post, and hopefully this will help the next person. I finally did get the webhook above to communicate with InitialState. I embarrassingly had a typo in my access key so I was continually getting an unauthorized response.

I can confirm that the above webhook does work with the InitialState services.

Great, @TheYoungSoul your webhook looks identical to the one I used for myself as well. I’m glad you got it to work and I appreciate you posting here! Please let me know if you have any other issues!

Cheers

I was not able to use the ubidots webhook and publish method provided here. The dashboard would say “Sleeping …too many errors”. Unfortunatly the dashboard does not give much information on the error :frowning:

hi @tiagonmas there’s a new Particle-Ubidots library in the community libraries section in the Particle IDE. You may want to check it out:

Thanks @aguspg.
Tried the new library but nothing shows up in Ubidots. How can I debug this ?

I noticed I was using the API Key and not the Token.
As suggested in another thread, I tried http://things.ubidots.com/api/v1.6/variables/?token= and it was giving the same “Authentication credentials were not provided”. That’s how I noticed the token was wrong. if you are using the correct token, you will see a list of your variables.

Still, using the correct Token, I was not able to see anything posted to Ubidots when using the library :frowning:

 ubidots.sendUbidots( 1, "VisualPulses",photoCount);

I was able to send using a webhook for one variable, but not with a webook with many variables as your example states. When using a webhook with many variables I get the error

Spark.Publish("ubidots2", "{PhotoPulses:" + String(photoCount) + "}");

Error shown in dashboard:

{"value":["'{PhotoPulses:20}' value must be a float."]}

hey @tiagonmas i will help you with you issue, give me some minutes.
The Ubidots library have a debugger and it need that you connect USB with the particle photon, and open a serial port. Could you show me your serial port with a screenshot please?