Apps Script Development
Use the bkper-gs library to build Bkper automations that run inside Google's serverless Apps Script platform — scheduled jobs, spreadsheet triggers, custom add-ons, and workflows that combine Bkper with Sheets, Drive, and Gmail.
Google Apps Script is Google’s serverless platform for extending Google Workspace. With the bkper-gs library, you can build Bkper automations that run inside Google’s infrastructure — no servers, no deployment pipeline, and native access to Sheets, Drive, Calendar, and Gmail.
When to use Apps Script
Use Apps Script when your automation lives in the Google Workspace ecosystem:
- Scheduled jobs that read from or write to Google Sheets
- Spreadsheet triggers (on-edit, on-form-submit) that record transactions
- Custom add-ons distributed to a team or domain
- Workflows that combine Bkper with other Google services (Drive, Calendar, Gmail)
If you need real-time event handling, a web UI, or automation that runs outside Google Workspace, use Node.js scripts or a platform app instead.
Setup
Add the library
bkper-gs is published as an Apps Script library. To add it to your script:
- Open your script in the Apps Script editor
- Click Resources → Libraries
- In the “Add a Library” field, enter the Script ID:
1hMJszJGSUVZDB3vmsWrUZfRhY1UWbhS0SQ6Lzl06gm1zhBF3ioTM7mpJ
- Choose the latest version and click Save
The BkperApp global is now available in your script.
TypeScript definitions
For TypeScript development with autocomplete, install the type definitions:
npm i -S @bkper/bkper-gs-typesConfigure tsconfig.json:
{ "compilerOptions": { "typeRoots": ["node_modules/@bkper", "node_modules/@types"] }}See Develop Apps Script using TypeScript and use clasp to push TypeScript projects to Apps Script.
The BkperApp entry point
BkperApp works the same way as CalendarApp, DocumentApp, and SpreadsheetApp — it’s a global entry point that follows familiar Apps Script conventions.
The book ID comes from the URL when you open a book at bkper.com:
// Get a book by its ID (from the URL)const book = BkperApp.getBook('agtzfmJrcGVyLWhyZHIOCxIGTGVkZ2VyGNKJAgw');Common patterns
Get a book
function getBookName() { const book = BkperApp.getBook('agtzfmJrcGVyLWhyZHIOCxIGTGVkZ2VyGNKJAgw'); Logger.log(book.getName());}Record a transaction
function recordTransaction() { const book = BkperApp.getBook('agtzfmJrcGVyLWhyZHIOCxIGTGVkZ2VyGNKJAgw'); book.record('#gas 63.23');}Transactions use the same shorthand syntax you’d use in the Bkper UI.
Batch record transactions
For bulk operations, pass an array. The library sends all records in a single API call — important for avoiding Apps Script execution time limits:
function importExpenses() { const book = BkperApp.getBook('agtzfmJrcGVyLWhyZHIOCxIGTGVkZ2VyGNKJAgw');
const transactions = [ '#breakfast 15.40', '#lunch 27.45', '#dinner 35.86', ];
book.record(transactions);}Query transactions
The getTransactions() method returns a TransactionIterator for handling large datasets without loading everything into memory:
function listTransactions() { const book = BkperApp.getBook('agtzfmJrcGVyLWhyZHIOCxIGTGVkZ2VyGNKJAgw');
const iterator = book.getTransactions("account:'Bank' after:01/01/2024");
while (iterator.hasNext()) { const transaction = iterator.next(); Logger.log(transaction.getDescription()); }}See Querying Transactions for the full query syntax.
List accounts with balances
function listAccountBalances() { const book = BkperApp.getBook('agtzfmJrcGVyLWhyZHIOCxIGTGVkZ2VyGNKJAgw');
const accounts = book.getAccounts(); for (const account of accounts) { if (account.isPermanent() && account.isActive()) { Logger.log(`${account.getName()}: ${account.getBalance()}`); } }}Building triggers
Apps Script triggers let your automation run on a schedule or respond to spreadsheet events — without any always-on infrastructure.
Time-based (scheduled)
function setupDailySync() { ScriptApp.newTrigger('syncTransactions') .timeBased() .everyDays(1) .atHour(6) .create();}
function syncTransactions() { const book = BkperApp.getBook('YOUR_BOOK_ID'); const sheet = SpreadsheetApp.openById('YOUR_SHEET_ID').getActiveSheet();
// Read rows from Sheets, record to Bkper const rows = sheet.getDataRange().getValues(); const transactions = rows.slice(1).map(row => `${row[0]} ${row[1]} ${row[2]}`); book.record(transactions);}Spreadsheet edit trigger
function onEdit(e) { const sheet = e.source.getActiveSheet(); if (sheet.getName() !== 'Expenses') return;
const row = e.range.getRow(); const amount = sheet.getRange(row, 3).getValue(); const description = sheet.getRange(row, 2).getValue();
if (amount && description) { const book = BkperApp.getBook('YOUR_BOOK_ID'); book.record(`${description} ${amount}`); }}TypeScript development workflow
For non-trivial scripts, use clasp for local development with TypeScript:
# Install claspnpm install -g @google/clasp
# Log inclasp login
# Clone an existing scriptclasp clone <scriptId>
# Push changesclasp push
# Watch for changesclasp push --watchWith @bkper/bkper-gs-types configured, your editor provides full autocomplete for BkperApp, Book, Transaction, Account, and all other bkper-gs types.
API reference
The complete bkper-gs reference is at bkper.com/docs/bkper-gs.
Related
- Building Sheets Integrations — Custom Sheets automations with bkper-gs
- Node.js Scripts — When you need automation outside Google Workspace
- Guides → Google Sheets Add-on — End-user guide for recording and fetching data with the Bkper add-on