From 42eeefe819d06a607cb103444842052afc57fdf3 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Thu, 25 Dec 2025 02:09:15 -0800 Subject: [PATCH 01/11] fix typo RegisteGithubCronJob --- jobs/github.go | 2 +- main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jobs/github.go b/jobs/github.go index 980ace5..6af8aaa 100644 --- a/jobs/github.go +++ b/jobs/github.go @@ -9,7 +9,7 @@ import ( cron "github.com/robfig/cron/v3" ) -func RegisteGithubCronJob() { +func RegisterGithubCronJob() { if config.Env != "PROD" { utils.SugarLogger.Infoln("Github CRON Job not registered because environment is not PROD") return diff --git a/main.go b/main.go index c2e6f15..45271b0 100644 --- a/main.go +++ b/main.go @@ -26,7 +26,7 @@ func main() { commands.InitializeDiscordBot() jobs.RegisterDriveCronJob() - jobs.RegisteGithubCronJob() + jobs.RegisterGithubCronJob() jobs.RegisterDiscordCronJob() router := controller.SetupRouter() From d87c3f7f727c2e9f0f2fbb5a78fb8baac2b51832 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 01:23:01 -0800 Subject: [PATCH 02/11] add team member role id in config --- config/config.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 7e927b5..794d66e 100644 --- a/config/config.go +++ b/config/config.go @@ -35,7 +35,8 @@ var AdminRoleID = "1030681203864522823" var OfficerRoleID = "812948550819905546" var LeadRoleID = "970423652791246888" var SpecialAdvisorRoleID = "1386909324596609034" -var MemberRoleID = "1334383074410237984" +var TeamMemberRoleID = "1456575818460430522" +var MemberRoleID = "1334383074410237984" // this is actually the Discord Role ID for "verified" role var AlumniRoleID = "817577502968512552" var BotRoleID = "1229611357259694132" From dd90a0ac5b97cc51ad45dd3244796170fd612047 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 01:27:23 -0800 Subject: [PATCH 03/11] add team member role to Sync service --- service/role_service.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/service/role_service.go b/service/role_service.go index 1faeba0..38a597e 100644 --- a/service/role_service.go +++ b/service/role_service.go @@ -84,6 +84,8 @@ func SyncDiscordRolesForUser(userID string, roleIds []string) { roles = append(roles, "d_lead") } else if id == config.SpecialAdvisorRoleID { roles = append(roles, "d_special_advisor") + } else if id == config.TeamMemberRoleID { + roles = append(roles, "d_team_member") } else if id == config.MemberRoleID { roles = append(roles, "d_member") } else if id == config.AlumniRoleID { From bb994170f1c644b4369f69bc0a821699210298ea Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 01:28:14 -0800 Subject: [PATCH 04/11] update user model helper functions --- model/user.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/model/user.go b/model/user.go index 594683c..1e26686 100644 --- a/model/user.go +++ b/model/user.go @@ -58,6 +58,9 @@ func (user User) GetHighestRole() string { if user.IsSpecialAdvisor() { return "d_special_advisor" } + if user.IsTeamMember() { + return "d_team_member" + } if user.IsMember() { return "d_member" } @@ -96,6 +99,10 @@ func (user User) IsInnerCircle() bool { return user.IsAdmin() || user.IsOfficer() || user.IsLead() || user.IsSpecialAdvisor() } +func (user User) IsTeamMember() bool { + return user.HasRole("d_team_member") +} + func (user User) IsMember() bool { return user.HasRole("d_member") } From 89e46a34efac277047c935158a9c1927d5b19f69 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 02:03:05 -0800 Subject: [PATCH 05/11] update populate recovery function --- service/discord_service.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/service/discord_service.go b/service/discord_service.go index 191ddb2..1ceac7e 100644 --- a/service/discord_service.go +++ b/service/discord_service.go @@ -405,6 +405,11 @@ func PopulateDiscordMembers() { if err != nil { utils.SugarLogger.Errorf("Error adding role to user %s: %s", user.Email, err.Error()) } + } else if user.HasRole("d_team_member") { + err := Discord.GuildMemberRoleAdd(config.DiscordGuild, user.ID, config.TeamMemberRoleID) + if err != nil { + utils.SugarLogger.Errorf("Error adding role to user %s: %s", user.Email, err.Error()) + } } else if user.HasRole("d_officer") { err := Discord.GuildMemberRoleAdd(config.DiscordGuild, user.ID, config.OfficerRoleID) if err != nil { From 488287bdf2f239bff7bf4bc5ef4803cf0abb5969 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 02:03:50 -0800 Subject: [PATCH 06/11] update Update callback function --- commands/handler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/handler.go b/commands/handler.go index 9cf1545..46ca0cb 100644 --- a/commands/handler.go +++ b/commands/handler.go @@ -159,8 +159,8 @@ func OnGuildMemberUpdate(s *discordgo.Session, m *discordgo.GuildMemberUpdate) { utils.SugarLogger.Infof("Removed all subteam roles from user %s (%s) as they are alumni", m.User.ID, m.Nick) service.SendMessage(config.DiscordLogChannel, fmt.Sprintf("Removed all subteam roles from user %s (%s) as they are alumni", m.User.ID, m.Nick)) - // User cannot have member, lead, or officer roles if they are alumni (admin and special advisor ok) - removeRoles := []string{config.MemberRoleID, config.LeadRoleID, config.OfficerRoleID} + // User cannot have member, team member, lead, or officer roles if they are alumni (admin and special advisor ok) + removeRoles := []string{config.MemberRoleID, config.TeamMemberRoleID, config.LeadRoleID, config.OfficerRoleID} for _, role := range removeRoles { err := service.Discord.GuildMemberRoleRemove(config.DiscordGuild, m.User.ID, role) if err != nil { From 81c3d4c2a3ba75b6949dfa40f6d3a1055adba339 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 11:32:16 -0800 Subject: [PATCH 07/11] add team member sheet id --- config/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/config/config.go b/config/config.go index 794d66e..7695118 100644 --- a/config/config.go +++ b/config/config.go @@ -50,6 +50,7 @@ var RsaPrivateKeyString = os.Getenv("RSA_PRIVATE_KEY") var MemberDirectorySheetID = "1reuLZox2daj8r2H-lZrwB4oFPYlJ6oC7983UUaZd6AY" var MailingListSheetID = "1O5KQzpOo9Ja4Vg55TGCyc3uUDZFvHjyhZqw4Eh1SKVY" +var TeamMemberMasterListSheetID = "1tKawKKq1jk-WN8WM8gGkwOeEc0IA6-pkKxHL1DcWzd0" var DriveCron = os.Getenv("DRIVE_CRON") var GithubCron = os.Getenv("GITHUB_CRON") From df059622960bd346253e47c7eae127dc4637025a Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 11:32:38 -0800 Subject: [PATCH 08/11] add team member drive service and job --- jobs/drive.go | 6 +++- service/drive_service.go | 71 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/jobs/drive.go b/jobs/drive.go index cdcf18f..a8f8412 100644 --- a/jobs/drive.go +++ b/jobs/drive.go @@ -20,7 +20,7 @@ func RegisterDriveCronJob() { _, _ = service.Discord.ChannelMessageSend(config.DiscordLogChannel, ":alarm_clock: Starting google drive CRON Job") utils.SugarLogger.Infoln("Starting google drive CRON Job...") var wg sync.WaitGroup - wg.Add(5) + wg.Add(6) go func() { defer wg.Done() service.PopulateMemberDirectorySheet() @@ -41,6 +41,10 @@ func RegisterDriveCronJob() { defer wg.Done() service.CleanLeadsDriveMembers() }() + go func() { + defer wg.Done() + service.UpdateTeamMembers() + }() wg.Wait() // utils.SugarLogger.Infoln("Finished google drive cleanup, running PopulateDriveMembers...") // _, _ = service.Discord.ChannelMessageSend(config.DiscordLogChannel, "Finished google drive cleanup, running PopulateDriveMembers...") diff --git a/service/drive_service.go b/service/drive_service.go index fcde695..ae84e5d 100644 --- a/service/drive_service.go +++ b/service/drive_service.go @@ -604,3 +604,74 @@ func PopulateMailingListSheet() { externalMailingListEntries := GetExternalMailingListEntries() populateMailingListSheet("External", externalMailingListEntries) } + +// UpdateTeamMembers checks the Team Members google sheet and gives the Team Member Discord role to all users with a TRUE cell +func UpdateTeamMembers() { + spreadsheet, err := SheetClient.Spreadsheets.Get(config.TeamMemberMasterListSheetID).Do() + + sheetName := "New Members" + if err != nil { + utils.SugarLogger.Errorf("Unable to get spreadsheet: %v", err) + return + } + + sheetId := -1 + for _, sheet := range spreadsheet.Sheets { + if sheet.Properties.Title == sheetName { + utils.SugarLogger.Infof("Found sheet %s with ID %v", sheet.Properties.Title, sheet.Properties.SheetId) + sheetId = int(sheet.Properties.SheetId) + break + } + } + if sheetId == -1 { + utils.SugarLogger.Errorf("Sheet %s not found", sheetName) + return + } + + readRange := fmt.Sprintf("'%s'!A:H", sheetName) + resp, err := SheetClient.Spreadsheets.Values.Get(config.TeamMemberMasterListSheetID, readRange).Do() + if err != nil { + utils.SugarLogger.Errorf("Unable to read sheet: %v", err) + return + } + + var emails []string + for i, row := range resp.Values { + // Skip column names + if i == 0 { + continue + } + + // Skip rows that aren't filled until column H + if len(row) < 8 { + continue + } + + // Check if column H is TRUE + if hValue, ok := row[7].(string); ok && hValue == "TRUE" { + if email, ok := row[1].(string); ok && email != "" { + emails = append(emails, email) + } + } + } + count := 0 + for _, email := range emails { + user := GetUserByEmail(email) + + if user.ID == "" { + continue + } + if user.IsAlumni() || user.IsTeamMember() || !user.IsMember() { + continue + } + utils.SugarLogger.Infof("Updating %s with Team Member role", email) + err := Discord.GuildMemberRoleAdd(config.DiscordGuild, user.ID, config.TeamMemberRoleID) + if err != nil { + utils.SugarLogger.Errorln("Error adding role, ", err) + continue + } + count++ + } + utils.SugarLogger.Infof("Gave %d users the Team Member role", count) + SendMessage(config.DiscordLogChannel, fmt.Sprintf("Gave %d users the Team Member role", count)) +} From dc3992290826a89d67ceea4bd9c176a31489d972 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 11:35:06 -0800 Subject: [PATCH 09/11] version bump --- config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 7695118..a46d821 100644 --- a/config/config.go +++ b/config/config.go @@ -5,7 +5,7 @@ import ( "os" ) -var Version = "4.5.8" +var Version = "4.5.9" var Env = os.Getenv("ENV") var Port = os.Getenv("PORT") var Prefix = os.Getenv("PREFIX") From 0dcd2c5c68d729f5001dba7199d6d0bea53e6869 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 11:43:37 -0800 Subject: [PATCH 10/11] update users command --- commands/users.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/commands/users.go b/commands/users.go index 048c1c5..45a3c5b 100644 --- a/commands/users.go +++ b/commands/users.go @@ -39,6 +39,7 @@ func Users(args []string, s *discordgo.Session, m *discordgo.MessageCreate) { officerMembers := 0 specialAdvisorMembers := 0 alumniMembers := 0 + teamMembers := 0 subteamMap := make(map[string]int) subteams := service.GetAllSubteams() @@ -63,6 +64,9 @@ func Users(args []string, s *discordgo.Session, m *discordgo.MessageCreate) { if role == config.AlumniRoleID { alumniMembers++ } + if role == config.TeamMemberRoleID { + teamMembers++ + } for _, subteam := range subteams { if role == subteam.ID { subteamMap[subteam.Name]++ @@ -71,10 +75,11 @@ func Users(args []string, s *discordgo.Session, m *discordgo.MessageCreate) { } guildMembers++ } - messageText := fmt.Sprintf("Discord Members: %d\nMembers Role: %d\nAlumni Members: %d\n", guildMembers, memberMembers, alumniMembers) + messageText := fmt.Sprintf("Discord Members: %d\nMembers Role: %d\nAlumni Members: %d\nTeam Members: %d\n\n", guildMembers, memberMembers, alumniMembers, teamMembers) utils.SugarLogger.Infof("Discord Members: %d", guildMembers) utils.SugarLogger.Infof("Members Role: %d", memberMembers) utils.SugarLogger.Infof("Alumni Members: %d", alumniMembers) + utils.SugarLogger.Infof("Team Members: %d", teamMembers) for subteam, count := range subteamMap { utils.SugarLogger.Infof("%s: %d", subteam, count) messageText += fmt.Sprintf("%s: %d\n", subteam, count) From 60c5c100dc34b09b93e263285b64406ad221c4e0 Mon Sep 17 00:00:00 2001 From: austinchan3678 Date: Fri, 2 Jan 2026 11:56:30 -0800 Subject: [PATCH 11/11] oops remove useless code --- service/drive_service.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/service/drive_service.go b/service/drive_service.go index ae84e5d..94a8cb2 100644 --- a/service/drive_service.go +++ b/service/drive_service.go @@ -607,27 +607,7 @@ func PopulateMailingListSheet() { // UpdateTeamMembers checks the Team Members google sheet and gives the Team Member Discord role to all users with a TRUE cell func UpdateTeamMembers() { - spreadsheet, err := SheetClient.Spreadsheets.Get(config.TeamMemberMasterListSheetID).Do() - sheetName := "New Members" - if err != nil { - utils.SugarLogger.Errorf("Unable to get spreadsheet: %v", err) - return - } - - sheetId := -1 - for _, sheet := range spreadsheet.Sheets { - if sheet.Properties.Title == sheetName { - utils.SugarLogger.Infof("Found sheet %s with ID %v", sheet.Properties.Title, sheet.Properties.SheetId) - sheetId = int(sheet.Properties.SheetId) - break - } - } - if sheetId == -1 { - utils.SugarLogger.Errorf("Sheet %s not found", sheetName) - return - } - readRange := fmt.Sprintf("'%s'!A:H", sheetName) resp, err := SheetClient.Spreadsheets.Values.Get(config.TeamMemberMasterListSheetID, readRange).Do() if err != nil {