# Duplicated broadcast messages

**URL:** <https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847>\
**Category:** Extensions\
**Created:** [September 23, 2018, 9:45am UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847 "2018-09-23T09:45:25Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![rassouljb](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rassouljb](https://discuss.dev.twitch.com/u/rassouljb)\
**Post date:** [September 23, 2018, 9:45am UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/1 "2018-09-23T09:45:25Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![Dist](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/dist/32/7192_2.png) [@Dist](https://discuss.dev.twitch.com/u/Dist)\
**Post date:** [September 23, 2018, 11:44am UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/2 "2018-09-23T11:44:29Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![rassouljb](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rassouljb](https://discuss.dev.twitch.com/u/rassouljb)\
**Post date:** [September 23, 2018, 11:47am UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/3 "2018-09-23T11:47:06Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tf2casperr](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/tf2casperr/32/9301_2.png) [@tf2casperr](https://discuss.dev.twitch.com/u/tf2casperr)\
**Post date:** [September 23, 2018, 2:38pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/4 "2018-09-23T14:38:38Z")

</div>

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 🤞

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 23, 2018, 7:15pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/5 "2018-09-23T19:15:00Z")

</div>

I raised a similar issue in September 2017

> [@Calling listen inside onAuthorized, listen callback'ed four times](https://discuss.dev.twitch.com/t/calling-listen-inside-onauthorized-listen-callbacked-four-times/12032):
>
> Consider this code: 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 }); }); Compared to var authed = false; window.Twitch.ext.onAuthorized(function(auth) { console.log('Authorised'); if (authed) { return; } authed = true; }); …

TLDR: don’t listen in onAuthorised basically

---

<div class="post-metadata">

**Author:** ![tf2casperr](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/tf2casperr/32/9301_2.png) [@tf2casperr](https://discuss.dev.twitch.com/u/tf2casperr)\
**Post date:** [September 23, 2018, 7:29pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/6 "2018-09-23T19:29:30Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![rassouljb](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rassouljb](https://discuss.dev.twitch.com/u/rassouljb)\
**Post date:** [September 25, 2018, 12:12am UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/7 "2018-09-25T00:12:43Z")

</div>

Thanks, [tf2casperr](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/4).  
After moving listener bind into onAuthorized hook all works as documented.  
Multiple messages are dissapeared.

---

<div class="post-metadata">

**Author:** ![yagottahavehart](https://avatars.discourse-cdn.com/v4/letter/y/8dc957/32.png) [@yagottahavehart](https://discuss.dev.twitch.com/u/yagottahavehart)\
**Post date:** [October 15, 2018, 8:40pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/8 "2018-10-15T20:40:38Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![TheUKDude](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/theukdude/32/28386_2.png) [@TheUKDude](https://discuss.dev.twitch.com/u/TheUKDude)\
**Post date:** [September 4, 2026, 12:53pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/9 "2026-09-04T12:53:58Z")

</div>

> [@BarryCarlyon](#):
>
> I raised a similar issue in September 2017
> 
> [Calling listen inside onAuthorized, listen callback'ed four times](https://discuss.dev.twitch.com/t/calling-listen-inside-onauthorized-listen-callbacked-four-times/12032)
> 
> TLDR: don’t listen in onAuthorised basically

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.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 4, 2026, 1:49pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/10 "2026-09-04T13:49:50Z")

</div>

> [@TheUKDude](#):
>
> 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.

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)

---

<div class="post-metadata">

**Author:** ![TheUKDude](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/theukdude/32/28386_2.png) [@TheUKDude](https://discuss.dev.twitch.com/u/TheUKDude)\
**Post date:** [September 4, 2026, 6:16pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/11 "2026-09-04T18:16:06Z")

</div>

> [@BarryCarlyon](#):
>
> 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.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 4, 2026, 6:21pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/12 "2026-09-04T18:21:25Z")

</div>

> [@TheUKDude](#):
>
> 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.

see [Extensions Reference | Twitch Developers](https://dev.twitch.tv/docs/extensions/reference/#helper-viewer) for super globals

```auto
window.Twitch.ext.viewer.sessionToken
window.Twitch.ext.viewer.helixToken

```

---

<div class="post-metadata">

**Author:** ![TheUKDude](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/theukdude/32/28386_2.png) [@TheUKDude](https://discuss.dev.twitch.com/u/TheUKDude)\
**Post date:** [September 4, 2026, 7:01pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/13 "2026-09-04T19:01:52Z")

</div>

> [@BarryCarlyon](#):
>
> see [Extensions Reference | Twitch Developers](https://dev.twitch.tv/docs/extensions/reference/#helper-viewer) for super globals
> 
> ```auto
> 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_):

```auto
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.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 4, 2026, 7:04pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/14 "2026-09-04T19:04:11Z")

</div>

> [@TheUKDude](#):
>
> 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.

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

> [@TheUKDude](#):
>
> You will see in the console the following logs in this order:  
> 1: Outside onAuthorized code: _null_

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

---

<div class="post-metadata">

**Author:** ![TheUKDude](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/theukdude/32/28386_2.png) [@TheUKDude](https://discuss.dev.twitch.com/u/TheUKDude)\
**Post date:** [September 4, 2026, 7:35pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/15 "2026-09-04T19:35:16Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 4, 2026, 7:46pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/16 "2026-09-04T19:46:21Z")

</div>

> [@TheUKDude](#):
>
> You might need to send actions from the viewer when they interact with something from the Frontend to the EBS.

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.

> [@TheUKDude](#):
>
> Or is there an overlaps of the **sessionToken** on the re-triggering of **onAuthorized** where both could be valid?

Yes.

> [@TheUKDude](#):
>
> 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.

Yeah if in dobut stick to the globals

---

<div class="post-metadata">

**Author:** ![TheUKDude](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/theukdude/32/28386_2.png) [@TheUKDude](https://discuss.dev.twitch.com/u/TheUKDude)\
**Post date:** [September 5, 2026, 12:24pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/17 "2026-09-05T12:24:38Z")

</div>

Good Morning.

> [@BarryCarlyon](#):
>
> 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.

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

```auto
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.

> [@BarryCarlyon](#):
>
> Yes.

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.

> [@BarryCarlyon](#):
>
> Yeah if in dobut stick to the globals

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`:

 ![image](https://d2opxh93rbxzdn.cloudfront.net/original/3X/6/1/612c1eaaaefef415ddc8163ea028e703003db249.png)  
All I have in my `viewer.js` file (_basic code for tests_) is the following:

```auto
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.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 5, 2026, 2:39pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/18 "2026-09-05T14:39:10Z")

</div>

> [@TheUKDude](#):
>
> 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.

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)

> [@TheUKDude](#):
>
> 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.

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)

---

<div class="post-metadata">

**Author:** ![TheUKDude](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/theukdude/32/28386_2.png) [@TheUKDude](https://discuss.dev.twitch.com/u/TheUKDude)\
**Post date:** [September 5, 2026, 7:04pm UTC](https://discuss.dev.twitch.com/t/duplicated-broadcast-messages/17847/19 "2026-09-05T19:04:43Z")

</div>

I will do and thanks for clearing stuff up.
