Nice, i am eagerly awaiting. Now i use a version of API Heartbeat that also shows a heartbeat in the API log (every 30 seconds) and logs all (? i hope) on() events. Maybe that is something that can be consolidated - and made really nice as my coding is of the 'make it work get a bigger hammer style. i basically added three functions: mylog = function(msg) { let d = new Date(); let lines = new Error().stack.split("\n"); log(d.toUTCString() + " " + lines[2].trim() + " " + msg); }, logTimestamp = function() { mylog('beat'); },
logOnEvent = function(event, obj, prev){
mylog(`${event} ${obj.id}`);
for (var p in prev) {
if (p !== 'bio' && p !== 'notes' && p !== '_defaulttoken' & p !== 'gmnotes') {
if( prev[p] !== obj.get(p)) {
mylog(`${event} ${obj.id} ${p} : ${prev[p]} => ${obj.get(p)}`);
}
}
}
},
and then added in startStopBeat() setInterval(logTimestamp,30000); and finally updated registerEventHandlers() to registerEventHandlers = function() { on('change:campaign:playerpageid', (obj,prev) => { logOnEvent("change:campaign:playerpageid",obj,null); }); on('change:campaign:turnorder', (obj,prev) => { logOnEvent("change:campaign:turnorder",obj,null); }); // prev generates too much logging on('change:campaign:initiativepage', (obj,prev) => { logOnEvent("change:campaign:initiativepage",obj,prev); }); on("change:player", (obj,prev) => { logOnEvent("change:player",obj,prev); }); on('add:page', (obj) => { logOnEvent("add:page",obj.id,null); }); on("change:page", (obj,prev) => { logOnEvent("change:page",obj,prev); }); on('destroy:page', (obj) => { logOnEvent("destroy:page",obj.id,null); }); on('add:path', (obj) => { logOnEvent("add:path",obj.id,null); }); on("change:path", (obj,prev) => { logOnEvent("change:path",obj,prev); }); on('destroy:path', (obj) => { logOnEvent("destroy:path",obj.id,null); }); on('add:text', (obj) => { logOnEvent("add:text",obj.id,null); }); on("change:text", (obj,prev) => { logOnEvent("change:text",obj,prev); }); on('destroy:text', (obj) => { logOnEvent("destroy:text",obj.id,null); }); on('add:graphic', (obj) => { logOnEvent("add:graphic",obj.id,null); }); on("change:graphic", (obj,prev) => { logOnEvent("change:graphic",obj,prev); }); on('destroy:graphic', (obj) => { logOnEvent("destroy:graphic",obj.id,null); }); on('remove:graphic', (obj) => { logOnEvent("destroy:graphic",obj.id,null); }); on('add:token', (obj) => { logOnEvent("add:token",obj.id,null); }); on("change:token", (obj,prev) => { logOnEvent("change:token",obj,prev); }); on('destroy:token', (obj) => { logOnEvent("destroy:token",obj.id,null); }); on('add:card', (obj) => { logOnEvent("add:card",obj.id,null); }); on("change:card", (obj,prev) => { logOnEvent("change:card",obj,prev); }); on('destroy:card', (obj) => { logOnEvent("destroy:card",obj.id,null); }); on('add:deck', (obj) => { logOnEvent("add:deck",obj.id,null); }); on("change:deck", (obj,prev) => { logOnEvent("change:deck",obj,prev); }); on('destroy:deck', (obj) => { logOnEvent("destroy:deck",obj.id,null); }); on('add:character', (obj) => { logOnEvent("add:character",obj.id,null); }); on("change:character", (obj,prev) => { logOnEvent("change:character",obj,prev); }); on('destroy:character', (obj) => { logOnEvent("destroy:character",obj.id,null); }); on('add:handout', (obj) => { logOnEvent("add:handout",obj.id,null); }); on("change:handout", (obj,prev) => { logOnEvent("change:handout",obj,prev); }); on('destroy:handout', (obj) => { logOnEvent("destroy:handout",obj.id,null); }); on('add:attribute', (obj) => { logOnEvent("add:attribute",obj.id,null); }); on("change:attribute", (obj,prev) => { logOnEvent("change:attribute",obj,prev); }); on('destroy:attribute', (obj) => { logOnEvent("destroy:attribute",obj.id,null); }); on('chat:message', handleInput); on('change:player:_online', startStopBeat); }; Maybe this should be two scripts. Nah.... Roll20 rolls it into one large script anyways.