Webhooks & Parse.com

Hello beautfiull Particle People :smile:

Iā€™m having a hard time making Webhooks work. After reading the documentation I have more questions then hawsers :slight_smile:

I want to create a object in my Parse database https://parse.com/docs/rest/guide#objects. The code bellow is the .json file that i have created.

{
  "event": "parse",
  "url": "https://api.parse.com/1/classes/History",
  "requestType": "POST",
  "auth": {
    "X-Parse-Application-Id": "XXX",
    "X-Parse-REST-API-Key": "XXX"
  },
  "headers": {
    "Content-Type": "application/json"
    },
  "json": {
    "accessorieID":"{{accessorieID}}",
    "user":"{{user}}"
  },
  "mydevices": true
}

The code on for the Core is as follow:

#define publish_delay 10000
unsigned int lastPublish = 0;

void setup() {

}

void loop() {
    unsigned long now = millis();

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

    Spark.publish("parse", "{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }", 60, PRIVATE);

    lastPublish = now;
}

When I do ā€œparticle subscribe mineā€ i get no errors from Parse.

{"name":"parse","data":"{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }","ttl":"60","published_at":"2015-07-05T17:30:18.111Z","coreid":"54ff6a066678574919370667"}
{"name":"parse","data":"{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }","ttl":"60","published_at":"2015-07-05T17:30:28.110Z","coreid":"54ff6a066678574919370667"}
{"name":"parse","data":"{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }","ttl":"60","published_at":"2015-07-05T17:30:38.128Z","coreid":"54ff6a066678574919370667"}
{"name":"parse","data":"{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }","ttl":"60","published_at":"2015-07-05T17:30:48.110Z","coreid":"54ff6a066678574919370667"}
{"name":"parse","data":"{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }","ttl":"60","published_at":"2015-07-05T17:30:58.114Z","coreid":"54ff6a066678574919370667"}
{"name":"parse","data":"{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }","ttl":"60","published_at":"2015-07-05T17:31:08.117Z","coreid":"54ff6a066678574919370667"}
{"name":"parse","data":"{ \"accessorieID\": \"tAUJDAEUXK\", \"user\": \"3wEtpxS126\" }","ttl":"60","published_at":"2015-07-05T17:31:18.112Z","coreid":"54ff6a066678574919370667"}

But nothing is being created in the Parse database. I tried a bunch of things but nothing seams to work.

I would be grateful is someone could check the code above and see what might be wrong.

Best.

1 Like

@davidgatti, I donā€™t see anything obvious except for the missing spaces after your ā€œ:ā€ in the json section. :wink:

That seams not to be the issue. Are you able to explain to me how is the son structure is being used?

"json": {
    "accessorieID":"{{accessorieID}}",
    "user":"{{user}}"
  },

Because in the Core code i just have one variable, a blob of data. Because i managed to work but not quite. I finally are able to make new rows, but there is no data saved in the columns. And right now my .json looks like this:

"json": {
    "test": "{{the-state}}"
  },

How is are the tags being used?

I think problem might be in authentication data format.
Read parse docs for more info, try to do requests with curl
And try to use this hook:

{
  "event": "parse",
  "url": "https://api.parse.com/1/classes/History",
  "requestType": "POST",
  "headers": {
    "X-Parse-Application-Id": "XXX",
    "X-Parse-REST-API-Key": "XXX",
    "Content-Type": "application/json"
    },
  "json": {
    "accessorieID":"{{accessorieID}}",
    "user":"{{user}}"
  },
  "mydevices": true
}

Sadly that is not the issue. I used Postman to make REST queries to Parse, and everything works fine. I found some bugs in the JSON itself, but fixed them and making direct REST request works.

I managed also to create rows in to Parse from Particle but without any data attached. I tried to write a name for a String type column. And I got a new row but the name was empty.

The .json looks like this now:

{
  "event": "parse",
  "url": "https://api.parse.com/1/classes/History",
  "requestType": "POST",
  "headers": {
    "X-Parse-Application-Id": "XXX",
    "X-Parse-REST-API-Key": "XXX",
    "Content-Type": "application/json"
  },
  "json": {
    "user" : {
      "__type" : "{{a}}",
      "className" : "{{a-a}}",
      "objectId" : "{{a-b}}"
    },
    "accessorieID" : {
      "__type" : "{{b}}",
      "className" : "{{b-a}}",
      "objectId" : "{{b-b}}"
    }
  },
  "mydevices": true
}

Firmware with the JSON is this:

Spark.publish("parse", "{ \"user\" : { \"__type\" : \"Pointer\", \"className\" : \"_User\", \"objectId\" : \"3wEtpxS126\" }, \"accessorieID\" : { \"__type\" : \"Pointer\", \"className\" : \"Accessories\", \"objectId\" : \"tAUJDAEUXK\" }}", 60, PRIVATE);

I spent two days on this and I have no idea what to do else. To me it seams that I donā€™t understand the .json and Iā€™m doing something wrong there.

FACTS

  • Doing direct REST calls works, which means there is no issue on Parse side
  • Authentication works, because if I try to save a string value I can create a empty row with no data.
  • If I put wrong credentials I get an error message from Parse, so the authentication process is correct.

I have no idea what to do more.

As I understand, particle makes simple substitution replacing {{key}} in you hook with "key":"value" from your Spark.publish. You should have simple dictionary without any hierarchy.
So you should rewrite it like this:

Spark.publish("parse", "{ \"a\" : \"Pointer\", \"a-a\" : \"_User\", \"a-b\" : \"3wEtpxS126\", \"b\" : \"Pointer\", \"b-a\" : \"Accessories\", \"b-b\" : \"tAUJDAEUXK\" }", 60, PRIVATE);

And use better names :blush:.
Also try to avoid dashes ('-') in names, prefer CamelCase or underscores.
Also remember that data field in Spark.publish is limited to 255 symbols.

1 Like

Check Core/Logs/Error and Core/Logs/Info on Parse.com

Sadly your solution doesnā€™t work. Same problem. I the request goes, no error but also no confirmation that the new object was created.

  • dashes are good as any char as far as i know
  • underscore is something that Pare enforces with on their own tables.

Core/Logs/Error and Core/Logs/Info are only for when you have a node app hosted on their servers

Hi @davidgatti

Since you have your host working with Postman, I would use http://requestb.in to debug what you are sending with the Webhook versus what you are sending with Postman. Usually it is pretty obvious what is wrong.

2 Likes

@bko not sure how that is different from Postman, but thee you go: http://requestb.in/ypjcc3yp?inspect.

I can create entries to Parse with Postman or strait CURL. The issue is that there is something wrong on the Particle side. My code or Particle code. Right now I what I do with straight CURL works, when I convert what works to Parse it stops working.

Hi @davidgatti

What I meant was to change the web hook to post to requestb.in so that you can see what you web hook is sending.

Is that what is in your bin? It looked like a postman request instead of a web hook request.

1 Like

@bko Oooā€¦ that how you use that :slight_smile: genius. OK, so the issue seams now really clear, this is Particle is sending out:

{"event":"parse","data":"{ \"a\" : \"Pointer\", \"a-a\" : \"_User\", \"a-b\" : \"3wEtpxS126\", \"b\" : \"Pointer\", \"b-a\" : \"Accessories\", \"b-b\" : \"tAUJDAEUXK\" }","published_at":"2015-07-06T02:25:55.823Z","coreid":"54ff6a066678574919370667","user":{"__type":"Pointer","className":"_User","objectId":"3wEtpxS126"},"accessorieID":{"__type":"Pointer","className":"Accessories","objectId":"tAUJDAEUXK"}} 

For some reason it appends the JSON from the firmware. While later actually structuring everything the right way. Iā€™m looking at my code and the tutorial and canā€™t see anything wrong.

Any ideas?

1 Like

Hi @davidgatti

Maybe @peekay123 or @Dave can help more.

The only thing I can imagine is that there is some magic that happens when you include a application-json header

@bko removing ā€œContent-Typeā€: ā€œapplication/jsonā€ hase not effect :frowning:

@davidgatti, I had an issue with the ā€œaddedā€ payload when I was posting a GET request on breezometer. The assumption was that the receiving server would ignore the added payload but that is not always the case. Perhaps @Dave can shed some light on this.

3 Likes

Hi @davidgatti,

I think the default behavior is to include everything, under the assumption that extra data will get ignored by the target website. It sounds like this isnā€™t the case here. Iā€™d love to make sure webhooks can send the kinds of requests you need. Is the issue here more that the wrong headers are being sent (app/json?), or that extra properties are being included (defaults from the published event)?

edit: If you want it to just not set the ā€œapplication/jsonā€ header, use the ā€œformā€ property instead of the ā€œjsonā€ property when creating up the webhook.

Thanks!
David

1 Like

Sadly Parse doesnā€™t have the track record to do everything the right way. And who knows if this is one of those things. I think it would be great if sending everything could be an opt in options.

But i general: what is the benefit of sending everything?

About the form: I will try it, but I have few questions:

  • authentication: do i keep the credentials (Application ID and Token) in the header?
  • JSON: do i keep the structure the same as i have it now?

@Dave, could a flag in the webhook definition be added to indicate whether the webhook should send the extra data or not?

1 Like

Hi @peekay123,

Totally! I think that makes sense, just trying to get a feel for how to present that, how it should work, etc. :slight_smile:

Thanks!
David

3 Likes

@Dave please do :slight_smile: I wooden mind for example:

  • raw: true/false

ps. could you answer my 2 last questions? :slight_smile:

2 Likes