PUBSUB BITS: Malformed JSON Response

Hello there.

I’ve been retrieving bits information from the pubsub for a while now, and until now I had no problems in dealing with the malformed JSON response.
But now that subscriptions have been introduced to the pubsub I have a hard time dealing with the responses.

Let me give an example.
This is the code I currently have which deals with bits:

psSocket.onmessage = function(data) {
                    data = JSON.parse(data.data.replace(/\\/g, '').replace('","message":"{"data"', '","message":{"data"').replace('"}"}}', '"}}}'));
                    switch(data.type) {
                        case "RESPONSE": {
                            if(debug_bits)
                                consoleLog('BITS SOCKET RESPONSE:'), consoleLog(data);
                        } break;
                        case "MESSAGE": {
                            consoleLog(data);
                            switch(data.data.topic) {
                                case 'channel-bits-events-v1.' + window.channel_id: {
                                    if(debug_bits)
                                        consoleLog('BITS SOCKET RETRIEVE: x' + data.data.message.data.bits_used + ' FROM ' + data.data.message.data.user_name + ' WITH MESSAGE: \'' + data.data.message.data.chat_message + '\'');
                                } break;
                                case 'channel-subscribe-events-v1.' + window.channel_id: {
                                    if(debug_subscribers)
                                        consoleLog('SUBSCRIBER SOCKET RETRIEVE: x' + data.data.message.months + ' FROM ' + data.data.message.user_name + ' WITH MESSAGE: \'' + data.data.message.sub_message.message + '\'');  
                                 } break;
                            }
                        } break;
                    }
                };

And this is the usual response you get when someone send bits:

{"type":"MESSAGE","data":{"topic":"channel-bitsevents.XXXXX","message":"{\"user_name\":\"TestUsername12345\",\"channel_name\":\"TestChannel12345\",\"user_id\":\"TestUserID12345\",\"channel_id\":\"TestChannelID12345\",\"time\":\"2017-06-3T12:00:00.000Z\",\"chat_message\":\"cheer1 Test message.\",\"bits_used\":1,\"total_bits_used\":1,\"context\":\"cheer\"}"}}

The problem I’m speaking of is the fact that I have to use this:
JSON.parse(data.data.replace(/\\/g, '').replace('","message":"{"data"', '","message":{"data"').replace('"}"}}', '"}}}'));
to avoid JSON.parse giving away this error:
jQuery.Deferred exception: Unexpected token u in JSON at position 74 SyntaxError: Unexpected token u in JSON at position 74

Until now I was able to avoid that problem by using:
.replace('","message":"{"data"', '","message":{"data"').replace('"}"}}', '"}}}'));
But now, since subscriptions have been introduced to the pubsub, and they are PROPERLY formatted, I have no way of interpreting a malformed message one way, and a properly formatted message another way.

I would like to kindly ask for the bits response messages to be formatted properly, because JSON.parse throws an error as soon as I try to parse the whole response.

It’s not malformed. data.data.message is a JSON string itself.

psSocket.onmessage = function (data) {
    data = JSON.parse(data);
    switch (data.type) {
        case "MESSAGE":
            var message = JSON.parse(data.data.message);
            console.log(message);
    }
}

You replied with a “solution”, but you haven’t even tested it on the response!
If I try your approach with this RESPONSE, I get that ERROR!
{"type":"MESSAGE","data":{"topic":"channel-bitsevents.XXXXX","message":"{\"user_name\":\"TestUsername12345\",\"channel_name\":\"TestChannel12345\",\"user_id\":\"TestUserID12345\",\"channel_id\":\"TestChannelID12345\",\"time\":\"2017-06-3T12:00:00.000Z\",\"chat_message\":\"cheer1 Test message.\",\"bits_used\":1,\"total_bits_used\":1,\"context\":\"cheer\"}"}}
Try doing JSON.parse on that response and see for yourself that IT throws an error.

Works fine.

This is what I’m trying just to see if it works, and I still get the error.

<script>
	data = '{"type":"MESSAGE","data":{"topic":"channel-bitsevents.XXXXX","message":"{\"user_name\":\"TestUsername12345\",\"channel_name\":\"TestChannel12345\",\"user_id\":\"TestUserID12345\",\"channel_id\":\"TestChannelID12345\",\"time\":\"2017-06-3T12:00:00.000Z\",\"chat_message\":\"cheer1 Test message.\",\"bits_used\":1,\"total_bits_used\":1,\"context\":\"cheer\"}"}} ';
	console.log(JSON.parse(data));
</script>

You’ll need to escape the backslashes \ when putting them inside a js string literal.

<script>
	data = '{"type":"MESSAGE","data":{"topic":"channel-bitsevents.XXXXX","message":"{\\"user_name\\":\\"TestUsername12345\\",\\"channel_name\\":\\"TestChannel12345\\",\\"user_id\\":\\"TestUserID12345\\",\\"channel_id\\":\\"TestChannelID12345\\",\\"time\\":\\"2017-06-3T12:00:00.000Z\\",\\"chat_message\\":\\"cheer1 Test message.\\",\\"bits_used\\":1,\\"total_bits_used\\":1,\\"context\\":\\"cheer\\"}"}} ';
	console.log(JSON.parse(data));
</script>

That works. I guess that was my problem. Not escaping the backslashes. Thanks.

I tried doing the same testing a while back with raw strings but is was more of a hassle than it was worth. What I found to be a good testing methodology is to assemble a class and then serialize it, like so:

PubSubMessage fake_message = new PubSubMessage
{
    type = PubSubType.MESSAGE.ToString(),
    data = new PubSubMessageData
    {
        topic = string.Empty,
        message = string.Empty
    }
};

PubSubSubscriptionsMessage fake_sub_message = new PubSubSubscriptionsMessage
{
    user_name = "dallas",
    display_name = "dallas",
    channel_name = "twitch",
    user_id = "44322889",
    channel_id = "12826",
    time = DateTime.Parse("2015-12-19T16:39:57-08:00"),
    sub_plan = "1000",
    sub_plan_name = "Mr_Woodchuck - Channel Subscription (mr_woodchuck)",
    months = 9,
    context = "resub",
    sub_message = new PubSubSubscriptionsSubMessage
    {
        message = "A Twitch baby is born! KappaHD",
        emotes = new List<PubSubEmotes>
        {
            new PubSubEmotes
            {
                start = 7,
                end = 23,
                id = "2867"
            }
        }
    }
};

fake_message.data.topic = "channel-subscribe-events-v1.44322889";
fake_message.data.message = JsonConvert.SerializeObject(fake_sub_message);

string fake_message_string = JsonConvert.SerializeObject(fake_message);

Then all you need to do is deserialize the string like normal. I personally find this much more flexible and much easier to read.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.