Updating...
đ Arcane Scribe
âī¸ Sync Now
âī¸ Setup
đ Bookshelf
Add
âŗ Mechanics
Max Pages
Hours/Level
Gold/Level
+
đ Cloud Configuration
Apps Script Web App URL
Connect
Copy Share Link
Paste code into
Extensions > Apps Script
:
const HEADERS = ["name", "level", "hours", "special", "completed", "notes"]; function doGet(e) { const ss = SpreadsheetApp.getActiveSpreadsheet(); let bookData = {}; ss.getSheets().forEach(s => { let data = s.getDataRange().getValues(); let spells = []; if(data.length > 1) { let headers = data[0]; for(let i=1; i
obj[h] = data[i][idx]); spells.push(obj); } } bookData[s.getName()] = spells; }); return ContentService.createTextOutput(JSON.stringify({books: bookData})).setMimeType(ContentService.MimeType.JSON); } function doPost(e) { try { const p = JSON.parse(e.postData.contents); if(p.action === 'saveData') { const ss = SpreadsheetApp.getActiveSpreadsheet(); Object.keys(p.books).forEach(name => { let s = ss.getSheetByName(name) || ss.insertSheet(name); s.clear(); let spells = p.books[name]; let rows = [HEADERS]; if(spells && spells.length > 0) { spells.forEach(spell => rows.push(HEADERS.map(h => spell[h] || ""))); } s.getRange(1, 1, rows.length, HEADERS.length).setValues(rows); }); return ContentService.createTextOutput(JSON.stringify({status: "success"})).setMimeType(ContentService.MimeType.JSON); } } catch(err) { return ContentService.createTextOutput(JSON.stringify({error: err.toString()})).setMimeType(ContentService.MimeType.JSON); } }
Close
Scribe Spell
1st Level
2nd Level
3rd Level
4th Level
5th Level
6th Level
7th Level
8th Level
9th Level
Cantrip
Hours Scribed
Specialty (Half Time/Gold)
Completed
Save
Cancel