djs-selfbot-v13 3.2.2 → 3.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/README.md +63 -36
  2. package/package.json +89 -85
  3. package/src/WebSocket.js +39 -39
  4. package/src/client/BaseClient.js +86 -86
  5. package/src/client/Client.js +941 -836
  6. package/src/client/WebhookClient.js +61 -61
  7. package/src/client/actions/Action.js +116 -120
  8. package/src/client/actions/ActionsManager.js +80 -78
  9. package/src/client/actions/ApplicationCommandPermissionsUpdate.js +34 -34
  10. package/src/client/actions/AutoModerationActionExecution.js +27 -27
  11. package/src/client/actions/AutoModerationRuleCreate.js +28 -28
  12. package/src/client/actions/AutoModerationRuleDelete.js +32 -32
  13. package/src/client/actions/AutoModerationRuleUpdate.js +30 -30
  14. package/src/client/actions/ChannelCreate.js +23 -23
  15. package/src/client/actions/ChannelDelete.js +39 -39
  16. package/src/client/actions/ChannelUpdate.js +43 -43
  17. package/src/client/actions/GuildAuditLogEntryCreate.js +29 -29
  18. package/src/client/actions/GuildBanAdd.js +20 -20
  19. package/src/client/actions/GuildBanRemove.js +25 -25
  20. package/src/client/actions/GuildChannelsPositionUpdate.js +21 -21
  21. package/src/client/actions/GuildDelete.js +65 -65
  22. package/src/client/actions/GuildEmojiCreate.js +20 -20
  23. package/src/client/actions/GuildEmojiDelete.js +21 -21
  24. package/src/client/actions/GuildEmojiUpdate.js +20 -20
  25. package/src/client/actions/GuildEmojisUpdate.js +34 -34
  26. package/src/client/actions/GuildIntegrationsUpdate.js +19 -19
  27. package/src/client/actions/GuildMemberRemove.js +33 -32
  28. package/src/client/actions/GuildMemberUpdate.js +44 -43
  29. package/src/client/actions/GuildRoleCreate.js +25 -25
  30. package/src/client/actions/GuildRoleDelete.js +31 -31
  31. package/src/client/actions/GuildRoleUpdate.js +39 -39
  32. package/src/client/actions/GuildRolesPositionUpdate.js +21 -21
  33. package/src/client/actions/GuildScheduledEventCreate.js +27 -27
  34. package/src/client/actions/GuildScheduledEventDelete.js +31 -31
  35. package/src/client/actions/GuildScheduledEventUpdate.js +30 -30
  36. package/src/client/actions/GuildScheduledEventUserAdd.js +32 -32
  37. package/src/client/actions/GuildScheduledEventUserRemove.js +32 -32
  38. package/src/client/actions/GuildStickerCreate.js +20 -20
  39. package/src/client/actions/GuildStickerDelete.js +21 -21
  40. package/src/client/actions/GuildStickerUpdate.js +20 -20
  41. package/src/client/actions/GuildStickersUpdate.js +34 -34
  42. package/src/client/actions/GuildUpdate.js +33 -33
  43. package/src/client/actions/InviteCreate.js +28 -28
  44. package/src/client/actions/InviteDelete.js +30 -30
  45. package/src/client/actions/MessageCreate.js +50 -46
  46. package/src/client/actions/MessageDelete.js +32 -32
  47. package/src/client/actions/MessageDeleteBulk.js +46 -46
  48. package/src/client/actions/MessagePollVoteAdd.js +33 -0
  49. package/src/client/actions/MessagePollVoteRemove.js +33 -0
  50. package/src/client/actions/MessageReactionAdd.js +68 -56
  51. package/src/client/actions/MessageReactionRemove.js +50 -45
  52. package/src/client/actions/MessageReactionRemoveAll.js +33 -33
  53. package/src/client/actions/MessageReactionRemoveEmoji.js +28 -28
  54. package/src/client/actions/MessageUpdate.js +26 -26
  55. package/src/client/actions/PresenceUpdate.js +50 -46
  56. package/src/client/actions/StageInstanceCreate.js +28 -28
  57. package/src/client/actions/StageInstanceDelete.js +33 -33
  58. package/src/client/actions/StageInstanceUpdate.js +30 -30
  59. package/src/client/actions/ThreadCreate.js +24 -24
  60. package/src/client/actions/ThreadDelete.js +32 -32
  61. package/src/client/actions/ThreadListSync.js +59 -59
  62. package/src/client/actions/ThreadMemberUpdate.js +30 -30
  63. package/src/client/actions/ThreadMembersUpdate.js +34 -34
  64. package/src/client/actions/TypingStart.js +29 -29
  65. package/src/client/actions/UserUpdate.js +35 -35
  66. package/src/client/actions/VoiceStateUpdate.js +50 -57
  67. package/src/client/actions/WebhooksUpdate.js +20 -20
  68. package/src/client/voice/ClientVoiceManager.js +151 -51
  69. package/src/client/voice/VoiceConnection.js +1249 -0
  70. package/src/client/voice/dispatcher/AnnexBDispatcher.js +120 -0
  71. package/src/client/voice/dispatcher/AudioDispatcher.js +145 -0
  72. package/src/client/voice/dispatcher/BaseDispatcher.js +459 -0
  73. package/src/client/voice/dispatcher/VPxDispatcher.js +54 -0
  74. package/src/client/voice/dispatcher/VideoDispatcher.js +68 -0
  75. package/src/client/voice/networking/VoiceUDPClient.js +173 -0
  76. package/src/client/voice/networking/VoiceWebSocket.js +286 -0
  77. package/src/client/voice/player/MediaPlayer.js +321 -0
  78. package/src/client/voice/player/processing/AnnexBNalSplitter.js +244 -0
  79. package/src/client/voice/player/processing/IvfSplitter.js +106 -0
  80. package/src/client/voice/player/processing/PCMInsertSilence.js +37 -0
  81. package/src/client/voice/receiver/PacketHandler.js +260 -0
  82. package/src/client/voice/receiver/Receiver.js +96 -0
  83. package/src/client/voice/receiver/Recorder.js +173 -0
  84. package/src/client/voice/util/Function.js +116 -0
  85. package/src/client/voice/util/PlayInterface.js +122 -0
  86. package/src/client/voice/util/Secretbox.js +64 -0
  87. package/src/client/voice/util/Silence.js +16 -0
  88. package/src/client/voice/util/Socket.js +62 -0
  89. package/src/client/voice/util/VolumeInterface.js +104 -0
  90. package/src/client/websocket/WebSocketManager.js +392 -392
  91. package/src/client/websocket/WebSocketShard.js +907 -906
  92. package/src/client/websocket/handlers/APPLICATION_COMMAND_CREATE.js +18 -18
  93. package/src/client/websocket/handlers/APPLICATION_COMMAND_DELETE.js +20 -20
  94. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js +5 -5
  95. package/src/client/websocket/handlers/APPLICATION_COMMAND_UPDATE.js +20 -20
  96. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js +5 -5
  97. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js +5 -5
  98. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js +5 -5
  99. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js +5 -5
  100. package/src/client/websocket/handlers/CALL_CREATE.js +14 -14
  101. package/src/client/websocket/handlers/CALL_DELETE.js +11 -11
  102. package/src/client/websocket/handlers/CALL_UPDATE.js +11 -11
  103. package/src/client/websocket/handlers/CHANNEL_CREATE.js +5 -5
  104. package/src/client/websocket/handlers/CHANNEL_DELETE.js +5 -5
  105. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js +22 -22
  106. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +19 -19
  107. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +16 -16
  108. package/src/client/websocket/handlers/CHANNEL_UPDATE.js +16 -16
  109. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js +5 -5
  110. package/src/client/websocket/handlers/GUILD_BAN_ADD.js +5 -5
  111. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.js +5 -5
  112. package/src/client/websocket/handlers/GUILD_CREATE.js +52 -52
  113. package/src/client/websocket/handlers/GUILD_DELETE.js +5 -5
  114. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js +5 -5
  115. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js +5 -5
  116. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js +39 -39
  117. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +20 -19
  118. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js +5 -5
  119. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js +5 -5
  120. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.js +5 -5
  121. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.js +5 -5
  122. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js +5 -5
  123. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js +5 -5
  124. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js +5 -5
  125. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js +5 -5
  126. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js +5 -5
  127. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js +5 -5
  128. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js +5 -5
  129. package/src/client/websocket/handlers/GUILD_UPDATE.js +5 -5
  130. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +12 -12
  131. package/src/client/websocket/handlers/INVITE_CREATE.js +5 -5
  132. package/src/client/websocket/handlers/INVITE_DELETE.js +5 -5
  133. package/src/client/websocket/handlers/MESSAGE_CREATE.js +5 -5
  134. package/src/client/websocket/handlers/MESSAGE_DELETE.js +5 -5
  135. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js +5 -5
  136. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +5 -22
  137. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +5 -12
  138. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js +5 -5
  139. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js +5 -5
  140. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js +5 -5
  141. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js +5 -5
  142. package/src/client/websocket/handlers/MESSAGE_UPDATE.js +16 -16
  143. package/src/client/websocket/handlers/PRESENCE_UPDATE.js +5 -5
  144. package/src/client/websocket/handlers/READY.js +121 -120
  145. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +19 -19
  146. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +17 -17
  147. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +41 -41
  148. package/src/client/websocket/handlers/RESUMED.js +14 -14
  149. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js +5 -5
  150. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js +5 -5
  151. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js +5 -5
  152. package/src/client/websocket/handlers/THREAD_CREATE.js +5 -5
  153. package/src/client/websocket/handlers/THREAD_DELETE.js +5 -5
  154. package/src/client/websocket/handlers/THREAD_LIST_SYNC.js +5 -5
  155. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js +5 -5
  156. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js +5 -5
  157. package/src/client/websocket/handlers/THREAD_UPDATE.js +16 -16
  158. package/src/client/websocket/handlers/TYPING_START.js +5 -5
  159. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +6 -6
  160. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +5 -5
  161. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -78
  162. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -5
  163. package/src/client/websocket/handlers/USER_UPDATE.js +5 -5
  164. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +16 -0
  165. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -12
  166. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js +6 -6
  167. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.js +5 -5
  168. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.js +5 -5
  169. package/src/client/websocket/handlers/index.js +84 -83
  170. package/src/errors/DJSError.js +61 -61
  171. package/src/errors/Messages.js +217 -183
  172. package/src/errors/index.js +4 -4
  173. package/src/index.js +172 -159
  174. package/src/managers/ApplicationCommandManager.js +264 -264
  175. package/src/managers/ApplicationCommandPermissionsManager.js +417 -417
  176. package/src/managers/AutoModerationRuleManager.js +296 -296
  177. package/src/managers/BaseGuildEmojiManager.js +80 -80
  178. package/src/managers/BaseManager.js +19 -19
  179. package/src/managers/BillingManager.js +66 -66
  180. package/src/managers/CachedManager.js +71 -71
  181. package/src/managers/ChannelManager.js +148 -138
  182. package/src/managers/ClientUserSettingManager.js +372 -372
  183. package/src/managers/DataManager.js +61 -61
  184. package/src/managers/GuildBanManager.js +250 -250
  185. package/src/managers/GuildChannelManager.js +488 -488
  186. package/src/managers/GuildEmojiManager.js +171 -171
  187. package/src/managers/GuildEmojiRoleManager.js +118 -118
  188. package/src/managers/GuildForumThreadManager.js +108 -108
  189. package/src/managers/GuildInviteManager.js +213 -213
  190. package/src/managers/GuildManager.js +338 -304
  191. package/src/managers/GuildMemberManager.js +599 -597
  192. package/src/managers/GuildMemberRoleManager.js +195 -191
  193. package/src/managers/GuildScheduledEventManager.js +314 -296
  194. package/src/managers/GuildSettingManager.js +155 -155
  195. package/src/managers/GuildStickerManager.js +179 -179
  196. package/src/managers/GuildTextThreadManager.js +98 -98
  197. package/src/managers/InteractionManager.js +39 -39
  198. package/src/managers/MessageManager.js +423 -391
  199. package/src/managers/PermissionOverwriteManager.js +164 -166
  200. package/src/managers/PresenceManager.js +71 -58
  201. package/src/managers/QuestManager.js +376 -0
  202. package/src/managers/ReactionManager.js +67 -67
  203. package/src/managers/ReactionUserManager.js +73 -71
  204. package/src/managers/RelationshipManager.js +278 -265
  205. package/src/managers/RoleManager.js +448 -352
  206. package/src/managers/SessionManager.js +66 -0
  207. package/src/managers/StageInstanceManager.js +162 -162
  208. package/src/managers/ThreadManager.js +175 -174
  209. package/src/managers/ThreadMemberManager.js +186 -186
  210. package/src/managers/UserManager.js +136 -146
  211. package/src/managers/UserNoteManager.js +53 -53
  212. package/src/managers/VoiceStateManager.js +59 -37
  213. package/src/rest/APIRequest.js +154 -160
  214. package/src/rest/APIRouter.js +53 -53
  215. package/src/rest/DiscordAPIError.js +119 -104
  216. package/src/rest/HTTPError.js +62 -62
  217. package/src/rest/RESTManager.js +67 -62
  218. package/src/rest/RateLimitError.js +55 -55
  219. package/src/rest/RequestHandler.js +466 -444
  220. package/src/sharding/Shard.js +444 -443
  221. package/src/sharding/ShardClientUtil.js +279 -275
  222. package/src/sharding/ShardingManager.js +319 -318
  223. package/src/structures/AnonymousGuild.js +98 -98
  224. package/src/structures/ApplicationCommand.js +593 -593
  225. package/src/structures/ApplicationRoleConnectionMetadata.js +48 -48
  226. package/src/structures/AutoModerationActionExecution.js +89 -89
  227. package/src/structures/AutoModerationRule.js +294 -294
  228. package/src/structures/AutocompleteInteraction.js +107 -107
  229. package/src/structures/Base.js +43 -43
  230. package/src/structures/BaseCommandInteraction.js +211 -211
  231. package/src/structures/BaseGuild.js +116 -116
  232. package/src/structures/BaseGuildEmoji.js +56 -56
  233. package/src/structures/BaseGuildTextChannel.js +191 -191
  234. package/src/structures/BaseGuildVoiceChannel.js +241 -241
  235. package/src/structures/BaseMessageComponent.js +181 -114
  236. package/src/structures/ButtonInteraction.js +11 -11
  237. package/src/structures/CallState.js +63 -63
  238. package/src/structures/CategoryChannel.js +85 -85
  239. package/src/structures/Channel.js +284 -270
  240. package/src/structures/ClientPresence.js +77 -85
  241. package/src/structures/ClientUser.js +653 -448
  242. package/src/structures/CommandInteraction.js +41 -41
  243. package/src/structures/CommandInteractionOptionResolver.js +276 -276
  244. package/src/structures/ContainerComponent.js +68 -0
  245. package/src/structures/ContextMenuInteraction.js +65 -65
  246. package/src/structures/DMChannel.js +219 -217
  247. package/src/structures/DirectoryChannel.js +20 -20
  248. package/src/structures/Emoji.js +148 -148
  249. package/src/structures/FileComponent.js +49 -0
  250. package/src/structures/ForumChannel.js +31 -261
  251. package/src/structures/GroupDMChannel.js +394 -387
  252. package/src/structures/Guild.js +1697 -1608
  253. package/src/structures/GuildAuditLogs.js +746 -729
  254. package/src/structures/GuildBan.js +59 -59
  255. package/src/structures/GuildBoost.js +108 -108
  256. package/src/structures/GuildChannel.js +470 -468
  257. package/src/structures/GuildEmoji.js +161 -161
  258. package/src/structures/GuildMember.js +636 -568
  259. package/src/structures/GuildPreview.js +191 -191
  260. package/src/structures/GuildPreviewEmoji.js +27 -27
  261. package/src/structures/GuildScheduledEvent.js +536 -441
  262. package/src/structures/GuildTemplate.js +236 -236
  263. package/src/structures/Integration.js +188 -188
  264. package/src/structures/IntegrationApplication.js +96 -96
  265. package/src/structures/Interaction.js +290 -290
  266. package/src/structures/InteractionCollector.js +248 -248
  267. package/src/structures/InteractionWebhook.js +43 -43
  268. package/src/structures/Invite.js +358 -358
  269. package/src/structures/InviteGuild.js +23 -23
  270. package/src/structures/InviteStageInstance.js +86 -86
  271. package/src/structures/MediaChannel.js +11 -0
  272. package/src/structures/MediaGalleryComponent.js +41 -0
  273. package/src/structures/MediaGalleryItem.js +47 -0
  274. package/src/structures/Message.js +1252 -1227
  275. package/src/structures/MessageActionRow.js +105 -103
  276. package/src/structures/MessageAttachment.js +216 -204
  277. package/src/structures/MessageButton.js +166 -165
  278. package/src/structures/MessageCollector.js +146 -146
  279. package/src/structures/MessageComponentInteraction.js +120 -120
  280. package/src/structures/MessageContextMenuInteraction.js +20 -20
  281. package/src/structures/MessageEmbed.js +596 -586
  282. package/src/structures/MessageMentions.js +273 -273
  283. package/src/structures/MessagePayload.js +354 -318
  284. package/src/structures/MessageReaction.js +181 -171
  285. package/src/structures/MessageSelectMenu.js +141 -140
  286. package/src/structures/Modal.js +161 -161
  287. package/src/structures/ModalSubmitFieldsResolver.js +53 -53
  288. package/src/structures/ModalSubmitInteraction.js +119 -119
  289. package/src/structures/NewsChannel.js +32 -32
  290. package/src/structures/OAuth2Guild.js +28 -28
  291. package/src/structures/PermissionOverwrites.js +198 -196
  292. package/src/structures/Poll.js +108 -0
  293. package/src/structures/PollAnswer.js +88 -0
  294. package/src/structures/Presence.js +1137 -1101
  295. package/src/structures/ReactionCollector.js +229 -229
  296. package/src/structures/ReactionEmoji.js +31 -31
  297. package/src/structures/Role.js +590 -531
  298. package/src/structures/SectionComponent.js +48 -0
  299. package/src/structures/SelectMenuInteraction.js +21 -21
  300. package/src/structures/SeparatorComponent.js +48 -0
  301. package/src/structures/Session.js +81 -0
  302. package/src/structures/StageChannel.js +104 -104
  303. package/src/structures/StageInstance.js +208 -208
  304. package/src/structures/Sticker.js +310 -310
  305. package/src/structures/StickerPack.js +95 -95
  306. package/src/structures/StoreChannel.js +56 -56
  307. package/src/structures/Team.js +118 -118
  308. package/src/structures/TeamMember.js +80 -71
  309. package/src/structures/TextChannel.js +33 -33
  310. package/src/structures/TextDisplayComponent.js +40 -0
  311. package/src/structures/TextInputComponent.js +132 -131
  312. package/src/structures/ThreadChannel.js +605 -607
  313. package/src/structures/ThreadMember.js +105 -105
  314. package/src/structures/ThreadOnlyChannel.js +249 -0
  315. package/src/structures/ThumbnailComponent.js +57 -0
  316. package/src/structures/Typing.js +74 -74
  317. package/src/structures/UnfurledMediaItem.js +29 -0
  318. package/src/structures/User.js +640 -543
  319. package/src/structures/UserContextMenuInteraction.js +29 -29
  320. package/src/structures/VoiceChannel.js +110 -110
  321. package/src/structures/VoiceChannelEffect.js +69 -0
  322. package/src/structures/VoiceRegion.js +53 -53
  323. package/src/structures/VoiceState.js +354 -341
  324. package/src/structures/WebEmbed.js +373 -373
  325. package/src/structures/Webhook.js +478 -467
  326. package/src/structures/WelcomeChannel.js +60 -60
  327. package/src/structures/WelcomeScreen.js +48 -48
  328. package/src/structures/Widget.js +87 -87
  329. package/src/structures/WidgetMember.js +99 -99
  330. package/src/structures/interfaces/Application.js +825 -313
  331. package/src/structures/interfaces/Collector.js +300 -300
  332. package/src/structures/interfaces/InteractionResponses.js +313 -313
  333. package/src/structures/interfaces/TextBasedChannel.js +759 -719
  334. package/src/util/APITypes.js +59 -0
  335. package/src/util/ActivityFlags.js +44 -44
  336. package/src/util/ApplicationFlags.js +76 -76
  337. package/src/util/AttachmentFlags.js +38 -38
  338. package/src/util/BitField.js +170 -170
  339. package/src/util/ChannelFlags.js +45 -45
  340. package/src/util/Constants.js +1914 -1773
  341. package/src/util/DataResolver.js +146 -145
  342. package/src/util/Formatters.js +228 -228
  343. package/src/util/GuildMemberFlags.js +43 -43
  344. package/src/util/Intents.js +74 -74
  345. package/src/util/InviteFlags.js +34 -29
  346. package/src/util/LimitedCollection.js +131 -131
  347. package/src/util/MessageFlags.js +63 -54
  348. package/src/util/Options.js +358 -336
  349. package/src/util/Permissions.js +202 -202
  350. package/src/util/PremiumUsageFlags.js +31 -31
  351. package/src/util/PurchasedFlags.js +33 -33
  352. package/src/util/RemoteAuth.js +382 -379
  353. package/src/util/RoleFlags.js +37 -37
  354. package/src/util/SnowflakeUtil.js +92 -92
  355. package/src/util/Speaking.js +33 -0
  356. package/src/util/Sweepers.js +466 -466
  357. package/src/util/SystemChannelFlags.js +55 -55
  358. package/src/util/ThreadMemberFlags.js +30 -30
  359. package/src/util/UserFlags.js +104 -104
  360. package/src/util/Util.js +1048 -889
  361. package/typings/enums.d.ts +439 -297
  362. package/typings/index.d.ts +8392 -7432
  363. package/typings/rawDataTypes.d.ts +403 -342
  364. package/src/structures/MessagePoll.js +0 -238
@@ -1,836 +1,941 @@
1
- /* eslint-disable no-unreachable */
2
- 'use strict';
3
-
4
- const process = require('node:process');
5
- const { setInterval } = require('node:timers');
6
- const { setTimeout } = require('node:timers');
7
- const { Collection } = require('@discordjs/collection');
8
- const BaseClient = require('./BaseClient');
9
- const ActionsManager = require('./actions/ActionsManager');
10
- const ClientVoiceManager = require('./voice/ClientVoiceManager');
11
- const WebSocketManager = require('./websocket/WebSocketManager');
12
- const { Error, TypeError } = require('../errors');
13
- const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager');
14
- const BillingManager = require('../managers/BillingManager');
15
- const ChannelManager = require('../managers/ChannelManager');
16
- const ClientUserSettingManager = require('../managers/ClientUserSettingManager');
17
- const GuildManager = require('../managers/GuildManager');
18
- const PresenceManager = require('../managers/PresenceManager');
19
- const RelationshipManager = require('../managers/RelationshipManager');
20
- const UserManager = require('../managers/UserManager');
21
- const UserNoteManager = require('../managers/UserNoteManager');
22
- const VoiceStateManager = require('../managers/VoiceStateManager');
23
- const ShardClientUtil = require('../sharding/ShardClientUtil');
24
- const ClientPresence = require('../structures/ClientPresence');
25
- const GuildPreview = require('../structures/GuildPreview');
26
- const GuildTemplate = require('../structures/GuildTemplate');
27
- const Invite = require('../structures/Invite');
28
- const { Sticker } = require('../structures/Sticker');
29
- const StickerPack = require('../structures/StickerPack');
30
- const VoiceRegion = require('../structures/VoiceRegion');
31
- const Webhook = require('../structures/Webhook');
32
- const Widget = require('../structures/Widget');
33
- const { Events, Status } = require('../util/Constants');
34
- const DataResolver = require('../util/DataResolver');
35
- const Intents = require('../util/Intents');
36
- const Permissions = require('../util/Permissions');
37
- const DiscordAuthWebsocket = require('../util/RemoteAuth');
38
- const Sweepers = require('../util/Sweepers');
39
-
40
- /**
41
- * The main hub for interacting with the Discord API, and the starting point for any bot.
42
- * @extends {BaseClient}
43
- */
44
- class Client extends BaseClient {
45
- /**
46
- * @param {ClientOptions} [options] Options for the client
47
- */
48
- constructor(options) {
49
- super(options);
50
-
51
- this._validateOptions();
52
-
53
- /**
54
- * Functions called when a cache is garbage collected or the Client is destroyed
55
- * @type {Set<Function>}
56
- * @private
57
- */
58
- this._cleanups = new Set();
59
-
60
- /**
61
- * The finalizers used to cleanup items.
62
- * @type {FinalizationRegistry}
63
- * @private
64
- */
65
- this._finalizers = new FinalizationRegistry(this._finalize.bind(this));
66
-
67
- /**
68
- * The WebSocket manager of the client
69
- * @type {WebSocketManager}
70
- */
71
- this.ws = new WebSocketManager(this);
72
-
73
- /**
74
- * The action manager of the client
75
- * @type {ActionsManager}
76
- * @private
77
- */
78
- this.actions = new ActionsManager(this);
79
-
80
- /**
81
- * The voice manager of the client
82
- * @type {ClientVoiceManager}
83
- */
84
- this.voice = new ClientVoiceManager(this);
85
-
86
- /**
87
- * A manager of the voice states of this client (Support DM / Group DM)
88
- * @type {VoiceStateManager}
89
- */
90
- this.voiceStates = new VoiceStateManager({ client: this });
91
-
92
- /**
93
- * Shard helpers for the client (only if the process was spawned from a {@link ShardingManager})
94
- * @type {?ShardClientUtil}
95
- */
96
- this.shard = process.env.SHARDING_MANAGER
97
- ? ShardClientUtil.singleton(this, process.env.SHARDING_MANAGER_MODE)
98
- : null;
99
-
100
- /**
101
- * All of the {@link User} objects that have been cached at any point, mapped by their ids
102
- * @type {UserManager}
103
- */
104
- this.users = new UserManager(this);
105
-
106
- /**
107
- * All of the guilds the client is currently handling, mapped by their ids -
108
- * as long as sharding isn't being used, this will be *every* guild the bot is a member of
109
- * @type {GuildManager}
110
- */
111
- this.guilds = new GuildManager(this);
112
-
113
- /**
114
- * All of the {@link Channel}s that the client is currently handling, mapped by their ids -
115
- * as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
116
- * is a member of. Note that DM channels will not be initially cached, and thus not be present
117
- * in the Manager without their explicit fetching or use.
118
- * @type {ChannelManager}
119
- */
120
- this.channels = new ChannelManager(this);
121
-
122
- /**
123
- * The sweeping functions and their intervals used to periodically sweep caches
124
- * @type {Sweepers}
125
- */
126
- this.sweepers = new Sweepers(this, this.options.sweepers);
127
-
128
- /**
129
- * The presence of the Client
130
- * @private
131
- * @type {ClientPresence}
132
- */
133
- this.presence = new ClientPresence(this, this.options.presence);
134
-
135
- /**
136
- * A manager of the presences belonging to this client
137
- * @type {PresenceManager}
138
- */
139
- this.presences = new PresenceManager(this);
140
-
141
- /**
142
- * All of the note that have been cached at any point, mapped by their ids
143
- * @type {UserManager}
144
- */
145
- this.notes = new UserNoteManager(this);
146
-
147
- /**
148
- * All of the relationships {@link User}
149
- * @type {RelationshipManager}
150
- */
151
- this.relationships = new RelationshipManager(this);
152
-
153
- /**
154
- * Manages the API methods
155
- * @type {BillingManager}
156
- */
157
- this.billing = new BillingManager(this);
158
-
159
- /**
160
- * All of the settings {@link Object}
161
- * @type {ClientUserSettingManager}
162
- */
163
- this.settings = new ClientUserSettingManager(this);
164
-
165
- Object.defineProperty(this, 'token', { writable: true });
166
- if (!this.token && 'DISCORD_TOKEN' in process.env) {
167
- /**
168
- * Authorization token for the logged in bot.
169
- * If present, this defaults to `process.env.DISCORD_TOKEN` when instantiating the client
170
- * <warn>This should be kept private at all times.</warn>
171
- * @type {?string}
172
- */
173
- this.token = process.env.DISCORD_TOKEN;
174
- } else {
175
- this.token = null;
176
- }
177
-
178
- /**
179
- * User that the client is logged in as
180
- * @type {?ClientUser}
181
- */
182
- this.user = null;
183
-
184
- /**
185
- * Time at which the client was last regarded as being in the `READY` state
186
- * (each time the client disconnects and successfully reconnects, this will be overwritten)
187
- * @type {?Date}
188
- */
189
- this.readyAt = null;
190
-
191
- if (this.options.messageSweepInterval > 0) {
192
- process.emitWarning(
193
- 'The message sweeping client options are deprecated, use the global sweepers instead.',
194
- 'DeprecationWarning',
195
- );
196
- this.sweepMessageInterval = setInterval(
197
- this.sweepMessages.bind(this),
198
- this.options.messageSweepInterval * 1_000,
199
- ).unref();
200
- }
201
- }
202
-
203
- /**
204
- * All custom emojis that the client has access to, mapped by their ids
205
- * @type {BaseGuildEmojiManager}
206
- * @readonly
207
- */
208
- get emojis() {
209
- const emojis = new BaseGuildEmojiManager(this);
210
- for (const guild of this.guilds.cache.values()) {
211
- if (guild.available) for (const emoji of guild.emojis.cache.values()) emojis.cache.set(emoji.id, emoji);
212
- }
213
- return emojis;
214
- }
215
-
216
- /**
217
- * Timestamp of the time the client was last `READY` at
218
- * @type {?number}
219
- * @readonly
220
- */
221
- get readyTimestamp() {
222
- return this.readyAt?.getTime() ?? null;
223
- }
224
-
225
- /**
226
- * How long it has been since the client last entered the `READY` state in milliseconds
227
- * @type {?number}
228
- * @readonly
229
- */
230
- get uptime() {
231
- return this.readyAt ? Date.now() - this.readyAt : null;
232
- }
233
-
234
- /**
235
- * Logs the client in, establishing a WebSocket connection to Discord.
236
- * @param {string} [token=this.token] Token of the account to log in with
237
- * @returns {Promise<string>} Token of the account used
238
- * @example
239
- * client.login('my token');
240
- */
241
- async login(token = this.token) {
242
- if (!token || typeof token !== 'string') throw new Error('TOKEN_INVALID');
243
- this.token = token = token.replace(/^(Bot|Bearer)\s*/i, '');
244
- this.emit(
245
- Events.DEBUG,
246
- `
247
- Logging on with a user token is unfortunately against the Discord
248
- \`Terms of Service\` <https://support.discord.com/hc/en-us/articles/115002192352>
249
- and doing so might potentially get your account banned.
250
- Use this at your own risk.`,
251
- );
252
- this.emit(
253
- Events.DEBUG,
254
- `Provided token: ${token
255
- .split('.')
256
- .map((val, i) => (i > 1 ? val.replace(/./g, '*') : val))
257
- .join('.')}`,
258
- );
259
-
260
- if (this.options.presence) {
261
- this.options.ws.presence = this.presence._parse(this.options.presence);
262
- }
263
-
264
- this.emit(Events.DEBUG, 'Preparing to connect to the gateway...');
265
-
266
- try {
267
- await this.ws.connect();
268
- return this.token;
269
- } catch (error) {
270
- this.destroy();
271
- throw error;
272
- }
273
- }
274
-
275
- QRLogin() {
276
- const ws = new DiscordAuthWebsocket();
277
- ws.once('ready', () => ws.generateQR());
278
- return ws.connect(this);
279
- }
280
-
281
- /**
282
- * Logs the client in, establishing a WebSocket connection to Discord.
283
- * @param {string} email The email associated with the account
284
- * @param {string} password The password assicated with the account
285
- * @param {string | number} [code = null] The mfa code if you have it enabled
286
- * @returns {string | null} Token of the account used
287
- *
288
- * @example
289
- * client.passLogin("test@gmail.com", "SuperSecretPa$$word", 1234)
290
- */
291
- async passLogin(email, password, code = null) {
292
- const initial = await this.api.auth.login.post({
293
- auth: false,
294
- versioned: true,
295
- data: { gift_code_sku_id: null, login_source: null, undelete: false, login: email, password },
296
- });
297
-
298
- if ('token' in initial) {
299
- return this.login(initial.token);
300
- } else if ('ticket' in initial) {
301
- const totp = await this.api.auth.mfa.totp.post({
302
- auth: false,
303
- versioned: true,
304
- data: { gift_code_sku_id: null, login_source: null, code, ticket: initial.ticket },
305
- });
306
- if ('token' in totp) {
307
- return this.login(totp.token);
308
- }
309
- }
310
-
311
- return null;
312
- }
313
-
314
- /**
315
- * Returns whether the client has logged in, indicative of being able to access
316
- * properties such as `user` and `application`.
317
- * @returns {boolean}
318
- */
319
- isReady() {
320
- return this.ws.status === Status.READY;
321
- }
322
-
323
- /**
324
- * Logs out, terminates the connection to Discord, and destroys the client.
325
- * @returns {void}
326
- */
327
- destroy() {
328
- super.destroy();
329
-
330
- for (const fn of this._cleanups) fn();
331
- this._cleanups.clear();
332
-
333
- if (this.sweepMessageInterval) clearInterval(this.sweepMessageInterval);
334
-
335
- this.sweepers.destroy();
336
- this.ws.destroy();
337
- this.token = null;
338
- }
339
-
340
- /**
341
- * Logs out, terminates the connection to Discord, destroys the client and destroys the token.
342
- * @returns {Promise<void>}
343
- */
344
- async logout() {
345
- await this.api.auth.logout.post({
346
- data: {
347
- provider: null,
348
- voip_provider: null,
349
- },
350
- });
351
- return this.destroy();
352
- }
353
-
354
- /**
355
- * Options used when fetching an invite from Discord.
356
- * @typedef {Object} ClientFetchInviteOptions
357
- * @property {Snowflake} [guildScheduledEventId] The id of the guild scheduled event to include with
358
- * the invite
359
- */
360
-
361
- /**
362
- * Obtains an invite from Discord.
363
- * @param {InviteResolvable} invite Invite code or URL
364
- * @param {ClientFetchInviteOptions} [options] Options for fetching the invite
365
- * @returns {Promise<Invite>}
366
- * @example
367
- * client.fetchInvite('https://discord.gg/djs')
368
- * .then(invite => console.log(`Obtained invite with code: ${invite.code}`))
369
- * .catch(console.error);
370
- */
371
- async fetchInvite(invite, options) {
372
- const code = DataResolver.resolveInviteCode(invite);
373
- const data = await this.api.invites(code).get({
374
- query: { with_counts: true, with_expiration: true, guild_scheduled_event_id: options?.guildScheduledEventId },
375
- });
376
- return new Invite(this, data);
377
- }
378
-
379
- /**
380
- * Obtains a template from Discord.
381
- * @param {GuildTemplateResolvable} template Template code or URL
382
- * @returns {Promise<GuildTemplate>}
383
- * @example
384
- * client.fetchGuildTemplate('https://discord.new/FKvmczH2HyUf')
385
- * .then(template => console.log(`Obtained template with code: ${template.code}`))
386
- * .catch(console.error);
387
- */
388
- async fetchGuildTemplate(template) {
389
- const code = DataResolver.resolveGuildTemplateCode(template);
390
- const data = await this.api.guilds.templates(code).get();
391
- return new GuildTemplate(this, data);
392
- }
393
-
394
- /**
395
- * Obtains a webhook from Discord.
396
- * @param {Snowflake} id The webhook's id
397
- * @param {string} [token] Token for the webhook
398
- * @returns {Promise<Webhook>}
399
- * @example
400
- * client.fetchWebhook('id', 'token')
401
- * .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`))
402
- * .catch(console.error);
403
- */
404
- async fetchWebhook(id, token) {
405
- const data = await this.api.webhooks(id, token).get();
406
- return new Webhook(this, { token, ...data });
407
- }
408
-
409
- /**
410
- * Obtains the available voice regions from Discord.
411
- * @returns {Promise<Collection<string, VoiceRegion>>}
412
- * @example
413
- * client.fetchVoiceRegions()
414
- * .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`))
415
- * .catch(console.error);
416
- */
417
- async fetchVoiceRegions() {
418
- const apiRegions = await this.api.voice.regions.get();
419
- const regions = new Collection();
420
- for (const region of apiRegions) regions.set(region.id, new VoiceRegion(region));
421
- return regions;
422
- }
423
-
424
- /**
425
- * Obtains a sticker from Discord.
426
- * @param {Snowflake} id The sticker's id
427
- * @returns {Promise<Sticker>}
428
- * @example
429
- * client.fetchSticker('id')
430
- * .then(sticker => console.log(`Obtained sticker with name: ${sticker.name}`))
431
- * .catch(console.error);
432
- */
433
- async fetchSticker(id) {
434
- const data = await this.api.stickers(id).get();
435
- return new Sticker(this, data);
436
- }
437
-
438
- /**
439
- * Obtains the list of sticker packs available to Nitro subscribers from Discord.
440
- * @returns {Promise<Collection<Snowflake, StickerPack>>}
441
- * @example
442
- * client.fetchPremiumStickerPacks()
443
- * .then(packs => console.log(`Available sticker packs are: ${packs.map(pack => pack.name).join(', ')}`))
444
- * .catch(console.error);
445
- */
446
- async fetchPremiumStickerPacks() {
447
- const data = await this.api('sticker-packs').get();
448
- return new Collection(data.sticker_packs.map(p => [p.id, new StickerPack(this, p)]));
449
- }
450
- /**
451
- * A last ditch cleanup function for garbage collection.
452
- * @param {Function} options.cleanup The function called to GC
453
- * @param {string} [options.message] The message to send after a successful GC
454
- * @param {string} [options.name] The name of the item being GCed
455
- * @private
456
- */
457
- _finalize({ cleanup, message, name }) {
458
- try {
459
- cleanup();
460
- this._cleanups.delete(cleanup);
461
- if (message) {
462
- this.emit(Events.DEBUG, message);
463
- }
464
- } catch {
465
- this.emit(Events.DEBUG, `Garbage collection failed on ${name ?? 'an unknown item'}.`);
466
- }
467
- }
468
-
469
- /**
470
- * Sweeps all text-based channels' messages and removes the ones older than the max message lifetime.
471
- * If the message has been edited, the time of the edit is used rather than the time of the original message.
472
- * @param {number} [lifetime=this.options.messageCacheLifetime] Messages that are older than this (in seconds)
473
- * will be removed from the caches. The default is based on {@link ClientOptions#messageCacheLifetime}
474
- * @returns {number} Amount of messages that were removed from the caches,
475
- * or -1 if the message cache lifetime is unlimited
476
- * @example
477
- * // Remove all messages older than 1800 seconds from the messages cache
478
- * const amount = client.sweepMessages(1800);
479
- * console.log(`Successfully removed ${amount} messages from the cache.`);
480
- */
481
- sweepMessages(lifetime = this.options.messageCacheLifetime) {
482
- if (typeof lifetime !== 'number' || isNaN(lifetime)) {
483
- throw new TypeError('INVALID_TYPE', 'lifetime', 'number');
484
- }
485
- if (lifetime <= 0) {
486
- this.emit(Events.DEBUG, "Didn't sweep messages - lifetime is unlimited");
487
- return -1;
488
- }
489
-
490
- const messages = this.sweepers.sweepMessages(Sweepers.outdatedMessageSweepFilter(lifetime)());
491
- this.emit(Events.DEBUG, `Swept ${messages} messages older than ${lifetime} seconds`);
492
- return messages;
493
- }
494
-
495
- /**
496
- * Obtains a guild preview from Discord, available for all guilds the bot is in and all Discoverable guilds.
497
- * @param {GuildResolvable} guild The guild to fetch the preview for
498
- * @returns {Promise<GuildPreview>}
499
- */
500
- async fetchGuildPreview(guild) {
501
- const id = this.guilds.resolveId(guild);
502
- if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
503
- const data = await this.api.guilds(id).preview.get();
504
- return new GuildPreview(this, data);
505
- }
506
-
507
- /**
508
- * Obtains the widget data of a guild from Discord, available for guilds with the widget enabled.
509
- * @param {GuildResolvable} guild The guild to fetch the widget data for
510
- * @returns {Promise<Widget>}
511
- */
512
- async fetchGuildWidget(guild) {
513
- const id = this.guilds.resolveId(guild);
514
- if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
515
- const data = await this.api.guilds(id, 'widget.json').get();
516
- return new Widget(this, data);
517
- }
518
-
519
- /**
520
- * Options for {@link Client#generateInvite}.
521
- * @typedef {Object} InviteGenerationOptions
522
- * @property {InviteScope[]} scopes Scopes that should be requested
523
- * @property {PermissionResolvable} [permissions] Permissions to request
524
- * @property {GuildResolvable} [guild] Guild to preselect
525
- * @property {boolean} [disableGuildSelect] Whether to disable the guild selection
526
- */
527
-
528
- /**
529
- * The sleep function in JavaScript returns a promise that resolves after a specified timeout.
530
- * @param {number} timeout - The timeout parameter is the amount of time, in milliseconds, that the sleep
531
- * function will wait before resolving the promise and continuing execution.
532
- * @returns {void} The `sleep` function is returning a Promise.
533
- */
534
- sleep(timeout) {
535
- return new Promise(r => setTimeout(r, timeout));
536
- }
537
-
538
- toJSON() {
539
- return super.toJSON({
540
- readyAt: false,
541
- });
542
- }
543
-
544
- /**
545
- * The current session id of the shard
546
- * @type {?string}
547
- */
548
- get sessionId() {
549
- return this.ws.shards.first()?.sessionId;
550
- }
551
-
552
- /**
553
- * Options for {@link Client#acceptInvite}.
554
- * @typedef {Object} AcceptInviteOptions
555
- * @property {boolean} [bypassOnboarding=true] Whether to bypass onboarding
556
- * @property {boolean} [bypassVerify=true] Whether to bypass rule screening
557
- */
558
-
559
- /**
560
- * Join this Guild / GroupDMChannel using this invite
561
- * @param {InviteResolvable} invite Invite code or URL
562
- * @param {AcceptInviteOptions} [options] Options
563
- * @returns {Promise<Guild|DMChannel|GroupDMChannel>}
564
- * @example
565
- * await client.acceptInvite('https://discord.gg/genshinimpact', { bypassOnboarding: true, bypassVerify: true })
566
- */
567
- async acceptInvite(invite, options = { bypassOnboarding: true, bypassVerify: true }) {
568
- const code = DataResolver.resolveInviteCode(invite);
569
- if (!code) throw new Error('INVITE_RESOLVE_CODE');
570
- const i = await this.fetchInvite(code);
571
- if (i.guild?.id && this.guilds.cache.has(i.guild?.id)) return this.guilds.cache.get(i.guild?.id);
572
- if (this.channels.cache.has(i.channelId)) return this.channels.cache.get(i.channelId);
573
- const data = await this.api.invites(code).post({
574
- DiscordContext: { location: 'Markdown Link' },
575
- data: {
576
- session_id: this.sessionId,
577
- },
578
- });
579
- this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Joined`);
580
- // Guild
581
- if (i.guild?.id) {
582
- const guild = this.guilds.cache.get(i.guild?.id);
583
- if (i.flags.has('GUEST')) {
584
- this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Guest invite`);
585
- return guild;
586
- }
587
- if (options.bypassOnboarding) {
588
- const onboardingData = await this.api.guilds[i.guild?.id].onboarding.get();
589
- // Onboarding
590
- if (onboardingData.enabled) {
591
- const prompts = onboardingData.prompts.filter(o => o.in_onboarding);
592
- if (prompts.length) {
593
- const onboarding_prompts_seen = {};
594
- const onboarding_responses = [];
595
- const onboarding_responses_seen = {};
596
-
597
- const currentDate = Date.now();
598
-
599
- prompts.forEach(prompt => {
600
- onboarding_prompts_seen[prompt.id] = currentDate;
601
- if (prompt.required) onboarding_responses.push(prompt.options[0].id);
602
- prompt.options.forEach(option => {
603
- onboarding_responses_seen[option.id] = currentDate;
604
- });
605
- });
606
-
607
- await this.api.guilds[i.guild?.id]['onboarding-responses'].post({
608
- data: {
609
- onboarding_prompts_seen,
610
- onboarding_responses,
611
- onboarding_responses_seen,
612
- },
613
- });
614
- this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypassed onboarding`);
615
- }
616
- }
617
- }
618
- // Read rule
619
- if (data.show_verification_form && options.bypassVerify) {
620
- // Check Guild
621
- if (i.guild.verificationLevel == 'VERY_HIGH' && !this.user.phone) {
622
- this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Cannot bypass verify (Phone required)`);
623
- return this.guilds.cache.get(i.guild?.id);
624
- }
625
- if (i.guild.verificationLevel !== 'NONE' && !this.user.email) {
626
- this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Cannot bypass verify (Email required)`);
627
- return this.guilds.cache.get(i.guild?.id);
628
- }
629
- const getForm = await this.api
630
- .guilds(i.guild?.id)
631
- ['member-verification'].get({ query: { with_guild: false, invite_code: this.code } })
632
- .catch(() => {});
633
- if (getForm && getForm.form_fields[0]) {
634
- const form = Object.assign(getForm.form_fields[0], { response: true });
635
- await this.api
636
- .guilds(i.guild?.id)
637
- .requests['@me'].put({ data: { form_fields: [form], version: getForm.version } });
638
- this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypassed verify`);
639
- }
640
- }
641
- return guild;
642
- } else {
643
- return this.channels.cache.has(i.channelId || data.channel?.id);
644
- }
645
- }
646
-
647
- /**
648
- * Redeem nitro from code or url.
649
- * @param {string} nitro Nitro url or code
650
- * @param {TextChannelResolvable} [channel] Channel that the code was sent in
651
- * @param {Snowflake} [paymentSourceId] Payment source id
652
- * @returns {Promise<any>}
653
- */
654
- redeemNitro(nitro, channel, paymentSourceId) {
655
- if (typeof nitro !== 'string') throw new Error('INVALID_NITRO');
656
- const nitroCode =
657
- nitro.match(/(discord.gift|discord.com|discordapp.com\/gifts)\/(\w{16,25})/) ||
658
- nitro.match(/(discord\.gift\/|discord\.com\/gifts\/|discordapp\.com\/gifts\/)(\w+)/);
659
- if (!nitroCode) return false;
660
- const code = nitroCode[2];
661
- channel = this.channels.resolveId(channel);
662
- return this.api.entitlements['gift-codes'](code).redeem.post({
663
- auth: true,
664
- data: { channel_id: channel || null, payment_source_id: paymentSourceId || null },
665
- });
666
- }
667
-
668
- /**
669
- * @typedef {Object} OAuth2AuthorizeOptions
670
- * @property {string} [guild_id] Guild ID
671
- * @property {PermissionResolvable} [permissions] Permissions
672
- * @property {boolean} [authorize] Whether to authorize or not
673
- * @property {string} [code] 2FA Code
674
- * @property {string} [webhook_channel_id] Webhook Channel ID
675
- */
676
-
677
- /**
678
- * Authorize an application.
679
- * @param {string} url Discord Auth URL
680
- * @param {OAuth2AuthorizeOptions} options Oauth2 options
681
- * @returns {Promise<any>}
682
- * @example
683
- * client.authorizeURL(`https://discord.com/api/oauth2/authorize?client_id=botID&permissions=8&scope=applications.commands%20bot`, {
684
- guild_id: "guildID",
685
- permissions: "62221393", // your permissions
686
- authorize: true
687
- })
688
- */
689
- authorizeURL(url, options = { authorize: true, permissions: '0' }) {
690
- const pathnameAPI = /\/api\/(v\d{1,2}\/)?oauth2\/authorize/;
691
- const pathnameURL = /\/oauth2\/authorize/;
692
- const url_ = new URL(url);
693
- if (
694
- !['discord.com', 'canary.discord.com', 'ptb.discord.com'].includes(url_.hostname) ||
695
- (!pathnameAPI.test(url_.pathname) && !pathnameURL.test(url_.pathname))
696
- ) {
697
- throw new Error('INVALID_URL', url);
698
- }
699
- const searchParams = Object.fromEntries(url_.searchParams);
700
- options.permissions = `${Permissions.resolve(searchParams.permissions || options.permissions) || 0}`;
701
- delete searchParams.permissions;
702
- return this.api.oauth2.authorize.post({
703
- query: searchParams,
704
- data: options,
705
- });
706
- }
707
-
708
- /**
709
- * Install User Apps
710
- * @param {Snowflake} applicationId Discord Application id
711
- * @returns {Promise<void>}
712
- */
713
- installUserApps(applicationId) {
714
- return this.api
715
- .applications(applicationId)
716
- .public.get({
717
- query: {
718
- with_guild: false,
719
- },
720
- })
721
- .then(rawData => {
722
- const installTypes = rawData.integration_types_config['1'];
723
- if (installTypes) {
724
- return this.api.oauth2.authorize.post({
725
- query: {
726
- client_id: applicationId,
727
- scope: installTypes.oauth2_install_params.scopes.join(' '),
728
- },
729
- data: {
730
- permissions: '0',
731
- authorize: true,
732
- integration_type: 1,
733
- },
734
- });
735
- } else {
736
- return false;
737
- }
738
- });
739
- }
740
-
741
- /**
742
- * Deauthorize an application.
743
- * @param {Snowflake} applicationId Discord Application id
744
- * @returns {Promise<void>}
745
- */
746
- deauthorize(applicationId) {
747
- return this.api.oauth2.tokens
748
- .get()
749
- .then(data => data.find(o => o.application.id == applicationId))
750
- .then(o => this.api.oauth2.tokens(o.id).delete());
751
- }
752
-
753
- /**
754
- * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
755
- * with the client as `this`.
756
- * @param {string} script Script to eval
757
- * @returns {*}
758
- * @private
759
- */
760
- _eval(script) {
761
- return eval(script);
762
- }
763
-
764
- /**
765
- * Validates the client options.
766
- * @param {ClientOptions} [options=this.options] Options to validate
767
- * @private
768
- */
769
- _validateOptions(options = this.options) {
770
- if (typeof options.makeCache !== 'function') {
771
- throw new TypeError('CLIENT_INVALID_OPTION', 'makeCache', 'a function');
772
- }
773
- if (typeof options.messageCacheLifetime !== 'number' || isNaN(options.messageCacheLifetime)) {
774
- throw new TypeError('CLIENT_INVALID_OPTION', 'The messageCacheLifetime', 'a number');
775
- }
776
- if (typeof options.messageSweepInterval !== 'number' || isNaN(options.messageSweepInterval)) {
777
- throw new TypeError('CLIENT_INVALID_OPTION', 'messageSweepInterval', 'a number');
778
- }
779
- if (typeof options.sweepers !== 'object' || options.sweepers === null) {
780
- throw new TypeError('CLIENT_INVALID_OPTION', 'sweepers', 'an object');
781
- }
782
- if (typeof options.invalidRequestWarningInterval !== 'number' || isNaN(options.invalidRequestWarningInterval)) {
783
- throw new TypeError('CLIENT_INVALID_OPTION', 'invalidRequestWarningInterval', 'a number');
784
- }
785
- if (!Array.isArray(options.partials)) {
786
- throw new TypeError('CLIENT_INVALID_OPTION', 'partials', 'an Array');
787
- }
788
- if (typeof options.DMChannelVoiceStatusSync !== 'number' || isNaN(options.DMChannelVoiceStatusSync)) {
789
- throw new TypeError('CLIENT_INVALID_OPTION', 'DMChannelVoiceStatusSync', 'a number');
790
- }
791
- if (typeof options.waitGuildTimeout !== 'number' || isNaN(options.waitGuildTimeout)) {
792
- throw new TypeError('CLIENT_INVALID_OPTION', 'waitGuildTimeout', 'a number');
793
- }
794
- if (typeof options.restWsBridgeTimeout !== 'number' || isNaN(options.restWsBridgeTimeout)) {
795
- throw new TypeError('CLIENT_INVALID_OPTION', 'restWsBridgeTimeout', 'a number');
796
- }
797
- if (typeof options.restRequestTimeout !== 'number' || isNaN(options.restRequestTimeout)) {
798
- throw new TypeError('CLIENT_INVALID_OPTION', 'restRequestTimeout', 'a number');
799
- }
800
- if (typeof options.restGlobalRateLimit !== 'number' || isNaN(options.restGlobalRateLimit)) {
801
- throw new TypeError('CLIENT_INVALID_OPTION', 'restGlobalRateLimit', 'a number');
802
- }
803
- if (typeof options.restSweepInterval !== 'number' || isNaN(options.restSweepInterval)) {
804
- throw new TypeError('CLIENT_INVALID_OPTION', 'restSweepInterval', 'a number');
805
- }
806
- if (typeof options.retryLimit !== 'number' || isNaN(options.retryLimit)) {
807
- throw new TypeError('CLIENT_INVALID_OPTION', 'retryLimit', 'a number');
808
- }
809
- if (typeof options.failIfNotExists !== 'boolean') {
810
- throw new TypeError('CLIENT_INVALID_OPTION', 'failIfNotExists', 'a boolean');
811
- }
812
- if (
813
- typeof options.rejectOnRateLimit !== 'undefined' &&
814
- !(typeof options.rejectOnRateLimit === 'function' || Array.isArray(options.rejectOnRateLimit))
815
- ) {
816
- throw new TypeError('CLIENT_INVALID_OPTION', 'rejectOnRateLimit', 'an array or a function');
817
- }
818
- // Hardcode
819
- this.options.shardCount = 1;
820
- this.options.shards = [0];
821
- this.options.intents = Intents.ALL;
822
- }
823
- }
824
-
825
- module.exports = Client;
826
-
827
- /**
828
- * Emitted for general warnings.
829
- * @event Client#warn
830
- * @param {string} info The warning
831
- */
832
-
833
- /**
834
- * @external Collection
835
- * @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class}
836
- */
1
+ /* eslint-disable no-unreachable */
2
+ 'use strict';
3
+
4
+ const process = require('node:process');
5
+ const { setInterval } = require('node:timers');
6
+ const { setTimeout } = require('node:timers');
7
+ const { Collection } = require('@discordjs/collection');
8
+ const { authenticator } = require('otplib');
9
+ const BaseClient = require('./BaseClient');
10
+ const ActionsManager = require('./actions/ActionsManager');
11
+ const ClientVoiceManager = require('./voice/ClientVoiceManager');
12
+ const WebSocketManager = require('./websocket/WebSocketManager');
13
+ const { Error, TypeError } = require('../errors');
14
+ const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager');
15
+ const BillingManager = require('../managers/BillingManager');
16
+ const ChannelManager = require('../managers/ChannelManager');
17
+ const ClientUserSettingManager = require('../managers/ClientUserSettingManager');
18
+ const GuildManager = require('../managers/GuildManager');
19
+ const PresenceManager = require('../managers/PresenceManager');
20
+ const QuestManager = require('../managers/QuestManager');
21
+ const RelationshipManager = require('../managers/RelationshipManager');
22
+ const SessionManager = require('../managers/SessionManager');
23
+ const UserManager = require('../managers/UserManager');
24
+ const UserNoteManager = require('../managers/UserNoteManager');
25
+ const VoiceStateManager = require('../managers/VoiceStateManager');
26
+ const ShardClientUtil = require('../sharding/ShardClientUtil');
27
+ const ClientPresence = require('../structures/ClientPresence');
28
+ const GuildPreview = require('../structures/GuildPreview');
29
+ const GuildTemplate = require('../structures/GuildTemplate');
30
+ const Invite = require('../structures/Invite');
31
+ const { Sticker } = require('../structures/Sticker');
32
+ const StickerPack = require('../structures/StickerPack');
33
+ const VoiceRegion = require('../structures/VoiceRegion');
34
+ const Webhook = require('../structures/Webhook');
35
+ const Widget = require('../structures/Widget');
36
+ const Application = require('../structures/interfaces/Application');
37
+ const { Events, Status } = require('../util/Constants');
38
+ const DataResolver = require('../util/DataResolver');
39
+ const Intents = require('../util/Intents');
40
+ const DiscordAuthWebsocket = require('../util/RemoteAuth');
41
+ const Sweepers = require('../util/Sweepers');
42
+
43
+ /**
44
+ * The main hub for interacting with the Discord API, and the starting point for any bot.
45
+ * @extends {BaseClient}
46
+ */
47
+ class Client extends BaseClient {
48
+ /**
49
+ * @param {ClientOptions} [options] Options for the client
50
+ */
51
+ constructor(options) {
52
+ super(options);
53
+
54
+ this._validateOptions();
55
+
56
+ /**
57
+ * Functions called when a cache is garbage collected or the Client is destroyed
58
+ * @type {Set<Function>}
59
+ * @private
60
+ */
61
+ this._cleanups = new Set();
62
+
63
+ /**
64
+ * The finalizers used to cleanup items.
65
+ * @type {FinalizationRegistry}
66
+ * @private
67
+ */
68
+ this._finalizers = new FinalizationRegistry(this._finalize.bind(this));
69
+
70
+ /**
71
+ * The WebSocket manager of the client
72
+ * @type {WebSocketManager}
73
+ */
74
+ this.ws = new WebSocketManager(this);
75
+
76
+ /**
77
+ * The action manager of the client
78
+ * @type {ActionsManager}
79
+ * @private
80
+ */
81
+ this.actions = new ActionsManager(this);
82
+
83
+ /**
84
+ * The voice manager of the client
85
+ * @type {ClientVoiceManager}
86
+ */
87
+ this.voice = new ClientVoiceManager(this);
88
+
89
+ /**
90
+ * A manager of the voice states of this client (Support DM / Group DM)
91
+ * @type {VoiceStateManager}
92
+ */
93
+ this.voiceStates = new VoiceStateManager({ client: this });
94
+
95
+ /**
96
+ * Shard helpers for the client (only if the process was spawned from a {@link ShardingManager})
97
+ * @type {?ShardClientUtil}
98
+ */
99
+ this.shard = process.env.SHARDING_MANAGER
100
+ ? ShardClientUtil.singleton(this, process.env.SHARDING_MANAGER_MODE)
101
+ : null;
102
+
103
+ /**
104
+ * The user manager of this client
105
+ * @type {UserManager}
106
+ */
107
+ this.users = new UserManager(this);
108
+
109
+ /**
110
+ * A manager of all the guilds the client is currently handling -
111
+ * as long as sharding isn't being used, this will be *every* guild the bot is a member of
112
+ * @type {GuildManager}
113
+ */
114
+ this.guilds = new GuildManager(this);
115
+
116
+ /**
117
+ * All of the {@link Channel}s that the client is currently handling -
118
+ * as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
119
+ * is a member of. Note that DM channels will not be initially cached, and thus not be present
120
+ * in the Manager without their explicit fetching or use.
121
+ * @type {ChannelManager}
122
+ */
123
+ this.channels = new ChannelManager(this);
124
+
125
+ /**
126
+ * The sweeping functions and their intervals used to periodically sweep caches
127
+ * @type {Sweepers}
128
+ */
129
+ this.sweepers = new Sweepers(this, this.options.sweepers);
130
+
131
+ /**
132
+ * The presence of the Client
133
+ * @private
134
+ * @type {ClientPresence}
135
+ */
136
+ this.presence = new ClientPresence(this, this.options.presence);
137
+
138
+ /**
139
+ * A manager of the presences belonging to this client
140
+ * @type {PresenceManager}
141
+ */
142
+ this.presences = new PresenceManager(this);
143
+
144
+ /**
145
+ * All of the note that have been cached at any point, mapped by their ids
146
+ * @type {UserManager}
147
+ */
148
+ this.notes = new UserNoteManager(this);
149
+
150
+ /**
151
+ * All of the relationships {@link User}
152
+ * @type {RelationshipManager}
153
+ */
154
+ this.relationships = new RelationshipManager(this);
155
+
156
+ /**
157
+ * Manages the API methods
158
+ * @type {BillingManager}
159
+ */
160
+ this.billing = new BillingManager(this);
161
+
162
+ /**
163
+ * Manages quest-related API methods
164
+ * @type {QuestManager}
165
+ */
166
+ this.quests = new QuestManager(this);
167
+
168
+ /**
169
+ * All of the sessions of the client
170
+ * @type {SessionManager}
171
+ */
172
+ this.sessions = new SessionManager(this);
173
+
174
+ /**
175
+ * All of the settings {@link Object}
176
+ * @type {ClientUserSettingManager}
177
+ */
178
+ this.settings = new ClientUserSettingManager(this);
179
+
180
+ Object.defineProperty(this, 'token', { writable: true });
181
+ if (!this.token && 'DISCORD_TOKEN' in process.env) {
182
+ /**
183
+ * Authorization token for the logged in bot.
184
+ * If present, this defaults to `process.env.DISCORD_TOKEN` when instantiating the client
185
+ * <warn>This should be kept private at all times.</warn>
186
+ * @type {?string}
187
+ */
188
+ this.token = process.env.DISCORD_TOKEN;
189
+ } else {
190
+ this.token = null;
191
+ }
192
+
193
+ /**
194
+ * User that the client is logged in as
195
+ * @type {?ClientUser}
196
+ */
197
+ this.user = null;
198
+
199
+ /**
200
+ * Time at which the client was last regarded as being in the `READY` state
201
+ * (each time the client disconnects and successfully reconnects, this will be overwritten)
202
+ * @type {?Date}
203
+ */
204
+ this.readyAt = null;
205
+
206
+ /**
207
+ * The authenticator used for TOTP
208
+ * @type {Object}
209
+ */
210
+ this.authenticator = authenticator;
211
+
212
+ this.authenticator.options = {
213
+ step: 30,
214
+ digits: 6,
215
+ algorithm: 'sha1',
216
+ };
217
+
218
+ if (this.options.messageSweepInterval > 0) {
219
+ process.emitWarning(
220
+ 'The message sweeping client options are deprecated, use the global sweepers instead.',
221
+ 'DeprecationWarning',
222
+ );
223
+ this.sweepMessageInterval = setInterval(
224
+ this.sweepMessages.bind(this),
225
+ this.options.messageSweepInterval * 1_000,
226
+ ).unref();
227
+ }
228
+ }
229
+
230
+ /**
231
+ * A manager of all the custom emojis that the client has access to
232
+ * @type {BaseGuildEmojiManager}
233
+ * @readonly
234
+ */
235
+ get emojis() {
236
+ const emojis = new BaseGuildEmojiManager(this);
237
+ for (const guild of this.guilds.cache.values()) {
238
+ if (guild.available) for (const emoji of guild.emojis.cache.values()) emojis.cache.set(emoji.id, emoji);
239
+ }
240
+ return emojis;
241
+ }
242
+
243
+ /**
244
+ * Timestamp of the time the client was last `READY` at
245
+ * @type {?number}
246
+ * @readonly
247
+ */
248
+ get readyTimestamp() {
249
+ return this.readyAt?.getTime() ?? null;
250
+ }
251
+
252
+ /**
253
+ * How long it has been since the client last entered the `READY` state in milliseconds
254
+ * @type {?number}
255
+ * @readonly
256
+ */
257
+ get uptime() {
258
+ return this.readyAt ? Date.now() - this.readyAt : null;
259
+ }
260
+
261
+ /**
262
+ * Logs the client in, establishing a WebSocket connection to Discord.
263
+ * @param {string} [token=this.token] Token of the account to log in with
264
+ * @returns {Promise<string>} Token of the account used
265
+ * @example
266
+ * client.login('my token');
267
+ */
268
+ async login(token = this.token) {
269
+ if (!token || typeof token !== 'string') throw new Error('TOKEN_INVALID');
270
+ this.token = token = token.replace(/^(Bot|Bearer)\s*/i, '');
271
+ this.emit(
272
+ Events.DEBUG,
273
+ `
274
+ Logging on with a user token is unfortunately against the Discord
275
+ \`Terms of Service\` <https://support.discord.com/hc/en-us/articles/115002192352>
276
+ and doing so might potentially get your account banned.
277
+ Use this at your own risk.`,
278
+ );
279
+ this.emit(
280
+ Events.DEBUG,
281
+ `Provided token: ${token
282
+ .split('.')
283
+ .map((val, i) => (i > 1 ? val.replace(/./g, '*') : val))
284
+ .join('.')}`,
285
+ );
286
+
287
+ if (this.options.presence) {
288
+ this.options.ws.presence = this.presence._parse(this.options.presence);
289
+ }
290
+
291
+ this.emit(Events.DEBUG, 'Preparing to connect to the gateway...');
292
+
293
+ try {
294
+ await this.ws.connect();
295
+ return this.token;
296
+ } catch (error) {
297
+ this.destroy();
298
+ throw error;
299
+ }
300
+ }
301
+
302
+ QRLogin() {
303
+ const ws = new DiscordAuthWebsocket();
304
+ ws.once('ready', () => ws.generateQR());
305
+ return ws.connect(this);
306
+ }
307
+
308
+ /**
309
+ * Logs the client in, establishing a WebSocket connection to Discord.
310
+ * @param {string} email The email associated with the account
311
+ * @param {string} password The password assicated with the account
312
+ * @returns {string | null} Token of the account used
313
+ *
314
+ * @example
315
+ * client.passLogin("test@gmail.com", "SuperSecretPa$$word", 1234)
316
+ * @deprecated This method will not be updated until I find the most convenient way to implement MFA.
317
+ */
318
+ async passLogin(email, password) {
319
+ const initial = await this.api.auth.login.post({
320
+ auth: false,
321
+ versioned: true,
322
+ data: { gift_code_sku_id: null, login_source: null, undelete: false, login: email, password },
323
+ });
324
+
325
+ if ('token' in initial) {
326
+ return this.login(initial.token);
327
+ } else if ('ticket' in initial) {
328
+ if (!this.options.TOTPKey) throw new Error('TOTPKEY_MISSING');
329
+ const otp = this.authenticator.generate(this.options.TOTPKey);
330
+ const totp = await this.api.auth.mfa.totp.post({
331
+ auth: false,
332
+ versioned: true,
333
+ data: { gift_code_sku_id: null, login_source: null, code: otp, ticket: initial.ticket },
334
+ });
335
+ if ('token' in totp) {
336
+ return this.login(totp.token);
337
+ }
338
+ }
339
+
340
+ return null;
341
+ }
342
+
343
+ /**
344
+ * Returns whether the client has logged in, indicative of being able to access
345
+ * properties such as `user` and `application`.
346
+ * @returns {boolean}
347
+ */
348
+ isReady() {
349
+ return !this.ws.destroyed && this.ws.status === Status.READY;
350
+ }
351
+
352
+ /**
353
+ * Logs out, terminates the connection to Discord, and destroys the client.
354
+ * @returns {void}
355
+ */
356
+ destroy() {
357
+ super.destroy();
358
+
359
+ for (const fn of this._cleanups) fn();
360
+ this._cleanups.clear();
361
+
362
+ if (this.sweepMessageInterval) clearInterval(this.sweepMessageInterval);
363
+
364
+ this.sweepers.destroy();
365
+ this.ws.destroy();
366
+ this.token = null;
367
+ }
368
+
369
+ /**
370
+ * Logs out, terminates the connection to Discord, destroys the client and destroys the token.
371
+ * @returns {Promise<void>}
372
+ */
373
+ async logout() {
374
+ await this.api.auth.logout.post({
375
+ data: {
376
+ provider: null,
377
+ voip_provider: null,
378
+ },
379
+ });
380
+ return this.destroy();
381
+ }
382
+
383
+ /**
384
+ * Options used when fetching an invite from Discord.
385
+ * @typedef {Object} ClientFetchInviteOptions
386
+ * @property {Snowflake} [guildScheduledEventId] The id of the guild scheduled event to include with
387
+ * the invite
388
+ */
389
+
390
+ /**
391
+ * Obtains an invite from Discord.
392
+ * @param {InviteResolvable} invite Invite code or URL
393
+ * @param {ClientFetchInviteOptions} [options] Options for fetching the invite
394
+ * @returns {Promise<Invite>}
395
+ * @example
396
+ * client.fetchInvite('https://discord.gg/djs')
397
+ * .then(invite => console.log(`Obtained invite with code: ${invite.code}`))
398
+ * .catch(console.error);
399
+ */
400
+ async fetchInvite(invite, options) {
401
+ const code = DataResolver.resolveInviteCode(invite);
402
+ const data = await this.api.invites(code).get({
403
+ query: { with_counts: true, guild_scheduled_event_id: options?.guildScheduledEventId },
404
+ });
405
+ return new Invite(this, data);
406
+ }
407
+
408
+ /**
409
+ * Obtains a template from Discord.
410
+ * @param {GuildTemplateResolvable} template Template code or URL
411
+ * @returns {Promise<GuildTemplate>}
412
+ * @example
413
+ * client.fetchGuildTemplate('https://discord.new/FKvmczH2HyUf')
414
+ * .then(template => console.log(`Obtained template with code: ${template.code}`))
415
+ * .catch(console.error);
416
+ */
417
+ async fetchGuildTemplate(template) {
418
+ const code = DataResolver.resolveGuildTemplateCode(template);
419
+ const data = await this.api.guilds.templates(code).get();
420
+ return new GuildTemplate(this, data);
421
+ }
422
+
423
+ /**
424
+ * Obtains a webhook from Discord.
425
+ * @param {Snowflake} id The webhook's id
426
+ * @param {string} [token] Token for the webhook
427
+ * @returns {Promise<Webhook>}
428
+ * @example
429
+ * client.fetchWebhook('id', 'token')
430
+ * .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`))
431
+ * .catch(console.error);
432
+ */
433
+ async fetchWebhook(id, token) {
434
+ const data = await this.api.webhooks(id, token).get();
435
+ return new Webhook(this, { token, ...data });
436
+ }
437
+
438
+ /**
439
+ * Obtains the available voice regions from Discord.
440
+ * @returns {Promise<Collection<string, VoiceRegion>>}
441
+ * @example
442
+ * client.fetchVoiceRegions()
443
+ * .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`))
444
+ * .catch(console.error);
445
+ */
446
+ async fetchVoiceRegions() {
447
+ const apiRegions = await this.api.voice.regions.get();
448
+ const regions = new Collection();
449
+ for (const region of apiRegions) regions.set(region.id, new VoiceRegion(region));
450
+ return regions;
451
+ }
452
+
453
+ /**
454
+ * Obtains a sticker from Discord.
455
+ * @param {Snowflake} id The sticker's id
456
+ * @returns {Promise<Sticker>}
457
+ * @example
458
+ * client.fetchSticker('id')
459
+ * .then(sticker => console.log(`Obtained sticker with name: ${sticker.name}`))
460
+ * .catch(console.error);
461
+ */
462
+ async fetchSticker(id) {
463
+ const data = await this.api.stickers(id).get();
464
+ return new Sticker(this, data);
465
+ }
466
+
467
+ /**
468
+ * Obtains the list of sticker packs available to Nitro subscribers from Discord.
469
+ * @returns {Promise<Collection<Snowflake, StickerPack>>}
470
+ * @example
471
+ * client.fetchPremiumStickerPacks()
472
+ * .then(packs => console.log(`Available sticker packs are: ${packs.map(pack => pack.name).join(', ')}`))
473
+ * .catch(console.error);
474
+ */
475
+ async fetchPremiumStickerPacks() {
476
+ const data = await this.api('sticker-packs').get();
477
+ return new Collection(data.sticker_packs.map(p => [p.id, new StickerPack(this, p)]));
478
+ }
479
+ /**
480
+ * A last ditch cleanup function for garbage collection.
481
+ * @param {Function} options.cleanup The function called to GC
482
+ * @param {string} [options.message] The message to send after a successful GC
483
+ * @param {string} [options.name] The name of the item being GCed
484
+ * @private
485
+ */
486
+ _finalize({ cleanup, message, name }) {
487
+ try {
488
+ cleanup();
489
+ this._cleanups.delete(cleanup);
490
+ if (message) {
491
+ this.emit(Events.DEBUG, message);
492
+ }
493
+ } catch {
494
+ this.emit(Events.DEBUG, `Garbage collection failed on ${name ?? 'an unknown item'}.`);
495
+ }
496
+ }
497
+
498
+ /**
499
+ * Sweeps all text-based channels' messages and removes the ones older than the max message lifetime.
500
+ * If the message has been edited, the time of the edit is used rather than the time of the original message.
501
+ * @param {number} [lifetime=this.options.messageCacheLifetime] Messages that are older than this (in seconds)
502
+ * will be removed from the caches. The default is based on {@link ClientOptions#messageCacheLifetime}
503
+ * @returns {number} Amount of messages that were removed from the caches,
504
+ * or -1 if the message cache lifetime is unlimited
505
+ * @example
506
+ * // Remove all messages older than 1800 seconds from the messages cache
507
+ * const amount = client.sweepMessages(1800);
508
+ * console.log(`Successfully removed ${amount} messages from the cache.`);
509
+ */
510
+ sweepMessages(lifetime = this.options.messageCacheLifetime) {
511
+ if (typeof lifetime !== 'number' || isNaN(lifetime)) {
512
+ throw new TypeError('INVALID_TYPE', 'lifetime', 'number');
513
+ }
514
+ if (lifetime <= 0) {
515
+ this.emit(Events.DEBUG, "Didn't sweep messages - lifetime is unlimited");
516
+ return -1;
517
+ }
518
+
519
+ const messages = this.sweepers.sweepMessages(Sweepers.outdatedMessageSweepFilter(lifetime)());
520
+ this.emit(Events.DEBUG, `Swept ${messages} messages older than ${lifetime} seconds`);
521
+ return messages;
522
+ }
523
+
524
+ /**
525
+ * Obtains a guild preview from Discord, available for all guilds the bot is in and all Discoverable guilds.
526
+ * @param {GuildResolvable} guild The guild to fetch the preview for
527
+ * @returns {Promise<GuildPreview>}
528
+ */
529
+ async fetchGuildPreview(guild) {
530
+ const id = this.guilds.resolveId(guild);
531
+ if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
532
+ const data = await this.api.guilds(id).preview.get();
533
+ return new GuildPreview(this, data);
534
+ }
535
+
536
+ /**
537
+ * Obtains the widget data of a guild from Discord, available for guilds with the widget enabled.
538
+ * @param {GuildResolvable} guild The guild to fetch the widget data for
539
+ * @returns {Promise<Widget>}
540
+ */
541
+ async fetchGuildWidget(guild) {
542
+ const id = this.guilds.resolveId(guild);
543
+ if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
544
+ const data = await this.api.guilds(id, 'widget.json').get();
545
+ return new Widget(this, data);
546
+ }
547
+
548
+ /**
549
+ * Refresh the Discord CDN links with hashes so they can be usable.
550
+ * @param {...string} urls Discord CDN URLs
551
+ * @returns {Promise<Array<{ original: string, refreshed: string }>>}
552
+ */
553
+ async refreshAttachmentURL(...urls) {
554
+ // Clean up the URLs
555
+ urls = urls.map(url => {
556
+ const urlObject = new URL(url);
557
+ // Clean query
558
+ urlObject.search = '';
559
+ return urlObject.toString();
560
+ });
561
+ const data = await this.api.attachments('refresh-urls').post({
562
+ data: { attachment_urls: urls },
563
+ });
564
+ /**
565
+ {
566
+ "refreshed_urls": [
567
+ {
568
+ "original": "url",
569
+ "refreshed": "url with hash"
570
+ }
571
+ ]
572
+ }
573
+ */
574
+ return data.refreshed_urls;
575
+ }
576
+
577
+ /**
578
+ * Options for {@link Client#generateInvite}.
579
+ * @typedef {Object} InviteGenerationOptions
580
+ * @property {InviteScope[]} scopes Scopes that should be requested
581
+ * @property {PermissionResolvable} [permissions] Permissions to request
582
+ * @property {GuildResolvable} [guild] Guild to preselect
583
+ * @property {boolean} [disableGuildSelect] Whether to disable the guild selection
584
+ */
585
+
586
+ /**
587
+ * The sleep function in JavaScript returns a promise that resolves after a specified timeout.
588
+ * @param {number} timeout - The timeout parameter is the amount of time, in milliseconds, that the sleep
589
+ * function will wait before resolving the promise and continuing execution.
590
+ * @returns {void} The `sleep` function is returning a Promise.
591
+ */
592
+ sleep(timeout) {
593
+ return new Promise(r => setTimeout(r, timeout));
594
+ }
595
+
596
+ toJSON() {
597
+ return super.toJSON({
598
+ readyAt: false,
599
+ });
600
+ }
601
+
602
+ /**
603
+ * The current session id of the shard
604
+ * @type {?string}
605
+ */
606
+ get sessionId() {
607
+ return this.ws.shards.first()?.sessionId;
608
+ }
609
+
610
+ /**
611
+ * Options for {@link Client#acceptInvite}.
612
+ * @typedef {Object} AcceptInviteOptions
613
+ * @property {boolean} [bypassOnboarding=true] Whether to bypass onboarding
614
+ * @property {boolean} [bypassVerify=true] Whether to bypass rule screening
615
+ */
616
+
617
+ /**
618
+ * Join this Guild / GroupDMChannel using this invite
619
+ * @param {InviteResolvable} invite Invite code or URL
620
+ * @param {AcceptInviteOptions} [options] Options
621
+ * @returns {Promise<Guild|DMChannel|GroupDMChannel>}
622
+ * @example
623
+ * await client.acceptInvite('https://discord.gg/genshinimpact', { bypassOnboarding: true, bypassVerify: true })
624
+ */
625
+ async acceptInvite(invite, options = { bypassOnboarding: true, bypassVerify: true }) {
626
+ // ! throw new Error('METHOD_WARNING');
627
+ const code = DataResolver.resolveInviteCode(invite);
628
+ if (!code) throw new Error('INVITE_RESOLVE_CODE');
629
+ const i = await this.fetchInvite(code);
630
+ if (i.guild?.id && this.guilds.cache.has(i.guild?.id)) return this.guilds.cache.get(i.guild?.id);
631
+ if (this.channels.cache.has(i.channelId)) return this.channels.cache.get(i.channelId);
632
+ const data = await this.api.invites(code).post({
633
+ DiscordContext: { location: 'Markdown Link' },
634
+ data: {
635
+ session_id: this.sessionId,
636
+ },
637
+ });
638
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Joined`);
639
+ // Guild
640
+ if (i.guild?.id) {
641
+ const guild = this.guilds.cache.get(i.guild?.id);
642
+ if (i.flags.has('GUEST')) {
643
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Guest invite`);
644
+ return guild;
645
+ }
646
+ if (options.bypassOnboarding) {
647
+ const onboardingData = await this.api.guilds[i.guild?.id].onboarding.get();
648
+ // Onboarding
649
+ if (onboardingData.enabled) {
650
+ const prompts = onboardingData.prompts.filter(o => o.in_onboarding);
651
+ if (prompts.length) {
652
+ const onboarding_prompts_seen = {};
653
+ const onboarding_responses = [];
654
+ const onboarding_responses_seen = {};
655
+
656
+ const currentDate = Date.now();
657
+
658
+ prompts.forEach(prompt => {
659
+ onboarding_prompts_seen[prompt.id] = currentDate;
660
+ if (prompt.required) onboarding_responses.push(prompt.options[0].id);
661
+ prompt.options.forEach(option => {
662
+ onboarding_responses_seen[option.id] = currentDate;
663
+ });
664
+ });
665
+
666
+ await this.api.guilds[i.guild?.id]['onboarding-responses'].post({
667
+ data: {
668
+ onboarding_prompts_seen,
669
+ onboarding_responses,
670
+ onboarding_responses_seen,
671
+ },
672
+ });
673
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypassed onboarding`);
674
+ }
675
+ }
676
+ }
677
+ // Read rule
678
+ if (data.show_verification_form && options.bypassVerify) {
679
+ // Check Guild
680
+ if (i.guild.verificationLevel == 'VERY_HIGH' && !this.user.phone) {
681
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Cannot bypass verify (Phone required)`);
682
+ return this.guilds.cache.get(i.guild?.id);
683
+ }
684
+ if (i.guild.verificationLevel !== 'NONE' && !this.user.email) {
685
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Cannot bypass verify (Email required)`);
686
+ return this.guilds.cache.get(i.guild?.id);
687
+ }
688
+ const getForm = await this.api
689
+ .guilds(i.guild?.id)
690
+ ['member-verification'].get({ query: { with_guild: false, invite_code: this.code } })
691
+ .catch(() => {});
692
+ if (getForm && getForm.form_fields[0]) {
693
+ const form = Object.assign(getForm.form_fields[0], { response: true });
694
+ await this.api
695
+ .guilds(i.guild?.id)
696
+ .requests['@me'].put({ data: { form_fields: [form], version: getForm.version } });
697
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypassed verify`);
698
+ }
699
+ }
700
+ return guild;
701
+ } else {
702
+ return this.channels.cache.has(i.channelId || data.channel?.id);
703
+ }
704
+ }
705
+
706
+ /**
707
+ * Redeem nitro from code or url.
708
+ * @param {string} nitro Nitro url or code
709
+ * @param {TextChannelResolvable} [channel] Channel that the code was sent in
710
+ * @param {Snowflake} [paymentSourceId] Payment source id
711
+ * @returns {Promise<any>}
712
+ */
713
+ redeemNitro(nitro, channel, paymentSourceId) {
714
+ if (typeof nitro !== 'string') throw new Error('INVALID_NITRO');
715
+ const nitroCode =
716
+ nitro.match(/(discord.gift|discord.com|discordapp.com\/gifts)\/(\w{16,25})/) ||
717
+ nitro.match(/(discord\.gift\/|discord\.com\/gifts\/|discordapp\.com\/gifts\/)(\w+)/);
718
+ if (!nitroCode) return false;
719
+ const code = nitroCode[2];
720
+ channel = this.channels.resolveId(channel);
721
+ return this.api.entitlements['gift-codes'](code).redeem.post({
722
+ auth: true,
723
+ data: { channel_id: channel || null, payment_source_id: paymentSourceId || null },
724
+ });
725
+ }
726
+
727
+ /**
728
+ * @typedef {Object} OAuth2AuthorizeOptions
729
+ * @property {string} [guild_id] Guild ID
730
+ * @property {string} [permissions] Permissions
731
+ * @property {boolean} [authorize] Whether to authorize or not
732
+ * @property {string} [code] 2FA Code
733
+ * @property {string} [webhook_channel_id] Webhook Channel ID
734
+ */
735
+
736
+ /**
737
+ * Authorize an application.
738
+ * @param {string} urlOAuth2 Discord Auth URL
739
+ * @param {OAuth2AuthorizeOptions} [options] Oauth2 options
740
+ * @returns {Promise<{ location: string }>}
741
+ * @example
742
+ * client.authorizeURL(`https://discord.com/api/oauth2/authorize?client_id=botID&permissions=8&scope=applications.commands%20bot`, {
743
+ guild_id: "guildID",
744
+ })
745
+ */
746
+ authorizeURL(urlOAuth2, options = {}) {
747
+ // ! throw new Error('METHOD_WARNING');
748
+ const url = new URL(urlOAuth2);
749
+ if (!/^https:\/\/(?:canary\.|ptb\.)?discord\.com(?:\/api(?:\/v\d{1,2})?)?\/oauth2\/authorize\?/.test(urlOAuth2)) {
750
+ throw new Error('INVALID_URL', urlOAuth2);
751
+ }
752
+ const searchParams = Object.fromEntries(url.searchParams);
753
+ // Assign options
754
+ options = {
755
+ authorize: true,
756
+ permissions: '0',
757
+ integration_type: 0,
758
+ location_context: {
759
+ guild_id: '10000',
760
+ channel_id: '10000',
761
+ channel_type: 10000,
762
+ },
763
+ ...searchParams,
764
+ ...options,
765
+ };
766
+ delete searchParams.permissions;
767
+ delete searchParams.integration_type;
768
+ delete searchParams.guild_id;
769
+ return this.api.oauth2.authorize.post({
770
+ query: searchParams,
771
+ data: options,
772
+ });
773
+ }
774
+
775
+ /**
776
+ * Install User Apps
777
+ * @param {Snowflake} applicationId Discord Application id
778
+ * @returns {Promise<void>}
779
+ */
780
+ installUserApps(applicationId) {
781
+ return this.api
782
+ .applications(applicationId)
783
+ .public.get({
784
+ query: {
785
+ with_guild: false,
786
+ },
787
+ })
788
+ .then(rawData => {
789
+ const installTypes = rawData.integration_types_config['1'];
790
+ if (installTypes) {
791
+ return this.api.oauth2.authorize.post({
792
+ query: {
793
+ client_id: applicationId,
794
+ scope: installTypes.oauth2_install_params.scopes.join(' '),
795
+ },
796
+ data: {
797
+ permissions: '0',
798
+ authorize: true,
799
+ integration_type: 1,
800
+ },
801
+ });
802
+ } else {
803
+ return false;
804
+ }
805
+ });
806
+ }
807
+
808
+ /**
809
+ * Deauthorizes an application or token.
810
+ * @param {Snowflake} id - The ID of the Discord Application or Token.
811
+ * @param {'application' | 'token'} [type='application'] - The type of the ID provided. Defaults to 'application'.
812
+ * @returns {Promise<void>} A promise that resolves when the deauthorization is complete.
813
+ */
814
+ deauthorize(id, type = 'application') {
815
+ if (type === 'application') {
816
+ return this.api.oauth2.tokens
817
+ .get()
818
+ .then(data => data.find(o => o.application.id == id))
819
+ .then(o => this.api.oauth2.tokens(o.id).delete());
820
+ } else {
821
+ return this.api.oauth2.tokens(id).delete();
822
+ }
823
+ }
824
+
825
+ /**
826
+ * @typedef {Object} AuthorizedApplicationData
827
+ * @property {Application} application - The application object.
828
+ * @property {Snowflake} authorizedApplicationId - The ID of the OAuth2 token.
829
+ * @property {string[]} scopes - The scopes that were granted to this token.
830
+ * @property {function(): Promise<void>} deauthorize - Function to revoke this token.
831
+ */
832
+
833
+ /**
834
+ * Retrieves the list of authorized applications (OAuth2 tokens).
835
+ * @returns {Promise<Collection<Snowflake, AuthorizedApplicationData>>}
836
+ */
837
+ authorizedApplications() {
838
+ return this.api.oauth2.tokens.get().then(data => {
839
+ const results = new Collection();
840
+ for (const o of data) {
841
+ const application = new Application(this, o.application);
842
+ const data = {
843
+ application,
844
+ authorizedApplicationId: o.id,
845
+ scopes: o.scopes,
846
+ deauthorize: () => this.deauthorize(o.id, 'token'),
847
+ };
848
+ results.set(o.application.id, data);
849
+ }
850
+ return results;
851
+ });
852
+ }
853
+
854
+ /**
855
+ * Calls {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
856
+ * with the client as `this`.
857
+ * @param {string} script Script to eval
858
+ * @returns {*}
859
+ * @private
860
+ */
861
+ _eval(script) {
862
+ return eval(script);
863
+ }
864
+
865
+ /**
866
+ * Validates the client options.
867
+ * @param {ClientOptions} [options=this.options] Options to validate
868
+ * @private
869
+ */
870
+ _validateOptions(options = this.options) {
871
+ if (typeof options.makeCache !== 'function') {
872
+ throw new TypeError('CLIENT_INVALID_OPTION', 'makeCache', 'a function');
873
+ }
874
+ if (typeof options.messageCacheLifetime !== 'number' || isNaN(options.messageCacheLifetime)) {
875
+ throw new TypeError('CLIENT_INVALID_OPTION', 'The messageCacheLifetime', 'a number');
876
+ }
877
+ if (typeof options.messageSweepInterval !== 'number' || isNaN(options.messageSweepInterval)) {
878
+ throw new TypeError('CLIENT_INVALID_OPTION', 'messageSweepInterval', 'a number');
879
+ }
880
+ if (typeof options.sweepers !== 'object' || options.sweepers === null) {
881
+ throw new TypeError('CLIENT_INVALID_OPTION', 'sweepers', 'an object');
882
+ }
883
+ if (typeof options.invalidRequestWarningInterval !== 'number' || isNaN(options.invalidRequestWarningInterval)) {
884
+ throw new TypeError('CLIENT_INVALID_OPTION', 'invalidRequestWarningInterval', 'a number');
885
+ }
886
+ if (!Array.isArray(options.partials)) {
887
+ throw new TypeError('CLIENT_INVALID_OPTION', 'partials', 'an Array');
888
+ }
889
+ if (typeof options.DMChannelVoiceStatusSync !== 'number' || isNaN(options.DMChannelVoiceStatusSync)) {
890
+ throw new TypeError('CLIENT_INVALID_OPTION', 'DMChannelVoiceStatusSync', 'a number');
891
+ }
892
+ if (typeof options.waitGuildTimeout !== 'number' || isNaN(options.waitGuildTimeout)) {
893
+ throw new TypeError('CLIENT_INVALID_OPTION', 'waitGuildTimeout', 'a number');
894
+ }
895
+ if (typeof options.restWsBridgeTimeout !== 'number' || isNaN(options.restWsBridgeTimeout)) {
896
+ throw new TypeError('CLIENT_INVALID_OPTION', 'restWsBridgeTimeout', 'a number');
897
+ }
898
+ if (typeof options.restRequestTimeout !== 'number' || isNaN(options.restRequestTimeout)) {
899
+ throw new TypeError('CLIENT_INVALID_OPTION', 'restRequestTimeout', 'a number');
900
+ }
901
+ if (typeof options.restGlobalRateLimit !== 'number' || isNaN(options.restGlobalRateLimit)) {
902
+ throw new TypeError('CLIENT_INVALID_OPTION', 'restGlobalRateLimit', 'a number');
903
+ }
904
+ if (typeof options.restSweepInterval !== 'number' || isNaN(options.restSweepInterval)) {
905
+ throw new TypeError('CLIENT_INVALID_OPTION', 'restSweepInterval', 'a number');
906
+ }
907
+ if (typeof options.retryLimit !== 'number' || isNaN(options.retryLimit)) {
908
+ throw new TypeError('CLIENT_INVALID_OPTION', 'retryLimit', 'a number');
909
+ }
910
+ if (typeof options.failIfNotExists !== 'boolean') {
911
+ throw new TypeError('CLIENT_INVALID_OPTION', 'failIfNotExists', 'a boolean');
912
+ }
913
+ if (
914
+ typeof options.rejectOnRateLimit !== 'undefined' &&
915
+ !(typeof options.rejectOnRateLimit === 'function' || Array.isArray(options.rejectOnRateLimit))
916
+ ) {
917
+ throw new TypeError('CLIENT_INVALID_OPTION', 'rejectOnRateLimit', 'an array or a function');
918
+ }
919
+ if (typeof options.TOTPKey === 'string') {
920
+ // Convert to base32 if not already
921
+ options.TOTPKey = options.TOTPKey.replace(/ +/g, '').toUpperCase();
922
+ }
923
+ // Hardcode
924
+ this.options.shardCount = 1;
925
+ this.options.shards = [0];
926
+ this.options.intents = Intents.ALL;
927
+ }
928
+ }
929
+
930
+ module.exports = Client;
931
+
932
+ /**
933
+ * Emitted for general warnings.
934
+ * @event Client#warn
935
+ * @param {string} info The warning
936
+ */
937
+
938
+ /**
939
+ * @external Collection
940
+ * @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class}
941
+ */