Problem with handling pubsub messages


i’m new at devloping twitch extentions, have looked at the examples but now i’m stuck.
I have a front end video component that can call my php backend, but i cant send from my backend via pubsub to all user front ends. I guess i do something wrong with the pubsub message.

here is how i created the message php side

$EXT_CLIENT_ID = 'XXX'; // my id from the extention
$KEY = 'XXX'; // secret from extention
$CHANNEL = '265737932'; // dev rig channel

$payloadArray = array(	"exp" => time()+5000,
			"user_id"=> $CHANNEL, 
			"role"=> "external",
			"channel_id" =>$CHANNEL, 
			"pubsub_perms" => array("send" => "broadcast")
$payload = json_encode($payloadArray);	

$jwt = new JWT();
$jwtload = $jwt->encode($payload, $KEY, $algo = 'HS256');

$url = "" . $CHANNEL;
$headers = array(
	"Authorization: Bearer " . (string)$jwtload,
	"Client-Id: " . $EXT_CLIENT_ID,
	"Content-Type: application/json"

$data = array(
	"content_type" => "application/json",
	"targets" => array("broadcast"),
	"message" => '{"content_type":"application/json", "message":"{\"foo\":\"bar\"}", "targets":["broadcast"]}'

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if (curl_error($ch)) {

and thats inside the viewer.js where i want to log inside the dev rig

var twitch = window.Twitch.ext;

twitch.listen("broadcast", function(target, contentType, message) {

i dont know whats wrong, i get no curl error but it doesnt show inside the dev rig.
Maybe someone can help me?

$payloadArray = array(	"exp" => time()+5000,
		"role"=> "external",
		"channel_id" =>$CHANNEL, 
		"pubsub_perms" => array("send" => ["broadcast"])

Your pubsub_perms appear in correct “send” should be an array of strings, not an array. Also don’t need user_id here


thank you i added your fix and did some more testing finaly i had to add bas64 decode before the key and it works now - yeah


Hello, I’m trying this in node and somehow am stuck as well. Any suggestions? I always get {“error”:“Unauthorized”,“status”:401,“message”:“authentication failed”} returned to me.

const currentSecret = '<base64 encoded secret copied from extension settings>';
const ChannelId = '<my channel id>';
const OwnerId = '<my user id>';
const ClientId = '<client id from overview on my extension>';
const jwt = require('jsonwebtoken');
const request = require("request");

const secret = Buffer.from(currentSecret, 'base64');

const signedJwt = makeServerToken(ChannelId);

var options = {
        url : '' + ChannelId,
        headers :{
                'Authorization' : 'Bearer ' + signedJwt,
                'Client-Id': '<my client id from extensions overview>',
                'Content-Type': 'application/json'
        body : JSON.stringify({
                message: { "foo":"bar" },
                content_type: 'application/json',
                targets: ['broadcast']

function details(error,response,body) {
request(options, details);

// Create and return a JWT for use by this service.
function makeServerToken(channelId) {
  const payload = {
    exp: Math.floor( / 1000) + 60,
    channel_id: String(channelId),
    role: 'external',
    pubsub_perms: {
      send: ['broadcast'],
  return jwt.sign(payload, secret, { algorithm: 'HS256' });

  1. please don’t necro and hijack someone elses post
  2. options is missing a type: ‘post’ you appear to be making a get request instead of a post request.
  3. body is wrong:

Should be:

            message: JSON.stringify({ "foo":"bar" }),
            content_type: 'application/json',
            targets: ['broadcast']


Thanks BarryCarlyon! Sorry about posting on this thread instead of making a new one. I found it thru google initially and thought someone else may find that way and then would see something relevant. Won’t do again in the future.