callback is not a function – castv2

Issue

I’m following this http://siglerdev.us/blog/2021/02/26/google-home-message-broadcast-system-node-js/31 which uses this library castv2-client to send messages to my google home. It works. I get the messages no problem, but the code throws

C:\Users\Phil\Documents\google home\node_modules\castv2-client\lib\controllers\receiver.js:72
    callback(null, response.status.volume);
    ^

TypeError: callback is not a function
    at C:\Users\Phil\Documents\google home\node_modules\castv2-client\lib\controllers\receiver.js:72:5                                                                  ver.js:72
    at fn.onmessage (C:\Users\Phil\Documents\google home\node_modules\castv2-client\lib\controllers\request-response.js:27:7)
    at fn.emit (events.js:203:15)
    at Channel.onmessage (C:\Users\Phil\Documents\google home\node_modules\castv2-client\lib\controllers\controller.js:16:10)                                           s\receiver.js:72:5
    at Channel.emit (events.js:198:13)                                              lib\controllers\request-response.js:27:7)
    at Client.onmessage (C:\Users\Phil\Documents\google home\node_modules\castv2\lib\channel.js:23:10)                                                                  ient\lib\controllers\controller.js:16:10)
    at Client.emit (events.js:203:15)
    at PacketStreamWrapper.onpacket (C:\Users\Phil\Documents\google home\node_module\channel.js:23:10)s\castv2\lib\client.js:81:10)
    at PacketStreamWrapper.emit (events.js:198:13)                                  s\castv2\lib\client.js:81:10)
    at TLSSocket.<anonymous> (C:\Users\Phil\Documents\google home\node_modules\castv2\lib\packet-stream-wrapper.js:28:16)                     

What’s wrong with the code that is throwing this AND/OR how can I fix it so it’s either more graceful in catching error and doesn’t throw since the message still delivers to google home or fix it to not throw this at all?
I appreciate any help!

I believe it’s here in the castv2-client library that it’s referencing, but I haven’t been able to make it happy.

ReceiverController.prototype.launch = function(appId, callback) {
  this.request({ type: 'LAUNCH', appId: appId }, function(err, response) {
    if(err) return callback(err);
    if(response.type === 'LAUNCH_ERROR') {
      return callback(new Error('Launch failed. Reason: ' + response.reason));
    }
    callback(null, response.status.applications || []);
  });
};

my code

var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
const googleTTS = require('google-tts-api');

var App = {
  playin: false,
  DeviceIp: "",
  Player: null,
  GoogleHome: function (host, url) {
    var client = new Client();
    client.connect(host, function () {
      client.launch(DefaultMediaReceiver, function (err, player) {
        client.setVolume({ level: 1 });
        var media = {
            contentId: url,
            contentType: 'audio/mp3',
            streamType: 'BUFFERED'
        };
        App.Player = player;
        App.Player.load(media, { autoplay: true }, function (err, status) {
            App.Player.on('status', function (status) {
                if (status.playerState === "IDLE" && App.playin === false) {
                    client.close();
                }
            });
        });
    });
});
client.on('error', function (err) {
  console.log('Error: %s', err.message);
  client.close();
});
},
run: function (ip, text) {
  App.DeviceIp = ip;
  const url = googleTTS.getAudioUrl(text, {
      lang: 'en-US',
      slow: false,
      host: 'https://translate.google.com',
  });
  App.GoogleHome(App.DeviceIp, url, function (res) {
      console.log(res);
  })
},
broadcast: function(text){
  const ips = '192.168.0.15'.split(","); //From config, 192.168.68.105,192.168.68.107,192.168.68.124
  for (var s of ips){
      App.run(s, text);
  }
}
}

App.broadcast("Broadcasted to all of the devices"); //Only works if you did step 4.5

Solution

The error you reported:

C:\Users\Phil\Documents\google home\node_modules\castv2-client\lib\controllers\receiver.js:72
    callback(null, response.status.volume);
    ^

TypeError: callback is not a function
    at C:\Users\Phil\Documents\google home\node_modules\castv2-client\lib\controllers\receiver.js:72:5    

seems to be related to the invocation of the method setVolume in your client:

client.setVolume({ level: 1 });

Please, consider review the source code of receiver.js in the castv2-client library:

ReceiverController.prototype.setVolume = function(options, callback) {
  var data = {
    type: 'SET_VOLUME',
    volume: options // either `{ level: 0.5 }` or `{ muted: true }`
  };


  this.request(data, function(err, response) {
    if(err) return callback(err);
    callback(null, response.status.volume);
  });
};

The library is claiming because you aren’t providing a proper callback when invoking that function.

I have never used the library but probably providing something similar to the following callback could be of help:

client.setVolume({ level: 1 }, function(err, volume) {
  if (err) {
    // Handle error as appropriate
    console.log('Error on setVolume:', err);
  } else {
    console.log('Volume:', volume)
  }
  
});

Your final code would look like this:

var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
const googleTTS = require('google-tts-api');

var App = {
  playin: false,
  DeviceIp: "",
  Player: null,
  GoogleHome: function (host, url) {
    var client = new Client();
    client.connect(host, function () {
      client.launch(DefaultMediaReceiver, function (err, player) {
        client.setVolume({ level: 1 }, function(err, volume) {
          if (err) {
            // Handle error as appropriate
            console.log('Error on setVolume:', err);
          } else {
            console.log('Volume:', volume)
          }
        });

        var media = {
            contentId: url,
            contentType: 'audio/mp3',
            streamType: 'BUFFERED'
        };
        App.Player = player;
        App.Player.load(media, { autoplay: true }, function (err, status) {
            App.Player.on('status', function (status) {
                if (status.playerState === "IDLE" && App.playin === false) {
                    client.close();
                }
            });
        });
    });
});
client.on('error', function (err) {
  console.log('Error: %s', err.message);
  client.close();
});
},
run: function (ip, text) {
  App.DeviceIp = ip;
  const url = googleTTS.getAudioUrl(text, {
      lang: 'en-US',
      slow: false,
      host: 'https://translate.google.com',
  });
  App.GoogleHome(App.DeviceIp, url, function (res) {
      console.log(res);
  })
},
broadcast: function(text){
  const ips = '192.168.0.15'.split(","); //From config, 192.168.68.105,192.168.68.107,192.168.68.124
  for (var s of ips){
      App.run(s, text);
  }
}
}

App.broadcast("Broadcasted to all of the devices"); //Only works if you did step 4.5

Answered By – jccampanero

Answer Checked By – Jay B. (AngularFixing Admin)

Leave a Reply

Your email address will not be published.