Thinking about it, this sounds a bit tedious... How about this: !random-journal [ path] Picks a random entry from the specified folder path in the journal and gives a link to it: !random-journal Test/Encounters Omitting the path means it grabs one from the root of the journals. Works for characters and handouts, so just build your folders appropriately. This version just whispers to the GM, but you can expand on it I'll wager. =D Code: on('ready',function(){
'use strict';
on('chat:message',function(msg){
if('api' === msg.type && msg.content.match(/^!random-journal/) && playerIsGM(msg.playerid) ){
let path=msg.content.replace(/^!random-journal\s*/,''),
journals=JSON.parse(Campaign().get('journalfolder')),
obj = findObjs({
id: _.chain(path.split('/'))
.reject(_.isEmpty)
.reduce((m,p)=>(_.filter(m,(o)=>_.isObject(o) && o.n===p)[0]||{i:[]}).i, journals)
.reject(_.isObject)
.sample()
.value()
})[0];
if(obj){
sendChat('RandomJournal',`/w gm <a style="text-decoration:underline;padding: .1em .5em; border-radius: .5em;display:inline-block;border:1px solid #ccc;background-color:#eee;" href="<a href="http://journal.roll20.net/${obj.get('type')}/${obj.id}">${path.length" rel="nofollow">http://journal.roll20.net/${obj.get('type')}/${obj.id}">${path.length</a> ? `<b>${path}</b>: `:''}${obj.get('name')}</a>`);
} else {
sendChat('RandomJournal', `/w gm <b>Error:</b> No journal entries found in <code>${path||'[Root]'}</code>.`);
}
}
});
});