Skip to content

Commit

Permalink
178 optional tracking (#207)
Browse files Browse the repository at this point in the history
* New sheet tracking setting set up

* feat: google sheet tracking is optional

* feat: tracking disabled for default sheet

* Chore: Specify types

I noticed that the types weren't specified in some other parts of the code so I specified the types in both places.

* fix: errors for changing google sheet to default and displaying its id

* Formatting: ran `npm run formart`

---------

Co-authored-by: KMMineCube <63953483+KaoushikMurugan@users.noreply.github.com>
  • Loading branch information
hansonguyen and KaoushikMurugan committed Dec 30, 2023
1 parent d3375c2 commit d18d807
Show file tree
Hide file tree
Showing 15 changed files with 174 additions and 63 deletions.
81 changes: 49 additions & 32 deletions src/attending-server/base-attending-server.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,32 @@
/** @module AttendingServerV2 */
import {
BaseMessageOptions,
CategoryChannel,
ChannelType,
Collection,
Guild,
GuildMember,
BaseMessageOptions,
TextChannel,
VoiceState,
ChannelType,
Role,
Snowflake
Snowflake,
TextChannel,
VoiceState
} from 'discord.js';
import type { Logger } from 'pino';
import { environment } from '../environment/environment-manager.js';
import { ServerExtension } from '../extensions/extension-interface.js';
import { GoogleSheetServerExtension } from '../extensions/google-sheet-logging/google-sheet-server-extension.js';
import { CalendarServerExtension } from '../extensions/session-calendar/calendar-server-extension.js';
import { LOGGER } from '../global-states.js';
import { AutoClearTimeout, HelpQueue } from '../help-queue/help-queue.js';
import { EmbedColor, SimpleEmbed } from '../utils/embed-helper.js';
import {
AccessLevelRole,
accessLevelRoleConfigs,
AccessLevelRoleIds
AccessLevelRoleIds,
accessLevelRoleConfigs
} from '../models/access-level-roles.js';
import { Helpee, Helper } from '../models/member-states.js';
import { ServerExtension } from '../extensions/extension-interface.js';
import { GoogleSheetServerExtension } from '../extensions/google-sheet-logging/google-sheet-server-extension.js';
import {
// it is used idk why it complains
// eslint-disable-next-line @typescript-eslint/no-unused-vars
useSettingsBackup,
loadExternalServerData,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
useFullBackup,
backupQueueData
} from './firebase-backup.js';
import { QueueBackup, ServerBackup } from '../models/backups.js';
import { Helpee, Helper } from '../models/member-states.js';
import { blue, green, red } from '../utils/command-line-colors.js';
import {
convertMsToTime,
isCategoryChannel,
isQueueTextChannel,
isTextChannel,
isVoiceChannel
} from '../utils/util-functions.js';
import { EmbedColor, SimpleEmbed } from '../utils/embed-helper.js';
import {
CategoryChannelId,
GuildId,
Expand All @@ -50,18 +38,30 @@ import {
SpecialRoleValues,
WithRequired
} from '../utils/type-aliases.js';
import { environment } from '../environment/environment-manager.js';
import {
convertMsToTime,
isCategoryChannel,
isQueueTextChannel,
isTextChannel,
isVoiceChannel
} from '../utils/util-functions.js';
import { ExpectedServerErrors } from './expected-server-errors.js';
import { RoleConfigMenuForServerInit } from './server-settings-menus.js';
import {
backupQueueData,
loadExternalServerData,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
useFullBackup,
// it is used idk why it complains
// eslint-disable-next-line @typescript-eslint/no-unused-vars
useSettingsBackup
} from './firebase-backup.js';
import {
initializationCheck,
sendInvite,
setHelpChannelVisibility,
updateCommandHelpChannels
} from './guild-actions.js';
import { CalendarServerExtension } from '../extensions/session-calendar/calendar-server-extension.js';
import { LOGGER } from '../global-states.js';
import type { Logger } from 'pino';
import { RoleConfigMenuForServerInit } from './server-settings-menus.js';

/**
* Wrapper for TextChannel
Expand All @@ -85,6 +85,8 @@ type ServerSettings = {
autoGiveStudentRole: boolean;
/** Prompt modal asking for help topic when a user joins a queue */
promptHelpTopic: boolean;
/** Track data in Google sheet if true */
sheetTracking: boolean;
/**
* Role IDs are always snowflake strings (i.e. they are strings that only consist of numbers)
* @see https://discord.com/developers/docs/reference#snowflakes
Expand Down Expand Up @@ -134,6 +136,7 @@ class AttendingServer {
afterSessionMessage: '',
autoGiveStudentRole: false,
promptHelpTopic: true,
sheetTracking: false,
accessLevelRoleIds: {
botAdmin: SpecialRoleValues.NotSet,
staff: SpecialRoleValues.NotSet,
Expand Down Expand Up @@ -214,6 +217,11 @@ class AttendingServer {
return this.settings.promptHelpTopic;
}

/** Track data in Google sheet if true */
get sheetTracking(): boolean {
return this.settings.sheetTracking;
}

/** Auto clear values of a queue, undefined if not set */
get queueAutoClearTimeout(): Optional<AutoClearTimeout> {
return this._queues.first()?.timeUntilAutoClear;
Expand Down Expand Up @@ -1034,6 +1042,15 @@ class AttendingServer {
this.settings.promptHelpTopic = promptHelpTopic;
}

/**
* Sets the internal boolean value for sheetTracking
* @param sheetTracking
*/
@useSettingsBackup
async setSheetTracking(sheetTracking: boolean): Promise<void> {
this.settings.sheetTracking = sheetTracking;
}

/**
* Sets up queue auto clear for this server
* @param hours the number of hours to wait before clearing the queue
Expand Down
16 changes: 9 additions & 7 deletions src/attending-server/firebase-backup.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/** @module FirebaseServerBackup */
import util from 'util';
import { FrozenServer } from '../extensions/extension-utils.js';
import { LOGGER, client, firebaseDB } from '../global-states.js';
import { HelpQueue } from '../help-queue/help-queue.js';
import { QueueBackup, ServerBackup, serverBackupSchema } from '../models/backups.js';
import { SimpleLogEmbed } from '../utils/embed-helper.js';
import { Optional } from '../utils/type-aliases.js';
import { client, firebaseDB, LOGGER } from '../global-states.js';
import { FrozenServer } from '../extensions/extension-utils.js';
import { HelpQueue } from '../help-queue/help-queue.js';
import { AttendingServer } from './base-attending-server.js';
import util from 'util';

/**
* Loads the backup data in firebase given a server id
Expand Down Expand Up @@ -40,6 +40,7 @@ async function loadExternalServerData(serverId: string): Promise<Optional<Server
timeStamp: new Date(unpack.data.timeStamp._seconds * 1000),
autoGiveStudentRole: unpack.data.autoGiveStudentRole ?? false,
promptHelpTopic: unpack.data.promptHelpTopic ?? false,
sheetTracking: unpack.data.sheetTracking ?? false,
staffRoleId: unpack.data.staffRoleId ?? unpack.data.helperRoleId ?? 'Not Set', // !Migration code
timezone: unpack.data.timezone ?? {
sign: '-',
Expand Down Expand Up @@ -78,6 +79,7 @@ function fullServerBackup(server: FrozenServer): void {
studentRoleId: server.studentRoleID,
autoGiveStudentRole: server.autoGiveStudentRole,
promptHelpTopic: server.promptHelpTopic,
sheetTracking: server.sheetTracking,
timezone: server.timezone
};
firebaseDB
Expand Down Expand Up @@ -280,9 +282,9 @@ function useQueueBackup(
}

export {
backupQueueData,
loadExternalServerData,
useSettingsBackup,
useQueueBackup,
useFullBackup,
backupQueueData
useQueueBackup,
useSettingsBackup
};
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const ExpectedSheetErrors = {
badGoogleSheetId: new GoogleSheetConnectionError(
`YABOB cannot access this google sheet. Make sure you share the google sheet with this YABOB's email: \`${environment.googleCloudCredentials.client_email}\``
),
defaultGoogleSheetId: new GoogleSheetConnectionError(
'YABOB cannot write to this public sheet. Please use a different google sheet.'
),
noDataYet: (type: 'Help Session' | 'Attendance') =>
new CommandParseError(
`There are no rows in the ${type} sheet yet. Try running this command again after a ${type.toLowerCase()} entry has been written.`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ enum GoogleSheetCommandNames {
}

enum GoogleSheetButtonNames {
UpdateSheetTrackingStatus = 'UpdateSheetTrackingStatus',
ResetGoogleSheetSettings = 'ResetGoogleSheetSettings',
ShowGoogleSheetSettingsModal = 'ShowGoogleSheetSettingsModal'
}
Expand All @@ -20,4 +21,4 @@ type AllEnumsCorrect = EnsureCorrectEnum<typeof GoogleSheetCommandNames> &
EnsureCorrectEnum<typeof GoogleSheetButtonNames> &
EnsureCorrectEnum<typeof GoogleSheetModalNames>; // checks if all names and values are the same

export { GoogleSheetCommandNames, GoogleSheetButtonNames, GoogleSheetModalNames };
export { GoogleSheetButtonNames, GoogleSheetCommandNames, GoogleSheetModalNames };
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { buildComponent } from '../../../utils/component-id-factory.js';
import { GoogleSheetExtensionState } from '../google-sheet-states.js';
import { GoogleSheetModalNames } from './google-sheet-interaction-names.js';
import { environment } from '../../../environment/environment-manager.js';

/**
* Sets the Google Sheet URL for the server
Expand All @@ -34,7 +35,12 @@ function googleSheetSettingsModal(serverId: Snowflake, useMenu = false): ModalBu
.setPlaceholder('Enter Google Sheet ID')
.setStyle(TextInputStyle.Paragraph)
.setRequired(true)
.setValue(state?.googleSheet.spreadsheetId ?? '')
.setValue(
state?.googleSheet.spreadsheetId !==
environment.googleSheetLogging.YABOB_GOOGLE_SHEET_ID
? state?.googleSheet.spreadsheetId ?? ''
: ''
)
)
);
return modal;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from 'discord.js';
import {
APIEmbedField,
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
EmbedBuilder
} from 'discord.js';
import { SettingsSwitcher } from '../../../attending-server/server-settings-menus.js';
import { environment } from '../../../environment/environment-manager.js';
import { buildComponent } from '../../../utils/component-id-factory.js';
import { EmbedColor } from '../../../utils/embed-helper.js';
import { SettingsMenuOption, YabobEmbed } from '../../../utils/type-aliases.js';
import { FrozenServer } from '../../extension-utils.js';
import { GoogleSheetExtensionState } from '../google-sheet-states.js';
import { SettingsSwitcher } from '../../../attending-server/server-settings-menus.js';
import { buildComponent } from '../../../utils/component-id-factory.js';
import { GoogleSheetButtonNames } from './google-sheet-interaction-names.js';
import { environment } from '../../../environment/environment-manager.js';

/**
* Options for the server settings main menu
Expand Down Expand Up @@ -37,6 +43,18 @@ function GoogleSheetSettingsConfigMenu(
throw new Error('Google Sheet Logging state for this server was not found');
}

const currentSheet: APIEmbedField = {
name: 'Current Google Sheet',
value: ''
};

if (server.sheetTracking) {
currentSheet.value = `[Google Sheet Link](${state.googleSheetURL})\nSheet Name: ${state.googleSheet.title}\nTracking enabled`;
} else {
currentSheet.value =
'Tracking disabled. Enable tracking or set a new Google sheet to track hours.';
}

const embed = new EmbedBuilder()
.setTitle(`📊 Google Sheet Logging Configuration for ${server.guild.name} 📊`)
.setColor(EmbedColor.Aqua)
Expand All @@ -49,17 +67,28 @@ function GoogleSheetSettingsConfigMenu(
name: 'Documentation',
value: `[Learn more about Google Sheet Logging settings here.](https://github.com/KaoushikMurugan/yet-another-better-office-hour-bot/wiki/Configure-YABOB-Settings-For-Your-Server#google-sheet-settings)`
},
{
name: 'Current Google Sheet',
value: `[Google Sheet Link](${state.googleSheetURL})\nSheet Name: ${state.googleSheet.title}`
}
currentSheet
);

if (updateMessage.length > 0) {
embed.setFooter({ text: `✅ ${updateMessage}` });
}

const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
buildComponent(new ButtonBuilder(), [
isDm ? 'dm' : 'other',
GoogleSheetButtonNames.UpdateSheetTrackingStatus,
server.guild.id
])
.setEmoji(`${!server.sheetTracking ? '✔️' : '✖️'}`)
.setLabel(
`${!server.sheetTracking ? 'Enable' : 'Disable'} Google Sheet Tracking`
)
.setStyle(ButtonStyle.Secondary)
.setDisabled(
state.googleSheet.spreadsheetId ===
environment.googleSheetLogging.YABOB_GOOGLE_SHEET_ID
),
buildComponent(new ButtonBuilder(), [
isDm ? 'dm' : 'other',
GoogleSheetButtonNames.ShowGoogleSheetSettingsModal,
Expand All @@ -84,4 +113,4 @@ function GoogleSheetSettingsConfigMenu(
};
}

export { googleSheetSettingsMainMenuOptions, GoogleSheetSettingsConfigMenu };
export { GoogleSheetSettingsConfigMenu, googleSheetSettingsMainMenuOptions };
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ const GoogleSheetSuccessMessages = {
SimpleEmbed(
`Successfully changed to this new google sheet: ${newSheetTitle}`,
EmbedColor.Success
),
updatedSheetTracking: (newTrackingStatus: boolean): YabobEmbed =>
SimpleEmbed(
`Successfully ${
newTrackingStatus ? 'enabled' : 'disabled'
} google sheet tracking`,
EmbedColor.Success
)
} as const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class GoogleSheetServerExtension extends BaseServerExtension implements ServerEx
}

this.attendanceEntries.push({ ...activeTimeEntry, ...helper });
if (!this.attendanceUpdateIsScheduled) {
if (_server.sheetTracking && !this.attendanceUpdateIsScheduled) {
// if nothing is scheduled, start a timer
// otherwise the existing timer will update this entry
// so no need to schedule another one
Expand Down
Loading

0 comments on commit d18d807

Please sign in to comment.