Webhooks not passing all the payload details

I’m having a webhook be sent to my webcore instance. The webhook is getting there, but I can’t do much with it because it appears to be blank. When I have it log the args they are blank or just contain a (:).

Anyone else used webhooks? Looking to get notifications when remote playing happens.

no???

Hi,

to access the data in your webcore piston use the following. This does not decode all the payload, but most of the useful parts.
There is an issue with the media.play request, as it sends a multipart message with a jpeg, webcore can not handle this and fails. I’m working on a solution which I will document on the webcore forum. It uses an interim node.js app on a rasp pi

image

So you are saying I can’t use media.play? I just want to get a notification when someone starts playing on the server. I don’t care when they pause or do anything else. What is the next step in webcore to do this?

I don’t think so, although I’m surprised you get the “:” response from a play command. I found the piston didn’t even start.

The problem with media.play is that it sends a multipart message which webcore can not handle. I’ve written a node.js script running on the rasp pi. You point the web hook at it, and change the pi script to call your piston. It seems to work, although I#m still tweaking it. There are more details in this thread. Could you also consider voting for the enhancement request, so the node.js code is not required.

I voted for it. Also I setup your node.js. The sbc received the text however I got a }
statusCode: 500
{“error”:true,“type”:“org.codehaus.groovy.grails.web.converters.exceptions.ConverterException”,“message”:“An unexpected error occurred.”}

I must say, you are everywhere. I googled the error code and found this.

Looks like my data is too long.

This is my latest version, it includes quite a lot of commented out work in progress.

The error 500 can be caused by an extended ascii code, which I remove. Are there any errors returned by the node.js code? I suspect something copy/pasted badly.

//var utfstr = require(‘utf8’);
var http = require(‘http’);
var https = require(‘https’);

http.createServer(function(req, res){
main(req,res);
}).listen(1111);

function main(req, res){
let data = ;
req.on(‘data’, (chunk) => {
data.push(chunk);
});

req.on('end', () => {
    data = Buffer.concat(data).toString();
    // at this point, `data` has the entire request body stored in it as a string
   console.log(' ');
   console.log(' ');
   console.log('Processing request');
   console.log(data);
   header = data.substr(26,43);
   header = "--------------------";
   data = data.substr(data.indexOf("name="));
   data = data.substring(50,data.indexOf(header));
   var data2 = '{"payload":' + data + '}';

// console.log(data2);
var jsondata2 = JSON.parse(data2);
// remove unwanted JSON items
// delete jsondata2.payload.Metadata[‘Role’];
// delete jsondata2.payload.Metadata[‘Similar’];
// delete jsondata2.payload.Metadata[‘Location’];
// delete jsondata2.payload.Metadata[‘summary’];
data2 = JSON.stringify(jsondata2);
data2 = data2.replace(/[^\x20-\x7E]/g, ‘’); // Remove non printable chars
//data2 = utfstr.encode(data2);
console.log(‘tidied data’);
console.log(data2);
const options = {
hostname: ‘graph-eu01-euwest1.api.smartthings.com’,
path: ‘/api/token/******************:’,
method: ‘POST’,
headers: {
// ‘Content-Type’: ‘application/json; charset=utf-8’,
// ‘Content-Disposition’ : ‘form-data; name=payload’,
‘Content-Type’: ‘text/plain;charset=UTF-8’,
‘Content-Length’: data2.length
}
}
//make request
const req2 = https.request(options, res2 => {
console.log(statusCode: ${res2.statusCode})

    res2.on('data', d => {
        process.stdout.write(d)
        })
  })
   req2.on('error', error => {
       console.error(error)
   })
   req2.write(data2,'UTF-8')
   req2.end()
});
res.end();

}

That was my first assumption about the error 500. I later found it was the extended ascii chars in some of the data. I’m not aware of a data limit.

That copies really horribly. Any way to get it in one copy bubble?

I know, if you can suggest how, I’ll repost? I’m not sure why it comes out like that

click “preformated text” looks like </>

should work if you do it with the </>
//var utfstr = require('utf8');
var http = require('http');
var https = require('https');

http.createServer(function(req, res){
main(req,res);
}).listen(1111);

function main(req, res){
    let data = [];
    req.on('data', (chunk) => {
        data.push(chunk);
    });

   req.on('end', () => {
        data = Buffer.concat(data).toString();
        // at this point, `data` has the entire request body stored in it as a string
       console.log(' ');
       console.log(' ');
       console.log('Processing request');
       console.log(data);
       header = data.substr(26,43);
       header = "--------------------";
       data = data.substr(data.indexOf("name="));
       data = data.substring(50,data.indexOf(header));
       var data2 = '{"payload":' + data + '}';
//       console.log(data2);
       var jsondata2 = JSON.parse(data2);
       // remove unwanted JSON items
//       delete jsondata2.payload.Metadata['Role'];
//       delete jsondata2.payload.Metadata['Similar'];
//       delete jsondata2.payload.Metadata['Location'];
//       delete jsondata2.payload.Metadata['summary'];
       data2 = JSON.stringify(jsondata2);
       data2 = data2.replace(/[^\x20-\x7E]/g, ''); // Remove non printable chars
//data2 = utfstr.encode(data2);
       console.log('tidied data');
       console.log(data2);
       const options = {
           hostname: 'graph-eu01-euwest1.api.smartthings.com',
           path: '/api/token/*********:',
           method: 'POST',
           headers: {
//               'Content-Type': 'application/json; charset=utf-8',
//               'Content-Disposition' : 'form-data; name=payload',
               'Content-Type': 'text/plain;charset=UTF-8',
               'Content-Length': data2.length
               }
           }
        //make request
        const req2 = https.request(options, res2 => {
            console.log(`statusCode: ${res2.statusCode}`)

        res2.on('data', d => {
            process.stdout.write(d)
            })
      })

       req2.on('error', error => {
           console.error(error)
       })
       req2.write(data2,'UTF-8')
       req2.end()
    });
    res.end();
}

thanks! I still don’t seem to be getting media play though…the hunt continues.

spoke too soon, i uncommented these lines and I got a media.play

// delete jsondata2.payload.Metadata[‘Role’];
// delete jsondata2.payload.Metadata[‘Similar’];
// delete jsondata2.payload.Metadata[‘Location’];
// delete jsondata2.payload.Metadata[‘summary’];

Thats interesting, I’ve never had a problem with those lines included. I get the error 500 when any of the data contains an extended ascii > hex 127 char. without the line data2 = data2.replace(/[^\x20-\x7E]/g, ‘’); included. Do you still have this line in?

I’m wondering whether there is anything else in the content data Plex has sent, is your media meta data in english? Mine is english, with a few european accent chars (>hex 127) in ascii. If for example there was a Chinese description, I’m not sure if the metadata may contain UTF-8, which my script can not currently handle (I’m still working on this)
Perhaps by removing the JSON items (role,similar,location,summary) its working because a particular char is being removed, rather than changing the length.

It would be interesting to see the output from a failed call.

It’s working…most of the time. I’m noticing a few misses here or there. Hopefully plex just fixes the issue with the jpegs and this will be a moot point.

Can you confirm the problems you’re having, is it definitely data length or content?
What do you mean by misses? problems with different media files, or inconsistent with the same files? I’ve found the webhook does not seem to get fired consistently for play requests (all others seem ok) but cant see any pattern. Stopping & playing again the same file often works.

I think I’ve made progress with the extended ascii chars, see how this new (still in development) script works for you. I’d be interested to hear.

//var utfstr = require('utf8');
var http = require('http');
var https = require('https');
var request = require("request");

http.createServer(function(req, res){
main(req,res);
}).listen(1111);

function main(req, res){
    let data = [];
    req.on('data', (chunk) => {
        data.push(chunk);
    });

    req.on('end', () => {
        data = Buffer.concat(data).toString();
        // at this point, `data` has the entire request body stored in it as a string
       console.log(' ');
       console.log(' ');
       console.log('Processing request');
       console.log(data);
       header = "--------------------";
       data = data.substr(data.indexOf("name="));
       data = data.substring(50,data.indexOf(header));
       var data2 = '{"payload":' + data + '}';
       var jsondata2 = JSON.parse(data2);
       // remove unwanted JSON items
//       delete jsondata2.payload.Metadata['Role'];
//       delete jsondata2.payload.Metadata['Similar'];
//       delete jsondata2.payload.Metadata['Location'];
//       delete jsondata2.payload.Metadata['summary'];
       data2 = JSON.stringify(jsondata2);
//       data2 = data2.replace(/[^\x20-\x7E]/g, ''); // Remove non printable chars
//data2 = utfstr.encode(data2);
       console.log('tidied data');
       console.log(data2);
        //make request
request({
        url: 'https://graph-eu01-euwest1.api.smartthings.com/api/token/*********:',
        method: "POST",
        body: data2
    }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
            console.log(body)
        }
        else {
            console.log("error: " + error)
            console.log("response.statusCode: " + response.statusCode)
            console.log("response.statusText: " + response.statusText)
        }
    })

    });
    res.end();
}

Certain times the webhook doesn’t register. It typically gets every media.stop, however I will miss 3 out of 10 media. plays. It seems to work better with movies that have smaller amount of data coming in. For instance, Spider-Man Far From Home has 2 studios worth of credits on it. Where as a low budget movie has no problems.