Skip to content

Commit 41a2dab

Browse files
authored
Assign top coin ranks for top 5, 10, 20 (#525)
* Assign top coin ranks for top 5, 10, 20 * Repeat fetch coin leaderboard until specified number of humans are found for assignCodeyRoleForLeaderboard, disallowing bots from receiving a role
1 parent e319a8e commit 41a2dab

File tree

3 files changed

+77
-20
lines changed

3 files changed

+77
-20
lines changed

config/staging/vars.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
"TARGET_GUILD_ID": "701335585272627200",
33
"COFFEE_ROLE_ID": "861744590775779358",
44
"OFFICE_PING_ROLE_ID": "1031378676077572188",
5-
"CODEY_COIN_ROLE_ID": "1071958737100742756",
5+
"CODEY_COIN_T5_ROLE_ID": "1244832373946847253",
6+
"CODEY_COIN_T10_ROLE_ID": "1244832151904456775",
7+
"CODEY_COIN_T20_ROLE_ID": "1244832331618062336",
68
"NOTIF_CHANNEL_ID": "866861080301797386",
79
"ANNOUNCEMENTS_CHANNEL_ID": "1014739389206777867",
810
"OFFICE_STATUS_CHANNEL_ID": "866861080301797386",

config/vars.template.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
"TARGET_GUILD_ID": "GUILD_ID",
33
"COFFEE_ROLE_ID": "ROLE_ID",
44
"OFFICE_PING_ROLE_ID": "ROLE_ID",
5-
"CODEY_COIN_ROLE_ID": "ROLE_ID",
5+
"CODEY_COIN_T5_ROLE_ID": "ROLE_ID",
6+
"CODEY_COIN_T10_ROLE_ID": "ROLE_ID",
7+
"CODEY_COIN_T20_ROLE_ID": "ROLE_ID",
68
"NOTIF_CHANNEL_ID": "CHANNEL_ID",
79
"ANNOUNCEMENTS_CHANNEL_ID": "CHANNEL_ID",
810
"OFFICE_STATUS_CHANNEL_ID": "CHANNEL_ID",

src/components/cron.ts

+71-18
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import { alertUsers } from './officeOpenDM';
88
import { vars } from '../config';
99
import { DEFAULT_EMBED_COLOUR } from '../utils/embeds';
1010
import { getMatch, writeHistoricMatches } from '../components/coffeeChat';
11-
import { adjustCoinBalanceByUserId, BonusType, coinBonusMap, getCoinLeaderboard } from './coin';
11+
import {
12+
adjustCoinBalanceByUserId,
13+
BonusType,
14+
coinBonusMap,
15+
getCoinLeaderboard,
16+
UserCoinEntry,
17+
} from './coin';
1218
import { getInterviewers } from './interviewer';
1319
import {
1420
getSuggestionPrintout,
@@ -24,8 +30,13 @@ const NOTIF_CHANNEL_ID: string = vars.NOTIF_CHANNEL_ID;
2430
const OFFICE_STATUS_CHANNEL_ID: string = vars.OFFICE_STATUS_CHANNEL_ID;
2531
const OFFICE_HOURS_STATUS_API = 'https://csclub.uwaterloo.ca/~webcom/office-status.json';
2632
const TARGET_GUILD_ID: string = vars.TARGET_GUILD_ID;
27-
const CODEY_COIN_ROLE_ID: string = vars.CODEY_COIN_ROLE_ID;
28-
const NUMBER_USERS_TO_ASSIGN_ROLE = 10;
33+
const NUMBER_USERS_TO_ASSIGN_ROLE = 20;
34+
const CODEY_COIN_ROLES: string[] = [
35+
vars.CODEY_COIN_T5_ROLE_ID,
36+
vars.CODEY_COIN_T10_ROLE_ID,
37+
vars.CODEY_COIN_T20_ROLE_ID,
38+
];
39+
const CODEY_COIN_INTERVALS: number[] = [5, 10, 20];
2940

3041
// The last known status of the office
3142
// false if closed
@@ -141,27 +152,69 @@ export const createCoffeeChatCron = (client: Client): CronJob =>
141152
// Gives Codey coin role to those on the leaderboard list everyday
142153
export const assignCodeyRoleForLeaderboard = (client: Client): CronJob =>
143154
new CronJob('0 0 0 */1 * *', async function () {
144-
const leaderboard = await getCoinLeaderboard(NUMBER_USERS_TO_ASSIGN_ROLE);
145-
const leaderboardIds: Set<string> = new Set(leaderboard.map((entry) => entry.user_id));
146155
const guild = client.guilds.resolve(TARGET_GUILD_ID);
147156
if (!guild) {
148157
throw new CodeyUserError(undefined, 'guild not found');
149158
}
159+
150160
const members = await guild.members.fetch();
151-
// Removing role from previous members
152-
const guildMembersPreviousRole = await loadRoleMembers(CODEY_COIN_ROLE_ID);
153-
const previousIds: Set<string> = new Set(guildMembersPreviousRole.map((member) => member.id));
154-
const roleName: string = await getRoleName(CODEY_COIN_ROLE_ID);
155-
156-
guildMembersPreviousRole.forEach(async (member) => {
157-
if (member && !leaderboardIds.has(member.id)) {
158-
await updateMemberRole(member, roleName, false);
161+
const leaderboard: UserCoinEntry[] = [];
162+
let fetchAttempts = 0;
163+
164+
// Fetch leaderboard until we have enough human members to assign roles to
165+
while (leaderboard.length < NUMBER_USERS_TO_ASSIGN_ROLE) {
166+
const leaderboardBuffer = await getCoinLeaderboard(
167+
NUMBER_USERS_TO_ASSIGN_ROLE,
168+
fetchAttempts * NUMBER_USERS_TO_ASSIGN_ROLE,
169+
);
170+
171+
if (leaderboardBuffer.length <= 0) {
172+
break;
159173
}
160-
});
161-
leaderboardIds.forEach(async (user_id) => {
162-
const memberToUpdate = members.get(user_id);
163-
if (memberToUpdate && !previousIds.has(user_id)) {
164-
await updateMemberRole(memberToUpdate, roleName, true);
174+
175+
for (const entry of leaderboardBuffer) {
176+
if (members.get(entry.user_id)?.user?.bot) {
177+
continue;
178+
}
179+
leaderboard.push(entry);
180+
if (leaderboard.length >= NUMBER_USERS_TO_ASSIGN_ROLE) {
181+
break;
182+
}
165183
}
184+
185+
fetchAttempts++;
186+
}
187+
188+
// Create slices of the leaderboard to assign roles to
189+
const topSlices: string[][] = [];
190+
for (let i = 0; i < CODEY_COIN_INTERVALS.length; i++) {
191+
topSlices.push(
192+
leaderboard
193+
// Slice the leaderboard into intervals -> {[0,i), [i-1, i), [i-1, end|i)}
194+
.slice(i === 0 ? 0 : CODEY_COIN_INTERVALS[i - 1], CODEY_COIN_INTERVALS[i])
195+
.map((entry) => entry.user_id),
196+
);
197+
}
198+
199+
CODEY_COIN_ROLES.forEach(async (roleId, idx) => {
200+
const roleName: string = await getRoleName(roleId);
201+
const guildMembersPreviousRole = await loadRoleMembers(roleId);
202+
const previousIds: Set<string> = new Set(guildMembersPreviousRole.map((member) => member.id));
203+
const leaderboardIds = new Set(topSlices[idx]);
204+
205+
// Removing role from former members
206+
guildMembersPreviousRole.forEach(async (member) => {
207+
if (member && !leaderboardIds.has(member.id)) {
208+
await updateMemberRole(member, roleName, false);
209+
}
210+
});
211+
212+
// Adding role to new members
213+
leaderboardIds.forEach(async (user_id) => {
214+
const memberToUpdate = members.get(user_id);
215+
if (memberToUpdate && !previousIds.has(user_id)) {
216+
await updateMemberRole(memberToUpdate, roleName, true);
217+
}
218+
});
166219
});
167220
});

0 commit comments

Comments
 (0)