forked from nmalzieu/starky
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cron.ts
155 lines (143 loc) · 4.89 KB
/
cron.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { IsNull, Not } from "typeorm";
import { DiscordMember } from "./db/entity/DiscordMember";
import { DiscordServer } from "./db/entity/DiscordServer";
import { DiscordServerConfig } from "./db/entity/DiscordServerConfig";
import { restDiscordClient } from "./discord/client";
import { addRole, removeRole } from "./discord/role";
import { StarkyModule } from "./starkyModules/types";
import config from "./config";
import {
DiscordMemberRepository,
DiscordServerConfigRepository,
DiscordServerRepository,
} from "./db";
import modules from "./starkyModules";
const refreshDiscordServers = async () => {
const discordServers = await DiscordServerRepository.find();
for (let discordServer of discordServers) {
await refreshDiscordServer(discordServer);
}
};
export const refreshDiscordServer = async (discordServer: DiscordServer) => {
console.log(`[Cron] Refreshing discord server ${discordServer.id}`);
const discordMembers = await DiscordMemberRepository.find({
where: {
discordServerId: discordServer.id,
starknetWalletAddress: Not(IsNull()),
},
withDeleted: true,
});
const discordConfigs = await DiscordServerConfigRepository.findBy({
discordServerId: discordServer.id,
});
//console.log(discordMembers);
// Refreshing each member one by one. We could
// optimize using a pool in parallel.
for (let discordMember of discordMembers) {
let deleteDiscordMember = !!discordMember.deletedAt;
let hasAtLeastOneRole = new Map();
for (let discordConfig of discordConfigs) {
const starkyModule = modules[discordConfig.starkyModuleType];
if (!starkyModule) {
console.error(
`Server configuration ${discordConfig.id} uses module ${discordConfig.starkyModuleType} which does not exist`
);
continue;
}
try {
let hasRole = await refreshDiscordMember(
discordConfig,
discordMember,
starkyModule
);
if (!hasAtLeastOneRole.get(discordConfig.discordRoleId)) {
hasAtLeastOneRole.set(discordConfig.discordRoleId, {
server: discordConfig.discordServerId,
hasRole: [hasRole],
});
} else {
hasAtLeastOneRole.set(discordConfig.discordRoleId, {
...hasAtLeastOneRole.get(discordConfig.discordRoleId),
hasRole: [
...hasAtLeastOneRole.get(discordConfig.discordRoleId).hasRole,
hasRole,
],
});
}
} catch (e: any) {
console.log(e);
if (e?.code === 10007) {
// This user is no longer a member of this discord server, we should just remove it
deleteDiscordMember = true;
console.log(
`Discord member ${discordMember.discordMemberId} does not exist in Discord server ${discordConfig.discordServerId} and will be deleted`
);
} else {
console.error(
`Could not refresh discord member ${discordMember.discordMemberId} with configuration ${discordConfig.id} in server : ${discordConfig.discordServerId} ${e}`
);
}
}
if (deleteDiscordMember) {
try {
await DiscordMemberRepository.remove(discordMember);
} catch (e) {
console.error(
`Could not delete discord member ${discordMember.discordMemberId} in server ${discordConfig.discordServerId} ${e}`
);
}
}
}
//@ts-ignore
// for each role and value of the map
for (let [role, value] of Array.from(hasAtLeastOneRole.entries())) {
let hasOneRoleArray = value.hasRole.filter(Boolean);
if (0 === hasOneRoleArray.length) {
await removeRole(
restDiscordClient,
value.server,
discordMember.discordMemberId,
role
);
continue;
}
await addRole(
restDiscordClient,
value.server,
discordMember.discordMemberId,
role
);
}
}
};
export const refreshDiscordMember = async (
discordServerConfig: DiscordServerConfig,
discordMember: DiscordMember,
starkyModule?: StarkyModule
) => {
if (!discordMember.starknetWalletAddress) return;
if (discordMember.starknetNetwork !== discordServerConfig.starknetNetwork)
return;
const starkyMod =
starkyModule || modules[discordServerConfig.starkyModuleType];
// Always remove role for deleted users
const shouldHaveRole = discordMember.deletedAt
? false
: await starkyMod.shouldHaveRole(
discordMember.starknetWalletAddress,
discordServerConfig.starknetNetwork === "mainnet"
? "mainnet"
: "goerli",
discordServerConfig?.starkyModuleConfig
);
return shouldHaveRole;
};
const cronInterval = async () => {
try {
await refreshDiscordServers();
} catch (e) {
console.error(e);
}
setTimeout(cronInterval, config.UPDATE_STATUS_EVERY_SECONDS * 1000);
};
export default cronInterval;