With fear of adding confusion I'll provide my generate skills function for 5e. It's built with es6 and some wrapper functions around roll20's getters and setters, but it should give you the idea: EDIT: This is sheet workers, but you could use a similar process for API, just replace the calls. const SKILLS = {
ACROBATICS: 'dexterity',
ANIMALHANDLING: 'wisdom',
ARCANA: 'intelligence',
ATHLETICS: 'strength',
DECEPTION: 'charisma',
HISTORY: 'intelligence',
INSIGHT: 'wisdom',
INTIMIDATION: 'charisma',
INVESTIGATION: 'intelligence',
MEDICINE: 'wisdom',
NATURE: 'intelligence',
PERCEPTION: 'wisdom',
PERFORMANCE: 'charisma',
PERSUASION: 'charisma',
RELIGION: 'intelligence',
SLEIGHTOFHAND: 'dexterity',
STEALTH: 'dexterity',
SURVIVAL: 'wisdom',
};
const getIdOfRepeatingString = repString => repString.substring(repString.lastIndexOf('_') + 1);
const getSkillIdByStorageName = (data, repStrings, prop) => {
let returnId;
for (const repString of repStrings) {
if (data[`${repString}_storage_name`] === prop || data[`${repString}_storage_name`] === camelize(prop)) {
returnId = getIdOfRepeatingString(repString);
break;
}
}
return returnId;
};
generateSkills() {
getSetRepeatingItems('initialize.generateSkills', {
repeatingItems: ['repeating_skill'],
collectionArrayAddItems: ['storage_name', 'name', 'ability'],
callback: (data, repStrings) => {
Object.keys(SKILLS).forEach((skill) => {
let skillId = getSkillIdByStorageName(data, repStrings, skill);
if (!skillId) {
skillId = generateRowID();
}
const repString = `repeating_skill_${skillId}`;
data[`${repString}_storage_name`] = skill;
data[`${repString}_name`] = getTranslationByKey(skill);
data[`${repString}_ability`] = getFormattedAbility(SKILLS[skill]);
abilityChecks.updateSkill(skillId);
});
},
setFinalAttrsCallback: () => {
abilityChecks.updateMacro();
},
});
}
on('sheet:opened', () => {
this.generateSkills();
});