@@ -6,14 +6,22 @@ import {
6
6
ROLE_REMOVED ,
7
7
} from "../constants/responses" ;
8
8
import { DISCORD_BASE_URL } from "../constants/urls" ;
9
+ import {
10
+ parseRateLimitRemaining ,
11
+ parseResetAfter ,
12
+ } from "../utils/batchDiscordRequests" ;
13
+
9
14
import { env } from "../typeDefinitions/default.types" ;
10
15
import {
11
16
createNewRole ,
17
+ discordMessageError ,
18
+ discordMessageRequest ,
12
19
guildRoleResponse ,
13
20
memberGroupRole ,
14
21
} from "../typeDefinitions/discordMessage.types" ;
15
22
import { GuildRole , Role } from "../typeDefinitions/role.types" ;
16
23
import createDiscordHeaders from "./createDiscordHeaders" ;
24
+ import { sleep } from "./sleep" ;
17
25
18
26
export async function createGuildRole (
19
27
body : createNewRole ,
@@ -135,3 +143,68 @@ export async function getGuildRoleByName(
135
143
const roles = await getGuildRoles ( env ) ;
136
144
return roles ?. find ( ( role ) => role . name === roleName ) ;
137
145
}
146
+
147
+ export async function mentionEachUserInMessage ( {
148
+ message,
149
+ userIds,
150
+ channelId,
151
+ env,
152
+ } : {
153
+ message ?: string ;
154
+ userIds : string [ ] ;
155
+ channelId : number ;
156
+ env : env ;
157
+ } ) {
158
+ const batchSize = 5 ;
159
+ let waitTillNextAPICall = 0 ;
160
+ try {
161
+ const failedUsers : Array < string > = [ ] ;
162
+ for ( let i = 0 ; i < userIds . length ; i += batchSize ) {
163
+ const batchwiseUserIds = userIds . slice ( i , i + batchSize ) ;
164
+ const messageRequest = batchwiseUserIds . map ( ( userId ) => {
165
+ return fetch ( `${ DISCORD_BASE_URL } /channels/${ channelId } /messages` , {
166
+ method : "POST" ,
167
+ headers : {
168
+ "Content-Type" : "application/json" ,
169
+ Authorization : `Bot ${ env . DISCORD_TOKEN } ` ,
170
+ } ,
171
+ body : JSON . stringify ( {
172
+ content : `${ message ? message + " " : "" } ${ userId } ` ,
173
+ } ) ,
174
+ } ) . then ( ( response ) => {
175
+ const rateLimitRemaining = parseRateLimitRemaining ( response ) ;
176
+ if ( rateLimitRemaining === 0 ) {
177
+ waitTillNextAPICall = Math . max (
178
+ parseResetAfter ( response ) ,
179
+ waitTillNextAPICall
180
+ ) ;
181
+ }
182
+ return response . json ( ) ;
183
+ } ) as Promise < discordMessageRequest | discordMessageError > ;
184
+ } ) ;
185
+ const responses = await Promise . all ( messageRequest ) ;
186
+ responses . forEach ( ( response , i ) => {
187
+ if ( response && "message" in response ) {
188
+ failedUsers . push ( batchwiseUserIds [ i ] ) ;
189
+ console . error ( `Failed to mention a user` ) ;
190
+ }
191
+ } ) ;
192
+ await sleep ( waitTillNextAPICall * 1000 ) ;
193
+ waitTillNextAPICall = 0 ;
194
+ }
195
+ if ( failedUsers . length > 0 ) {
196
+ await fetch ( `${ DISCORD_BASE_URL } /channels/${ channelId } /messages` , {
197
+ method : "POST" ,
198
+ headers : {
199
+ "Content-Type" : "application/json" ,
200
+ Authorization : `Bot ${ env . DISCORD_TOKEN } ` ,
201
+ } ,
202
+ body : JSON . stringify ( {
203
+ content : `Failed to tag ${ failedUsers } individually.` ,
204
+ } ) ,
205
+ } ) ;
206
+ }
207
+ } catch ( error ) {
208
+ console . log ( "Error occured while running mentionEachUserInMessage" , error ) ;
209
+ }
210
+ }
0 commit comments