This is a Google Apps Script Web App that, given a Google calendar and date range, provides a summary of the total hours and number of events during the range as well as details for each event.
The interface looks like this:
![]()
And the output looks like this:
![]()
- Time tracking: choose any calendar and date range to get totals and per-event detail (events marked "not billable" or "don't track" are skipped).
- Remembered inputs: optional toggles save your calendar selection, date range, and invoice fields locally for the next visit.
- Invoice Builder: turn a run into a branded invoice (with your business/client info, hourly rate, tax, accent colour, auto 14-day due date), then download as a PDF or per-page SVG. Multi-page invoices are handled automatically.
- Create a calendar for a project you're starting
- Each time you spend time on the project:
- Create a project calendar event
- Give it a descriptive title like "Initial project configuration"
- Set the duration to the amount of time you spent
- Use the NCBrewer Calendar Event Tracker weekly to review your time spent on the project
- Generate an invoice from the tracked period and send it to a client
- Run the time tracker for the calendar and dates you want to invoice (this enables the Invoice Builder).
- Fill in invoice details (IDs, hourly rate, tax), your business info, client info, contact, payment notes, and pick an accent colour.
- Click Generate invoice to preview; use Download PDF or Download SVG to export. Check "Remember invoice inputs" to reuse the same details next time (stored only in your browser).
Calendar data is processed by Google Apps Script and returned to the user's browser to summarize time. Invoice fields and exports are processed in the browser. Optional remembered inputs persist in browser storage. Operational logs record activity and success/failure indicators; Google supplies execution metadata. The surrounding website uses Google Analytics. See the Privacy Policy and Terms of Service once the prepared website changes are published.
Use the Time Tracker homepage to open the app. Removing Google's unverified-app warning requires OAuth verification; publishing these policy pages alone does not remove it. Normal user consent remains necessary after verification.
The verification checklist contains the console values, scope justification, demo recording outline, deployment checks, and account-owner steps. Website pages are prepared in /home/nathaniel/dev/website; they are not published by building this repository.
- This app is deployed with
executeAs: USER_ACCESSINGand useshttps://www.googleapis.com/auth/calendar.readonly. - Because the app reads each user's own calendars, first-time OAuth consent is required for each user and cannot be removed by creating a new release/deployment.
- Share the Web App
.../execURL from a deployment, not the Script ID or editor URL. Sharing the wrong URL will cause users to request project access. - If you need zero user consent, you must deploy as
USER_DEPLOYING(executeAs: ME) and read only the deployer's calendars (not each user's calendars).
-
Clone the repository
git clone https://github.com/NathanielBrewer/google-calendar-time-tracker.git cd google-calendar-time-tracker -
Install dependencies
npm install
-
Configure Google Apps Script
- Navigate to your Google Apps Script project and open the Project Settings
- Copy the Script ID and paste it into either the
devScriptId,prodScriptId, or thescriptIdvariable in the .clasp.json file located atsrc/.clasp.json - Adjust the appscript.json as needed. Documentation available here
-
Develop
- The entry file is
src/code.js. This gets built tobuild/<prod|dev>/code.gs, which is a runnable Google Apps Script file. - After making changes and any files in the
src/directory, abuild:<prod|dev>command must be run before those changes will be exectuable by Google Apps Script. - While developing, make your changes and then use
reload:<prod|dev>to run bothbuild:<prod|dev>andpush:<prod|dev>commands.
- The entry file is
-
Build
The build step is required to convert the files into a single Google Script file that can then be pushed and deployed to your Apps Script project.
Command:
npm run build:<prod|dev>
-
Push
Invoke
clasp pushfor either theprodordevscript IDnpm run push:<prod|dev>
-
Deploy
Invoke
clasp deployfor either theprodordevscript IDnpm run deploy:<prod|dev>
-
Reload
For faster development, build and push in one command
npm run reload:<prod|dev>