Give this a try.  Note that it will only work on non-marketplace images:   on('ready',()=>{
  const playerCanControl = (obj, playerid='any') => {
    const playerInControlledByList = (list, playerid) => list.includes('all') || list.includes(playerid) || ('any'===playerid && list.length);
    let players = obj.get('controlledby')
      .split(/,/)
      .filter(s=>s.length);
    if(playerInControlledByList(players,playerid)){
      return true;
    }
    if('' !== obj.get('represents') ) {
      players = (getObj('character',obj.get('represents')) || {get: function(){return '';} } )
        .get('controlledby').split(/,/)
        .filter(s=>s.length);
      return  playerInControlledByList(players,playerid);
    }
    return false;
  };
  const getCleanImgsrc = (imgsrc) => {
    let parts = imgsrc.match(/(.*\/images\/.*)(thumb|med|original|max)([^?]*)(\?[^?]+)?$/);
    if(parts) {
      return parts[1]+'thumb'+parts[3]+(parts[4]?parts[4]:`?${Math.round(Math.random()*9999999)}`);
    }
    return;
  };
  const isString = (s)=>'string'===typeof s || s instanceof String;
  let tokenIds = [];
  const saveTokenId = (obj) => {
    tokenIds.push(obj.id);
  };
  const setTokenRandomSide = (obj,prev,force=false) => {
    if(tokenIds.includes(obj.id) || force){
      tokenIds=tokenIds.filter(id => id !== obj.id);
      if( 'graphic' === obj.get('type') && 'token'   === obj.get('subtype') && ! playerCanControl(obj)){
        let sideText = obj.get('sides');
        if( sideText.length ){
          let sides = sideText.split(/\|/).map(decodeURIComponent).map(getCleanImgsrc).filter(isString);
          if(sides.length){
            obj.set({
              imgsrc: sides[randomInteger(sides.length)-1]
            });
          }
        }
      }
    }
  };
  on('add:graphic', saveTokenId);
  on('change:graphic', setTokenRandomSide);
});
  Edit: Fixed crash when Marketplace Images are present.