Plugin Dev: No public methods

I am trying to create a plugin and keep getting this error, but I don’t know what it is in reference to?


narrowed it down to the http.get, unsure why however. The logged URL is valid.

const endpointUrl = protocol + host + ":" + port + http_root +  endpoint + "?apikey=" + apiKey + "&cmd=" + cmd + "&count=" + limit + "&media_type=" + type;
let response = http.get(endpointUrl)

Try this instead. I don’t think “const” can reference other variables.

var http = new HTTPClient();
var endpointUrl = protocol + host + ":" + port + http_root +  endpoint + "?apikey=" + apiKey + "&cmd=" + cmd + "&count=" + limit + "&media_type=" + type;
var response = http.get(endpointUrl);

Thanks Bill. I had already tried that with same result. const just means once it’s written to, it can’t be overwritten or rewritten.

Would you mind posting or sending me the entire plugin? That code above ran just fine on my machine. If you are seeing the error, I think it’s something else that’s causing the issue.

Can you change the file extension to “.plugin”?

I can’t download files with JS.

something is weird with the upload. No matter what file I try to upload again, it is always putting in the original. So here is the actual code.

        // this requires the use of Tautulli as well as a Plex server
        plugin.Name = "PlexRecentlyAddedMovies";
        plugin.OnChangeRequest = onChangeRequest;
        plugin.OnConnect = onConnect;
        plugin.OnDisconnect = onDisconnect;
        plugin.OnPoll = onPoll;
        plugin.OnSynchronizeDevices = onSynchronizeDevices;
        //Poll once every 5 minutes (aka 300000 ms).
        plugin.PollingInterval = 3000;
        plugin.DefaultSettings = {
          "Tautulli_API_Key" : "ABC123",
          "Limit" : "5",
          "Host" : "",
          "Port" : "8181",
          "HTTP_Root" : "tautulli",
          "SSL" : "false"
        var http_root = ""
        var protocol = 'http://'
        var type = "movie"
        var cmd = "get_recently_added"
        var endpoint = "/api/v2"
        var thumb = {}
        var http = new HTTPClient();
        var DEVICE_ID = "PRAMOVIES";
        function onChangeRequest(device, attribute, value) {
          console.log(device, attribute, value);
          // switch (attribute) {
          //   case "Switch":
          //     device.Switch = value;
          //     break;
          //   default:
          //     break;
          // }
        function onConnect() {
          console.log("start connect");
          //var device = plugin.Devices[DEVICE_ID];
          if(plugin.Settings["Tautulli_API_Key"] === "") {
            // console.log("no api key entered");
            console.log("Please add your Tautulli API key before proceeding.")
          } else {
            console.log("call getpayload")
        function onDisconnect() {
        function onPoll() {
          console.log("start poll")
        function onSynchronizeDevices() {
          var PlexRecentlyAddedMovies = new Device();
          PlexRecentlyAddedMovies.Id = DEVICE_ID;
          PlexRecentlyAddedMovies.DisplayName = "Plex Recently Added Movies";
          PlexRecentlyAddedMovies.Capabilities = [];
          PlexRecentlyAddedMovies.Attributes = ["full_title", "added_at", "parent_thumb", "grandparent_thumb", "thumb", "banner", "art"];
          plugin.Devices[DEVICE_ID] = PlexRecentlyAddedMovies;
        function getPayload() {
          console.log("in getpayload")
          var apiKey = plugin.Settings["Tautulli_API_Key"];
          var host = plugin.Settings["Host"];
          var port = plugin.Settings["Port"];
          var limit = plugin.Settings["Limit"];
          // var response;
          if (plugin.Settings["SSL"] === "True") protocol = 'https://'
          if (plugin.Settings["HTTP_Root"] !== "") http_root = "/" + plugin.Settings["HTTP_Root"]
          var endpointUrl = protocol + host + ":" + port + http_root +  endpoint + "?apikey=" + apiKey + "&cmd=" + cmd + "&count=" + limit + "&media_type=" + type;
          var response = http.get(endpointUrl)
          parsePayload(, limit)
        function parsePayload (payload, limit) {
          console.log("in parsepayload")
          var PlexRecentlyAddedMovies = plugin.Devices[DEVICE_ID];
          movies = [] //empties array to remove previous details
          for (var i = 0; i <= limit; i++) {
            if (payload.recently_added[i].thumb !== "") {	//DOES POSTER EXIST?
              thumb[i] = payload.recently_added[i].thumb;
            else if (payload.recently_added[i].parent_thumb !== "") {
              thumb[i] = payload.recently_added[i].parent_thumb;
            else if (payload.recently_added[i].grandparent_thumb !== "") {
              thumb[i] = payload.recently_added[i].grandparent_thumb;
            else { // no default thumb!
              thumb[i] = "";
            movies[i] = { //creates arrray with movies - used for gridview
          PlexRecentlyAddedMovies.ContentList = movies;

When I start the plugin I do not see that error. I do see that your onChangeRequest code is invalid.

Your current code has this line:

console.log(device, attribute, value);

That’s not going to work. You will see the “No public methods” error if you try to run that code. That log method expects a singe string parameter.

Instead use something like this:

console.log(device.Name + " " + attribute);

I removed it and was still getting the error, it doesn’t like console.log(response) either. I removed it and seems ok now. Is this log different than JS log? What version is this using?

Yes. It is different. Plugins are actually using a custom Home Remote console object. It’s not the same console you’re familiar with. It’s very basic. Only 1 function has been implemented & that’s the single string parameter log call. Any other use of console is not supported. Since the response object isn’t a string, it’s giving you an error.

Ahh, ok, makes sense now. Be nice to have more plugin documentation. But I know you’re busy.

There are also 404’s in the app for help links ie.

There some classes that haven’t been documented yet. You will see 404 errors for those items. If you have any question about a property in that class, let me know.

trying to understand how gridview works. say I need 3 columns and auto number of rows. Then how do I tell it what data goes where from my ItemsSource?

It’s in the same order as the data. Columns of -1 means you have a dynamic number columns based on the available size so you won’t know where exactly an item might be when using -1. If you set Columns to 3, then your GridView will look something like this:


oh ok, i was looking at it from and html table perspective.

so it’s not
thumb | title | year
thumb | title | year
thumb | title | year

No, it is not like that.