@@ -6,14 +6,22 @@ import {
66 ROLE_REMOVED ,
77} from "../constants/responses" ;
88import { DISCORD_BASE_URL } from "../constants/urls" ;
9+ import {
10+ parseRateLimitRemaining ,
11+ parseResetAfter ,
12+ } from "../utils/batchDiscordRequests" ;
13+
914import { env } from "../typeDefinitions/default.types" ;
1015import {
1116 createNewRole ,
17+ discordMessageError ,
18+ discordMessageRequest ,
1219 guildRoleResponse ,
1320 memberGroupRole ,
1421} from "../typeDefinitions/discordMessage.types" ;
1522import { GuildRole , Role } from "../typeDefinitions/role.types" ;
1623import createDiscordHeaders from "./createDiscordHeaders" ;
24+ import { sleep } from "./sleep" ;
1725
1826export async function createGuildRole (
1927 body : createNewRole ,
@@ -135,3 +143,68 @@ export async function getGuildRoleByName(
135143 const roles = await getGuildRoles ( env ) ;
136144 return roles ?. find ( ( role ) => role . name === roleName ) ;
137145}
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