Duplicated broadcast messages

Hi folks!

I encounter a problem using extension pubsub messages with bits confirm window.

What I’m trying to achieve is to broadcast a custom message on bits transaction. I know there is a broadcast function on product catalog but it doesn’t provide enough customization and thus doesn’t suit desired look.

So the bug is the following. When viewer has not been using bits and when bits confirm window has never appeared broadcast messages works fine.

But after the confirm window was opened and viewer confirmed the transaction pubsub message listener begins to fire multiple times for one incoming message.

Moreover each confirm window opened adds one redundant fire of listener. After some debug I‘ve found out that function onControllerMessage from javascript helper begans to fire multiple times.

It’s a very strange and undocumented behavior.

Any tips from community or fixes from twitch would be highly appreciated!

Where in your code are you registering your listener? If you’re doing it from inside onAuthorized then yeah it can potentially be called multiple times during the lifecycle of the extension. What you could do is have your function that registers the listener to check a boolean variable, and then flip it after it runs the first time so that any subsequent attempts to register duplicate listeners will not happen.

i check many times - my listener bind called only one time on page load.

I can confirm I am also experiencing this issue. My Extension has been live for months and this issue has never been noted before, however I personally started observing it as of yesterday.

For reference, here is my listener code

window.onload = function () {
    window.Twitch.ext.listen('broadcast', broadcastMessage);
};

Note - I initially had this code outside of the window.onload and the same thing was happening.

I noticed if I remove the listen from my JS file and instead register it by pasting into the brower dev tools console some time after my Extension was loaded I do not get the duplication issue.


Edit: After some testing, I believe the duplication only happens if the listen is bound before the initial onAuthorized is triggered. I tested this by having my listen outside the onAuthorized and binding it after several different timeouts (1ms, 100ms, 1000ms). The only instances I have observed the broadcast duplicating has been those in which the listen bind happens before the initial onAuthorized has been received.

I have now moved my listen bind inside the onAuthorized handler with a boolean to ensure it only happens on the first onAuthorized and am no longer observing duplicates. E.g.

var listenBound = false;
window.Twitch.ext.onAuthorized(function (auth) {
    if (listenBound === false) {
        window.Twitch.ext.listen('broadcast', broadcastMessage);
        listenBound = true;
    }
});

I also used the Wayback Machine to find older versions of the Twitch JavaScript helper file. The version from August 22nd appeared to have the same duplication and any older versions (March and earlier) seemed to have other API related issues which rendered them untestable. So, either this issue has been occurring since on or before August 22nd, or it is not directly related to the JavaScript helper file.

Of course my observations above may be a red herring entirely, but my testing thus far has seemed pretty consistent and I have in place what seems to be a reliable work around :crossed_fingers:

I raised a similar issue in September 2017

TLDR: don’t listen in onAuthorised basically

Hi Barry this issue doesn’t appear to be related to that. I am experiencing exactly what OP is describing and I only noticed it this weekend on an Extension whose code has not changed for months. My code was not inside onAuthorized . Please check out my edit in my previous comment for more details of what scenarios seem to manifest this bug.

I’d rather not listen inside onAuthorized due to being called multiple times, but right now ensuring that my listen is bound after the initial onAuthorized is fire is the only way I can avoid this duplication issue.

Thanks, tf2casperr.
After moving listener bind into onAuthorized hook all works as documented.
Multiple messages are dissapeared.

I experienced the same issue as OP & tf2capserr today (Oct 15). Solution to move broadcast after onAuthorized initial call fixed it for me.

I know this is an old post, but OMG, I was pulling my hair out due to whenever I went for lunch and left the stuff running I would come back to see a few onAuthorized console messages and when I sent a PubSub Message from my EBS I received multiple broadcasts responses from listen I first saw it the other week and thought it was my code, so cleaned it up a bit and still was getting it.

But to be fair, I thought everything needed to be inside onAuthorized code, that way we know we are authed when calling the other code.

But it does make sense as to why this is happening due to each time it did onAuthorized it adds a listen so yeah it would get multiple responses.

So I guess I will move some code about again LOL.

The thing to consider is that you should treat onAuthorized as document.ready (or similar), only hiccup is that onAuthorized can and will be called multiple times (and to my knowledge document.ready doesn’t can’t/should never)

Yeah. I put a time stamp on it and it seems to happen about every 50 mins give or take 30 odd seconds.
So… I still need to send the viewer.id and the viewer.helixToken (assuming I use that to get the display_name) to my EBS within the onAuthorized block due to the tokens within auth also change.

Yeah the window.onload / $(document).ready was only called once which makes sense and is confirmed by the console not clearing.

Going by your example, I assume that onAuthorize can never fail then due to the .listen block of code will be run instantly either way.

Also what if I have code that might “need” to access any parts of auth in the code outside after the onAuthorize block? Like auth.token for the Frontend to EBS communication. I ask due to any code that needs to access auth after the onAuthorize block is run instantly and will fail (Uncaught ReferenceError: auth is not defined) due to auth might not be set at that point.

Like for example the viewer joins a stream right as soon as the game starts an event that tells the EBS to send a PubSub Message, or onAuthorize gets re-triggered the same time as the viewer clicks on an object, for one the JWT would then be different, so would the auth.token at the time of the click would be invalid too yes ?

I guess I could store the {id, display_name} etc “if” I need them, just that any requests from the Frontend to the EBS requires the auth.token.

I will rethink the order stuff is run in my code.

see Extensions Reference | Twitch Developers for super globals

window.Twitch.ext.viewer.sessionToken
window.Twitch.ext.viewer.helixToken

Yeah I saw those, but you still have the issue where there will be a time that they are not set. While that time will be very small and may never happen, but you could be unlucky and it happens.

Say I have the following code (for example):

window.Twitch.ext.onAuthorized((auth) => {
    console.log('Twitch Extension Authorized successfully.', auth);
    ...
});

// Normally you wouldn't have this.
console.log('Outside onAuthorized code: ', window.Twitch.ext.viewer.sessionToken);

console.log('Setting up PubSub listen...');
window.Twitch.ext.listen('broadcast', (target, contentType, message) => {
    ...
});

You will see in the console the following logs in this order:
1: Outside onAuthorized code: null
2: Setting up PubSub listen…
3: Twitch Extension Authorized successfully. {auth info etc}

So like I said you could have variables not set in some situations, whereas when it was all inside the onAuthorized block it was all fine apart from that re-triggering of the onAuthorized every 50 mins or so.

Like I said it shouldn’t be too much of an issue, just means that I need to look at my code to see what variables I am using and when its used. I should be fine.

That may only be before the first onAuthorized happens. never after.

Yeah you have to wait for the first “extension is ready” aka onAuthorized you tried to grab the token too soon

That was my point with all code outside of the onAuthorized block i.e. after it. Like the .listen block are all run at the same time so its a race to what gets triggered first.

You might need to send actions from the viewer when they interact with something from the Frontend to the EBS.

Sure while the chances of .listen getting triggered first and sessionToken being null are low, but there are chances of it being invalid during the time of sending the viewer (i.e. users) interaction from the Frontend to the EBS due to being unlucky and the re-triggering of onAuthorized happens, making the sessionToken invalid.

Or is there an overlaps of the sessionToken on the re-triggering of onAuthorized where both could be valid?

Sure window.Twitch.ext.viewer.id and window.Twitch.ext.viewer.sessionToken probably will reduce that issue due to being accessible in both event code blocks.

But I will do some tests tomorrow.

Thanks for the responses, it cleared up a few of my questions.

You shouldn’t allow any actions before the first onAuthorized occurs which makes this irrelevant imo. As otherwise you have no token at all to use. And/or Twitch/Extension helper actions are still loading.

Yes.

Yeah if in dobut stick to the globals

Good Morning.

That was what I was saying. You cannot stop that from happening, like in your example code shown below:

var authed = false;
window.Twitch.ext.onAuthorized(function(auth) {
    console.log('Authorised');
    if (authed) {
        return;
    }
    authed = true;
});

window.Twitch.ext.listen('broadcast', function (topic, contentType, message) {
    console.log('Recv');
    // do stuff
});

Any code within .listen block that may require the window.Twitch.ext.viewer.sessionToken could be null due to the .listen block was triggered first.

Like I said its very unlikely it happening, but it could if you are unluky.

But I will assume that won’t happen and move on with coding.

Ok, thats good that we have an overlap where multiple tokens can be valid. I am assuming the tokens will live the remainder of their life i.e. the 1 hour set in the JWT.exp ?
If so then that is plenty of time to switch over to the new token.

So that isn’t an issue now.

Yeah that seems like a good plan, I was using auth.token, but all my code was within the onAuthorized block.

I am still confident that I can get it to all work within the onAuthorized block LOL so I am going to create a very basic code to see. I was just not aware that it could get triggered / invoked multiple times.
So just waiting for the approx 50 mins without doing anything to see.

Also what is the following that pops up now and then once I have setup the .listen:


All I have in my viewer.js file (basic code for tests) is the following:

if (window.Twitch && window.Twitch.ext) {

    var hooksSet = false;
    window.Twitch.ext.onAuthorized((auth) => {
        console.log('Twitch Extension Authorized successfully.', auth);
        console.log('window.Twitch.ext: ', window.Twitch.ext);
        console.log('isLinked: ', window.Twitch.ext.viewer.isLinked);
        console.log('Date: ', new Date());

        if (!hooksSet) {
            console.log('Setting up PubSub listen (broadcast)...');
            window.Twitch.ext.listen('broadcast', (target, contentType, message) => {
                console.log('broadcast: ', { target, contentType, message }, new Date());
            });

            hooksSet = true;
        }
    });
}

I am using Edge for displaying of the Extension, but I do have a Twitch Channel open on Firefox, so it shouldn’t be that causing the error in the image above.

I have only started seeing this the last few days, so its something that Twitch has changed their end.

I guess, sure, if you respond to a pubsub event by broadcasting the token.

Of in this case check if authed is true or not before doing the action

Or the listen call goes in after the authed=true line in my onAuthed (I think thats exampled in the other post)

Probably need to move this to a different thread as it doesn’t pertain to op any more

back-forward cache sounds like a browser thing/plugin issue as all your sockets are dead there. Chat and pubsub and BTTV (and I doubt BTTV is being connected to in your ext here)

I will do and thanks for clearing stuff up.