var Clay = require('@rebble/clay'); var clayConfig = require('./config'); var customClay = require('./customClay'); new Clay(clayConfig, customClay); Pebble.addEventListener("ready", function () { Pebble.sendAppMessage({ PKJS_READY: 1 }); }); Pebble.addEventListener("appmessage", function (dict) { if (dict.payload["PKJS_SLEEP_TIMESTAMP"]) { const sleepTimestamp = dict.payload["PKJS_SLEEP_TIMESTAMP"]; const cfg = JSON.parse(localStorage.getItem('clay-settings')); // report to user if some configuration is missing if (cfg.CLAY_API_HOST == "" || cfg.CLAY_API_KEY == "" || cfg.CLAY_USER == "") { Pebble.sendAppMessage({ PKJS_LAST_WATCHED: "SOME APP SETTINGS ARE UNSET" }); } if (cfg.CLAY_API_IS_JELLYFIN == true) { callAPI(cfg.CLAY_API_HOST + "/System/ActivityLog/Entries?hasUserId=true&limit=100", cfg.CLAY_API_KEY, true, cfg.CLAY_USER, sleepTimestamp * 1000); } else { // The official history endpoint doesn't seem to return history w/o Plex Pass. // If someone with Plex Pass wants to give it a shot, I'd be happy to accept a PR adding this as an option. // Until then, I'm using Tautulli because it's free. //callAPI(cfg.CLAY_API_HOST + "/status/sessions/history/all", cfg.CLAY_API_KEY, false, cfg.CLAY_USER, sleepTimestamp); callAPI(cfg.CLAY_API_HOST + "/api/v2?apikey=" + cfg.CLAY_API_KEY + "&cmd=get_history&length=100", null, false, cfg.CLAY_USER, sleepTimestamp); } } }); function callAPI(fullURL, apiKey, isJellyfin, trackedUser, sleepTimestamp) { const xhr = new XMLHttpRequest(); let didReportError = false; function reportApiError(message) { if (didReportError) { return; } didReportError = true; Pebble.sendAppMessage({ PKJS_LAST_WATCHED: message }); } xhr.onerror = function () { reportApiError("API UNREACHABLE"); }; xhr.ontimeout = function () { reportApiError("API TIMEOUT"); }; xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 0) { reportApiError("API UNREACHABLE"); return; } if (xhr.status < 200 || xhr.status >= 300) { if (xhr.status == 401) { reportApiError("API ERROR: " + xhr.status + " (CHECK API KEY)"); } else { reportApiError("API ERROR: " + xhr.status); } return; } if (!xhr.responseText) { reportApiError("API EMPTY RESPONSE"); return; } let resp; try { resp = JSON.parse(xhr.responseText); } catch (e) { reportApiError("API INVALID RESPONSE"); return; } if (resp && ((isJellyfin === true && Array.isArray(resp.Items)) || (isJellyfin === false && Array.isArray(resp.response.data.data)))) { let delta; let bestDelta = Infinity; let lastWatched = ""; if (isJellyfin === true) { const re = /^(.+) is playing (.+) on .*$/; let arr; let logTimestamp; resp.Items.forEach(function (item) { arr = re.exec(item.Name); if (arr != null && arr[1] == trackedUser) { logTimestamp = Date.parse(item.Date); if (!Number.isNaN(logTimestamp)) { delta = sleepTimestamp - logTimestamp; if (delta >= 0 && delta < bestDelta) { bestDelta = delta; lastWatched = arr[2]; } } } }); } else { resp.response.data.data.forEach(function (item) { if (item.user == trackedUser) { // we use "date" instead of "started" because started tracks the first // time the user watched the media, not just the start of the last session. delta = sleepTimestamp - item.date; if (delta >= 0 && delta < bestDelta) { bestDelta = delta; lastWatched = item.full_title; } } }); } if (lastWatched != "") { //console.log("Last watched: " + lastWatched); Pebble.sendAppMessage({ PKJS_LAST_WATCHED: lastWatched }); } else { Pebble.sendAppMessage({ PKJS_LAST_WATCHED: "NO WATCH HISTORY FOUND FOR USER " + trackedUser }); } } } }; xhr.open("GET", fullURL, true); xhr.timeout = 8000; xhr.setRequestHeader("Accept", "application/json"); if (isJellyfin) { xhr.setRequestHeader("Authorization", 'MediaBrowser Token="' + apiKey + '"'); } xhr.send(null); }