McRUN Attendance Documentation¶
About¶
Welcome to the McRUN Attendance codebase documentation. This project is a Google Apps Script-based solution designed to streamline attendance tracking for the McRUN club. It integrates with Google Sheets, Google Forms, and external tools to automate attendance submissions, formatting, and reporting.
The system also includes features for email notifications, data validation, and integration with the Points Ledger for tracking participation.
Files¶
- Github Repo: mcrun-attendance
- Google Sheets: Head Run Attendance - 2024-25
- Apps Script Project: Attendance Code 2024/25 (Accessible via Extensions > Apps Script in the Google Sheet)
Key Features¶
- Attendance Management: Automates the processing of attendance submissions from Google Forms and the McRUN app.
- Data Formatting: Ensures uniform formatting of names, headruns, and other attendance details.
- Email Notifications: Sends reminders and attendance copies to headrunners and club executives.
- Integration with Points Ledger: Transfers attendance data to a Points Ledger for tracking participation.
- Custom Menus: Provides a user-friendly interface in Google Sheets for executing scripts.
- Triggers and Scheduling: Automates tasks like checking for missing attendance and updating calendar-based triggers.
Note: This documentation is generated from a code search and may not include every function in the repository.
View all code on GitHub
Function Docs¶
This section provides a quick reference to all functions in the McRUN Attendance codebase. Click on a function name to jump to its detailed documentation.
# Formatting.gs ¶
- addMissingPlatform()
- toTitleCase()
- cleanSheetData()
- formatAllHeadRun()
- formatAllConfirmations()
- formatConfirmationInRow()
## addMissingPlatform() ¶
Adds 'Google Form' as a platform source for a row.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet (defaults to ATTENDANCE_SHEET.getLastRow())) | 
## toTitleCase() ¶
Converts a string to title case.
| Name | Type | Description | 
|---|---|---|
| inputString | String | The string to title | 
Output: String
## cleanSheetData() ¶
Runs all formatting functions for the sheet.
## formatAllHeadRun() ¶
Formats all headrun entries in the sheet.
## formatAllConfirmations() ¶
Formats all confirmation columns in the sheet.
## formatConfirmationInRow(row) ¶
Formats confirmation as a user-friendly string.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet. Default: ATTENDANCE_SHEET.getLastRow() | 
# HeadRun-Attendance.gs ¶
- onFormSubmission()
- onFormSubmissionInRow()
- onAppSubmission()
- bulkFormatting()
- transferAndFormat()
- getLastSubmission()
## onFormSubmission() ¶
Runs after form submission; sorts, processes, transfers, and formats the new entry.
## onFormSubmissionInRow() ¶
Executes post-form-submission logic for a specific row.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet (1-index) | 
## onAppSubmission() ¶
Processes app-based attendance submissions.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet (1-index). Defaults to ATTENDANCE_SHEET.getLastRow() | 
## bulkFormatting() ¶
Bulk-formats a row: confirmation and names.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet | 
## transferAndFormat() ¶
Transfers a row to the Points Ledger, triggers formatting.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet | 
## getLastSubmission() ¶
Finds the last non-empty row in the attendance sheet.
| Name | Type | Description | 
|---|---|---|
| sheet | Sheet | (Optional) Target sheet object. Defaults to GET_ATTENDANCE_SHEET() | 
Output: Integer (1-indexed row number)
# Headrun-Info.gs ¶
- storeObject(key, obj)-> Stores object in GAS document properties.
- getAllHeadruns()
- getAllHeadrunners()
- getWeekday()
- getScheduleFromStore()
- getMatchedTimeKey()
## storeObject() ¶
Stores obj in the document properties under key.
| Name | Type | Description | 
|---|---|---|
| key | String | Property key | 
| obj | Object | Object to store | 
## getAllHeadruns() ¶
Returns all stored headruns.
## getAllHeadrunners() ¶
Returns all stored headrunners.
## getWeekday() ¶
Returns day string for the given index.
| Name | Type | Description | 
|---|---|---|
| weekdayIndex | Integer | 0=Sunday, 6=Saturday | 
## getScheduleFromStore() ¶
Returns run schedule for the specified weekday.
| Name | Type | Description | 
|---|---|---|
| currentWeekday | String | Int | 
## getMatchedTimeKey() ¶
Finds the time key in runSchedule matching submission time ± offset.
| Name | Type | Description | 
|---|---|---|
| submissionDate | Date | Date of the submission | 
| runSchedule | Object | Schedule object | 
| offsetHours | Integer | Offset window in hours (default 2) | 
# Import.gs ¶
## processImportFromApp(importObj) ¶
Processes the latest attendance submission imported via the McRUN app.
Verifies if the import is JSON or multi-column, appends to the import sheet, processes and transfers to semester sheet, and triggers post-import logic.
| Name | Type | Description | 
|---|---|---|
| importObj | String (JSON) | JSON string of the attendance submission | 
Output: None (side effects: rows added, triggers post-import)
Pitfalls: Import must be a valid JSON string; malformed data will throw.  
## transferLastImport() ¶
Transfers the last imported attendance submission (from Import Sheet) to the semester sheet.
| Name | Type | Description | 
|---|---|---|
| — | — | No parameters | 
Output: None (side effects: submission transferred)
Pitfalls: Only for use with valid import rows.
## transferThisRow(row) ¶
Helper to transfer a specific row from the import sheet to the semester sheet.
| Name | Type | Description | 
|---|---|---|
| row | Integer | The row number in the import sheet to process | 
Output: None.
Pitfalls: Row must contain valid JSON string.
# Points-Ledger.gs ¶
- appendMemberEmail(row, registered, unregistered) -> Appends member emails to attendee names in a row.
- transferSubmissionToLedger(row)-> Transfers a submission to the Points Ledger.
## appendMemberEmail() ¶
Appends member emails to attendee names in a row.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet | 
| registered | String[][] | Registered attendees/emails | 
| unregistered | String[][] | Unregistered attendees | 
## transferSubmissionToLedger() ¶
Transfers a submission to the Points Ledger.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in attendance sheet (default: getLastSubmission()) | 
# Triggers.gs ¶
- updateWeeklyCalendarTriggers()
- addSingleEventTrigger()
- createDailyAttendanceTrigger()
- getStartOfDay()
## updateWeeklyCalendarTriggers() ¶
Adds/removes time-based triggers for events, ensures correct calendar is used.
## addSingleEventTrigger() ¶
Adds a trigger for all events today.
## createDailyAttendanceTrigger() ¶
Creates time-based triggers for all relevant events in the current week.
## getStartOfDay() ¶
Returns start-of-day for a given date.
| Name | Type | Description | 
|---|---|---|
| date | Date | The date object | 
Output: Date (start of the given day)
# Unregistered.gs ¶
## getAllUnregisteredMembers() ¶
Runs the unregistered member check for all rows in the attendance sheet.
| Name | Type | Description | 
|---|---|---|
| — | — | No parameters | 
## getUnregisteredMembersInRow(row) ¶
Finds attendees in a specific row who are unregistered, sets in the NOT_FOUND_COL, and appends emails to registered attendees.
| Name | Type | Description | 
|---|---|---|
| row | Integer | Row in the attendance sheet (1-indexed). Default: ATTENDANCE_SHEET.getLastRow() | 
Output: None; side effects on sheet.
# User-Menu.gs ¶
## logMenuAttempt() ¶
Logs a user's attempt to use the custom menu.
| Name | Type | Description | 
|---|---|---|
| String | Email address of the active user. Defaults to empty string. | 
## onOpen() ¶
Creates the custom menu in the spreadsheet UI.
## helpUI() ¶
Displays a help message for the custom menu.
Triggers¶
- Form Submission: Set up a trigger for onFormSubmission(From form).
- App Submission: Set up a trigger for onAppSubmission(From event or manual).
- Scheduled Checks:
- Use time-driven triggers (e.g., weekly, daily) for functions like updateWeeklyCalendarTriggers.
- Calendar event-based triggers for event-driven attendance checks.
Troubleshooting¶
Common Issues¶
| Issue/Error | Cause | Solution | 
|---|---|---|
| "Exception: No permission" | Not authorized | Ensure proper account and OAuth scopes | 
| "Cannot read property 'getRange' of null" | Sheet name or ID is wrong | Double-check constants in Attendance-Variables.gs | 
| "Trigger not firing" | Trigger not set up | Manually add the trigger in Apps Script UI | 
| "Malformed JSON" | Import data is not valid JSON | Validate data before import | 
FAQ¶
Q: How do I add a new admin?
A: Add their email to PERM_USER_ in User-Menu.gs.
Q: How do I change the active semester?
A: Update ATTENDANCE_SHEET_NAME and related constants in Attendance-Variables.gs.
Q: Where are attendance logs stored?
A: In the Points Ledger Google Sheet (see constants).