safeness-sb-new 0.0.1

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 (343) hide show
  1. package/README.md +115 -0
  2. package/package.json +96 -0
  3. package/src/WebSocket.js +39 -0
  4. package/src/client/BaseClient.js +86 -0
  5. package/src/client/Client.js +836 -0
  6. package/src/client/WebhookClient.js +61 -0
  7. package/src/client/actions/Action.js +120 -0
  8. package/src/client/actions/ActionsManager.js +78 -0
  9. package/src/client/actions/ApplicationCommandPermissionsUpdate.js +34 -0
  10. package/src/client/actions/AutoModerationActionExecution.js +27 -0
  11. package/src/client/actions/AutoModerationRuleCreate.js +28 -0
  12. package/src/client/actions/AutoModerationRuleDelete.js +32 -0
  13. package/src/client/actions/AutoModerationRuleUpdate.js +30 -0
  14. package/src/client/actions/ChannelCreate.js +23 -0
  15. package/src/client/actions/ChannelDelete.js +39 -0
  16. package/src/client/actions/ChannelUpdate.js +43 -0
  17. package/src/client/actions/GuildAuditLogEntryCreate.js +29 -0
  18. package/src/client/actions/GuildBanAdd.js +20 -0
  19. package/src/client/actions/GuildBanRemove.js +25 -0
  20. package/src/client/actions/GuildChannelsPositionUpdate.js +21 -0
  21. package/src/client/actions/GuildDelete.js +65 -0
  22. package/src/client/actions/GuildEmojiCreate.js +20 -0
  23. package/src/client/actions/GuildEmojiDelete.js +21 -0
  24. package/src/client/actions/GuildEmojiUpdate.js +20 -0
  25. package/src/client/actions/GuildEmojisUpdate.js +34 -0
  26. package/src/client/actions/GuildIntegrationsUpdate.js +19 -0
  27. package/src/client/actions/GuildMemberRemove.js +33 -0
  28. package/src/client/actions/GuildMemberUpdate.js +44 -0
  29. package/src/client/actions/GuildRoleCreate.js +25 -0
  30. package/src/client/actions/GuildRoleDelete.js +31 -0
  31. package/src/client/actions/GuildRoleUpdate.js +39 -0
  32. package/src/client/actions/GuildRolesPositionUpdate.js +21 -0
  33. package/src/client/actions/GuildScheduledEventCreate.js +27 -0
  34. package/src/client/actions/GuildScheduledEventDelete.js +31 -0
  35. package/src/client/actions/GuildScheduledEventUpdate.js +30 -0
  36. package/src/client/actions/GuildScheduledEventUserAdd.js +32 -0
  37. package/src/client/actions/GuildScheduledEventUserRemove.js +32 -0
  38. package/src/client/actions/GuildStickerCreate.js +20 -0
  39. package/src/client/actions/GuildStickerDelete.js +21 -0
  40. package/src/client/actions/GuildStickerUpdate.js +20 -0
  41. package/src/client/actions/GuildStickersUpdate.js +34 -0
  42. package/src/client/actions/GuildUpdate.js +33 -0
  43. package/src/client/actions/InviteCreate.js +28 -0
  44. package/src/client/actions/InviteDelete.js +30 -0
  45. package/src/client/actions/MessageCreate.js +46 -0
  46. package/src/client/actions/MessageDelete.js +32 -0
  47. package/src/client/actions/MessageDeleteBulk.js +46 -0
  48. package/src/client/actions/MessageReactionAdd.js +56 -0
  49. package/src/client/actions/MessageReactionRemove.js +45 -0
  50. package/src/client/actions/MessageReactionRemoveAll.js +33 -0
  51. package/src/client/actions/MessageReactionRemoveEmoji.js +28 -0
  52. package/src/client/actions/MessageUpdate.js +26 -0
  53. package/src/client/actions/PresenceUpdate.js +46 -0
  54. package/src/client/actions/StageInstanceCreate.js +28 -0
  55. package/src/client/actions/StageInstanceDelete.js +33 -0
  56. package/src/client/actions/StageInstanceUpdate.js +30 -0
  57. package/src/client/actions/ThreadCreate.js +24 -0
  58. package/src/client/actions/ThreadDelete.js +32 -0
  59. package/src/client/actions/ThreadListSync.js +59 -0
  60. package/src/client/actions/ThreadMemberUpdate.js +30 -0
  61. package/src/client/actions/ThreadMembersUpdate.js +34 -0
  62. package/src/client/actions/TypingStart.js +29 -0
  63. package/src/client/actions/UserUpdate.js +35 -0
  64. package/src/client/actions/VoiceStateUpdate.js +57 -0
  65. package/src/client/actions/WebhooksUpdate.js +20 -0
  66. package/src/client/voice/ClientVoiceManager.js +150 -0
  67. package/src/client/voice/VoiceConnection.js +849 -0
  68. package/src/client/voice/dispatcher/AnnexBDispatcher.js +120 -0
  69. package/src/client/voice/dispatcher/AudioDispatcher.js +115 -0
  70. package/src/client/voice/dispatcher/BaseDispatcher.js +405 -0
  71. package/src/client/voice/dispatcher/VPxDispatcher.js +52 -0
  72. package/src/client/voice/dispatcher/VideoDispatcher.js +31 -0
  73. package/src/client/voice/networking/VoiceUDPClient.js +188 -0
  74. package/src/client/voice/networking/VoiceWebSocket.js +280 -0
  75. package/src/client/voice/player/MediaPlayer.js +294 -0
  76. package/src/client/voice/player/processing/AnnexBNalSplitter.js +244 -0
  77. package/src/client/voice/player/processing/IvfSplitter.js +106 -0
  78. package/src/client/voice/receiver/PacketHandler.js +170 -0
  79. package/src/client/voice/receiver/Receiver.js +82 -0
  80. package/src/client/voice/receiver/video/IvfJoinner.js +106 -0
  81. package/src/client/voice/util/Function.js +14 -0
  82. package/src/client/voice/util/PlayInterface.js +122 -0
  83. package/src/client/voice/util/Secretbox.js +42 -0
  84. package/src/client/voice/util/Silence.js +16 -0
  85. package/src/client/voice/util/Socket.js +62 -0
  86. package/src/client/voice/util/VolumeInterface.js +104 -0
  87. package/src/client/websocket/WebSocketManager.js +392 -0
  88. package/src/client/websocket/WebSocketShard.js +906 -0
  89. package/src/client/websocket/handlers/APPLICATION_COMMAND_CREATE.js +18 -0
  90. package/src/client/websocket/handlers/APPLICATION_COMMAND_DELETE.js +20 -0
  91. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js +5 -0
  92. package/src/client/websocket/handlers/APPLICATION_COMMAND_UPDATE.js +20 -0
  93. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js +5 -0
  94. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js +5 -0
  95. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js +5 -0
  96. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js +5 -0
  97. package/src/client/websocket/handlers/CALL_CREATE.js +14 -0
  98. package/src/client/websocket/handlers/CALL_DELETE.js +11 -0
  99. package/src/client/websocket/handlers/CALL_UPDATE.js +11 -0
  100. package/src/client/websocket/handlers/CHANNEL_CREATE.js +5 -0
  101. package/src/client/websocket/handlers/CHANNEL_DELETE.js +5 -0
  102. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js +22 -0
  103. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +19 -0
  104. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +16 -0
  105. package/src/client/websocket/handlers/CHANNEL_UPDATE.js +16 -0
  106. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js +5 -0
  107. package/src/client/websocket/handlers/GUILD_BAN_ADD.js +5 -0
  108. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.js +5 -0
  109. package/src/client/websocket/handlers/GUILD_CREATE.js +52 -0
  110. package/src/client/websocket/handlers/GUILD_DELETE.js +5 -0
  111. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js +5 -0
  112. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js +5 -0
  113. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js +39 -0
  114. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +20 -0
  115. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js +5 -0
  116. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js +5 -0
  117. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.js +5 -0
  118. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.js +5 -0
  119. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js +5 -0
  120. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js +5 -0
  121. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js +5 -0
  122. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js +5 -0
  123. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js +5 -0
  124. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js +5 -0
  125. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js +5 -0
  126. package/src/client/websocket/handlers/GUILD_UPDATE.js +5 -0
  127. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +12 -0
  128. package/src/client/websocket/handlers/INVITE_CREATE.js +5 -0
  129. package/src/client/websocket/handlers/INVITE_DELETE.js +5 -0
  130. package/src/client/websocket/handlers/MESSAGE_CREATE.js +5 -0
  131. package/src/client/websocket/handlers/MESSAGE_DELETE.js +5 -0
  132. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js +5 -0
  133. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +22 -0
  134. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +12 -0
  135. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js +5 -0
  136. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js +5 -0
  137. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js +5 -0
  138. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js +5 -0
  139. package/src/client/websocket/handlers/MESSAGE_UPDATE.js +16 -0
  140. package/src/client/websocket/handlers/PRESENCE_UPDATE.js +5 -0
  141. package/src/client/websocket/handlers/READY.js +120 -0
  142. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +19 -0
  143. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +17 -0
  144. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +41 -0
  145. package/src/client/websocket/handlers/RESUMED.js +14 -0
  146. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js +5 -0
  147. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js +5 -0
  148. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js +5 -0
  149. package/src/client/websocket/handlers/THREAD_CREATE.js +5 -0
  150. package/src/client/websocket/handlers/THREAD_DELETE.js +5 -0
  151. package/src/client/websocket/handlers/THREAD_LIST_SYNC.js +5 -0
  152. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js +5 -0
  153. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js +5 -0
  154. package/src/client/websocket/handlers/THREAD_UPDATE.js +16 -0
  155. package/src/client/websocket/handlers/TYPING_START.js +5 -0
  156. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +6 -0
  157. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +5 -0
  158. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
  159. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -0
  160. package/src/client/websocket/handlers/USER_UPDATE.js +5 -0
  161. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
  162. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js +6 -0
  163. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.js +5 -0
  164. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.js +5 -0
  165. package/src/client/websocket/handlers/index.js +83 -0
  166. package/src/errors/DJSError.js +61 -0
  167. package/src/errors/Messages.js +208 -0
  168. package/src/errors/index.js +4 -0
  169. package/src/index.js +159 -0
  170. package/src/managers/ApplicationCommandManager.js +264 -0
  171. package/src/managers/ApplicationCommandPermissionsManager.js +417 -0
  172. package/src/managers/AutoModerationRuleManager.js +296 -0
  173. package/src/managers/BaseGuildEmojiManager.js +80 -0
  174. package/src/managers/BaseManager.js +19 -0
  175. package/src/managers/BillingManager.js +66 -0
  176. package/src/managers/CachedManager.js +71 -0
  177. package/src/managers/ChannelManager.js +138 -0
  178. package/src/managers/ClientUserSettingManager.js +372 -0
  179. package/src/managers/DataManager.js +61 -0
  180. package/src/managers/GuildBanManager.js +204 -0
  181. package/src/managers/GuildChannelManager.js +488 -0
  182. package/src/managers/GuildEmojiManager.js +171 -0
  183. package/src/managers/GuildEmojiRoleManager.js +118 -0
  184. package/src/managers/GuildForumThreadManager.js +108 -0
  185. package/src/managers/GuildInviteManager.js +213 -0
  186. package/src/managers/GuildManager.js +304 -0
  187. package/src/managers/GuildMemberManager.js +597 -0
  188. package/src/managers/GuildMemberRoleManager.js +191 -0
  189. package/src/managers/GuildScheduledEventManager.js +296 -0
  190. package/src/managers/GuildSettingManager.js +155 -0
  191. package/src/managers/GuildStickerManager.js +179 -0
  192. package/src/managers/GuildTextThreadManager.js +98 -0
  193. package/src/managers/InteractionManager.js +39 -0
  194. package/src/managers/MessageManager.js +391 -0
  195. package/src/managers/PermissionOverwriteManager.js +166 -0
  196. package/src/managers/PresenceManager.js +58 -0
  197. package/src/managers/ReactionManager.js +67 -0
  198. package/src/managers/ReactionUserManager.js +71 -0
  199. package/src/managers/RelationshipManager.js +265 -0
  200. package/src/managers/RoleManager.js +352 -0
  201. package/src/managers/StageInstanceManager.js +162 -0
  202. package/src/managers/ThreadManager.js +174 -0
  203. package/src/managers/ThreadMemberManager.js +186 -0
  204. package/src/managers/UserManager.js +146 -0
  205. package/src/managers/UserNoteManager.js +53 -0
  206. package/src/managers/VoiceStateManager.js +37 -0
  207. package/src/rest/APIRequest.js +159 -0
  208. package/src/rest/APIRouter.js +53 -0
  209. package/src/rest/DiscordAPIError.js +104 -0
  210. package/src/rest/HTTPError.js +62 -0
  211. package/src/rest/RESTManager.js +62 -0
  212. package/src/rest/RateLimitError.js +55 -0
  213. package/src/rest/RequestHandler.js +444 -0
  214. package/src/sharding/Shard.js +443 -0
  215. package/src/sharding/ShardClientUtil.js +275 -0
  216. package/src/sharding/ShardingManager.js +318 -0
  217. package/src/structures/AnonymousGuild.js +98 -0
  218. package/src/structures/ApplicationCommand.js +593 -0
  219. package/src/structures/ApplicationRoleConnectionMetadata.js +48 -0
  220. package/src/structures/AutoModerationActionExecution.js +89 -0
  221. package/src/structures/AutoModerationRule.js +294 -0
  222. package/src/structures/AutocompleteInteraction.js +107 -0
  223. package/src/structures/Base.js +43 -0
  224. package/src/structures/BaseCommandInteraction.js +211 -0
  225. package/src/structures/BaseGuild.js +116 -0
  226. package/src/structures/BaseGuildEmoji.js +56 -0
  227. package/src/structures/BaseGuildTextChannel.js +191 -0
  228. package/src/structures/BaseGuildVoiceChannel.js +241 -0
  229. package/src/structures/BaseMessageComponent.js +114 -0
  230. package/src/structures/ButtonInteraction.js +11 -0
  231. package/src/structures/CallState.js +63 -0
  232. package/src/structures/CategoryChannel.js +85 -0
  233. package/src/structures/Channel.js +270 -0
  234. package/src/structures/ClientPresence.js +77 -0
  235. package/src/structures/ClientUser.js +450 -0
  236. package/src/structures/CommandInteraction.js +41 -0
  237. package/src/structures/CommandInteractionOptionResolver.js +276 -0
  238. package/src/structures/ContextMenuInteraction.js +65 -0
  239. package/src/structures/DMChannel.js +217 -0
  240. package/src/structures/DirectoryChannel.js +20 -0
  241. package/src/structures/Emoji.js +148 -0
  242. package/src/structures/ForumChannel.js +261 -0
  243. package/src/structures/GroupDMChannel.js +387 -0
  244. package/src/structures/Guild.js +1608 -0
  245. package/src/structures/GuildAuditLogs.js +729 -0
  246. package/src/structures/GuildBan.js +59 -0
  247. package/src/structures/GuildBoost.js +108 -0
  248. package/src/structures/GuildChannel.js +468 -0
  249. package/src/structures/GuildEmoji.js +161 -0
  250. package/src/structures/GuildMember.js +568 -0
  251. package/src/structures/GuildPreview.js +191 -0
  252. package/src/structures/GuildPreviewEmoji.js +27 -0
  253. package/src/structures/GuildScheduledEvent.js +441 -0
  254. package/src/structures/GuildTemplate.js +236 -0
  255. package/src/structures/Integration.js +188 -0
  256. package/src/structures/IntegrationApplication.js +96 -0
  257. package/src/structures/Interaction.js +290 -0
  258. package/src/structures/InteractionCollector.js +248 -0
  259. package/src/structures/InteractionWebhook.js +43 -0
  260. package/src/structures/Invite.js +358 -0
  261. package/src/structures/InviteGuild.js +23 -0
  262. package/src/structures/InviteStageInstance.js +86 -0
  263. package/src/structures/Message.js +1227 -0
  264. package/src/structures/MessageActionRow.js +103 -0
  265. package/src/structures/MessageAttachment.js +204 -0
  266. package/src/structures/MessageButton.js +165 -0
  267. package/src/structures/MessageCollector.js +146 -0
  268. package/src/structures/MessageComponentInteraction.js +120 -0
  269. package/src/structures/MessageContextMenuInteraction.js +20 -0
  270. package/src/structures/MessageEmbed.js +586 -0
  271. package/src/structures/MessageMentions.js +273 -0
  272. package/src/structures/MessagePayload.js +318 -0
  273. package/src/structures/MessagePoll.js +238 -0
  274. package/src/structures/MessageReaction.js +171 -0
  275. package/src/structures/MessageSelectMenu.js +140 -0
  276. package/src/structures/Modal.js +161 -0
  277. package/src/structures/ModalSubmitFieldsResolver.js +53 -0
  278. package/src/structures/ModalSubmitInteraction.js +119 -0
  279. package/src/structures/NewsChannel.js +32 -0
  280. package/src/structures/OAuth2Guild.js +28 -0
  281. package/src/structures/PermissionOverwrites.js +196 -0
  282. package/src/structures/Presence.js +1131 -0
  283. package/src/structures/ReactionCollector.js +229 -0
  284. package/src/structures/ReactionEmoji.js +31 -0
  285. package/src/structures/Role.js +531 -0
  286. package/src/structures/SelectMenuInteraction.js +21 -0
  287. package/src/structures/StageChannel.js +104 -0
  288. package/src/structures/StageInstance.js +208 -0
  289. package/src/structures/Sticker.js +310 -0
  290. package/src/structures/StickerPack.js +95 -0
  291. package/src/structures/StoreChannel.js +56 -0
  292. package/src/structures/Team.js +118 -0
  293. package/src/structures/TeamMember.js +71 -0
  294. package/src/structures/TextChannel.js +33 -0
  295. package/src/structures/TextInputComponent.js +131 -0
  296. package/src/structures/ThreadChannel.js +607 -0
  297. package/src/structures/ThreadMember.js +105 -0
  298. package/src/structures/Typing.js +74 -0
  299. package/src/structures/User.js +543 -0
  300. package/src/structures/UserContextMenuInteraction.js +29 -0
  301. package/src/structures/VoiceChannel.js +110 -0
  302. package/src/structures/VoiceRegion.js +53 -0
  303. package/src/structures/VoiceState.js +345 -0
  304. package/src/structures/WebEmbed.js +373 -0
  305. package/src/structures/Webhook.js +467 -0
  306. package/src/structures/WelcomeChannel.js +60 -0
  307. package/src/structures/WelcomeScreen.js +48 -0
  308. package/src/structures/Widget.js +87 -0
  309. package/src/structures/WidgetMember.js +99 -0
  310. package/src/structures/interfaces/Application.js +313 -0
  311. package/src/structures/interfaces/Collector.js +300 -0
  312. package/src/structures/interfaces/InteractionResponses.js +313 -0
  313. package/src/structures/interfaces/TextBasedChannel.js +719 -0
  314. package/src/util/ActivityFlags.js +44 -0
  315. package/src/util/ApplicationFlags.js +76 -0
  316. package/src/util/AttachmentFlags.js +38 -0
  317. package/src/util/BitField.js +170 -0
  318. package/src/util/ChannelFlags.js +45 -0
  319. package/src/util/Constants.js +1815 -0
  320. package/src/util/DataResolver.js +145 -0
  321. package/src/util/Formatters.js +228 -0
  322. package/src/util/GuildMemberFlags.js +43 -0
  323. package/src/util/Intents.js +74 -0
  324. package/src/util/InviteFlags.js +29 -0
  325. package/src/util/LimitedCollection.js +131 -0
  326. package/src/util/MessageFlags.js +54 -0
  327. package/src/util/Options.js +336 -0
  328. package/src/util/Permissions.js +202 -0
  329. package/src/util/PremiumUsageFlags.js +31 -0
  330. package/src/util/PurchasedFlags.js +33 -0
  331. package/src/util/RemoteAuth.js +382 -0
  332. package/src/util/RoleFlags.js +37 -0
  333. package/src/util/SnowflakeUtil.js +92 -0
  334. package/src/util/Speaking.js +33 -0
  335. package/src/util/Sweepers.js +466 -0
  336. package/src/util/SystemChannelFlags.js +55 -0
  337. package/src/util/ThreadMemberFlags.js +30 -0
  338. package/src/util/UserFlags.js +104 -0
  339. package/src/util/Util.js +889 -0
  340. package/typings/enums.d.ts +297 -0
  341. package/typings/index.d.ts +7670 -0
  342. package/typings/index.test-d.ts +0 -0
  343. package/typings/rawDataTypes.d.ts +342 -0
@@ -0,0 +1,1227 @@
1
+ 'use strict';
2
+
3
+ const process = require('node:process');
4
+ const { Collection } = require('@discordjs/collection');
5
+ const Base = require('./Base');
6
+ const BaseMessageComponent = require('./BaseMessageComponent');
7
+ const MessageAttachment = require('./MessageAttachment');
8
+ const Embed = require('./MessageEmbed');
9
+ const Mentions = require('./MessageMentions');
10
+ const MessagePayload = require('./MessagePayload');
11
+ const MessagePoll = require('./MessagePoll');
12
+ const ReactionCollector = require('./ReactionCollector');
13
+ const { Sticker } = require('./Sticker');
14
+ const Application = require('./interfaces/Application');
15
+ const { Error } = require('../errors');
16
+ const ReactionManager = require('../managers/ReactionManager');
17
+ const { InteractionTypes, MessageTypes, SystemMessageTypes, MessageComponentTypes } = require('../util/Constants');
18
+ const MessageFlags = require('../util/MessageFlags');
19
+ const Permissions = require('../util/Permissions');
20
+ const SnowflakeUtil = require('../util/SnowflakeUtil');
21
+ const Util = require('../util/Util');
22
+
23
+ /**
24
+ * @type {WeakSet<Message>}
25
+ * @private
26
+ * @internal
27
+ */
28
+ const deletedMessages = new WeakSet();
29
+ let deprecationEmittedForDeleted = false;
30
+
31
+ /**
32
+ * Represents a message on Discord.
33
+ * @extends {Base}
34
+ */
35
+ class Message extends Base {
36
+ constructor(client, data) {
37
+ super(client);
38
+
39
+ /**
40
+ * The id of the channel the message was sent in
41
+ * @type {Snowflake}
42
+ */
43
+ this.channelId = data.channel_id;
44
+
45
+ /**
46
+ * The id of the guild the message was sent in, if any
47
+ * @type {?Snowflake}
48
+ */
49
+ this.guildId = data.guild_id ?? this.channel?.guild?.id ?? null;
50
+
51
+ this._patch(data);
52
+ }
53
+
54
+ _patch(data) {
55
+ /**
56
+ * The message's id
57
+ * @type {Snowflake}
58
+ */
59
+ this.id = data.id;
60
+
61
+ if ('position' in data) {
62
+ /**
63
+ * A generally increasing integer (there may be gaps or duplicates) that represents
64
+ * the approximate position of the message in a thread.
65
+ * @type {?number}
66
+ */
67
+ this.position = data.position;
68
+ } else {
69
+ this.position ??= null;
70
+ }
71
+
72
+ /**
73
+ * The timestamp the message was sent at
74
+ * @type {number}
75
+ */
76
+ this.createdTimestamp = SnowflakeUtil.timestampFrom(this.id);
77
+
78
+ if ('type' in data) {
79
+ /**
80
+ * The type of the message
81
+ * @type {?MessageType}
82
+ */
83
+ this.type = MessageTypes[data.type];
84
+
85
+ /**
86
+ * Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications)
87
+ * @type {?boolean}
88
+ */
89
+ this.system = SystemMessageTypes.includes(this.type);
90
+ } else {
91
+ this.system ??= null;
92
+ this.type ??= null;
93
+ }
94
+
95
+ if ('content' in data) {
96
+ /**
97
+ * The content of the message
98
+ * @type {?string}
99
+ */
100
+ this.content = data.content;
101
+ } else {
102
+ this.content ??= null;
103
+ }
104
+
105
+ if ('author' in data) {
106
+ /**
107
+ * The author of the message
108
+ * @type {?User}
109
+ */
110
+ this.author = this.client.users._add(data.author, !data.webhook_id);
111
+ } else {
112
+ this.author ??= null;
113
+ }
114
+
115
+ if ('pinned' in data) {
116
+ /**
117
+ * Whether or not this message is pinned
118
+ * @type {?boolean}
119
+ */
120
+ this.pinned = Boolean(data.pinned);
121
+ } else {
122
+ this.pinned ??= null;
123
+ }
124
+
125
+ if ('tts' in data) {
126
+ /**
127
+ * Whether or not the message was Text-To-Speech
128
+ * @type {?boolean}
129
+ */
130
+ this.tts = data.tts;
131
+ } else {
132
+ this.tts ??= null;
133
+ }
134
+
135
+ if ('nonce' in data) {
136
+ /**
137
+ * A random number or string used for checking message delivery
138
+ * <warn>This is only received after the message was sent successfully, and
139
+ * lost if re-fetched</warn>
140
+ * @type {?string}
141
+ */
142
+ this.nonce = data.nonce;
143
+ } else {
144
+ this.nonce ??= null;
145
+ }
146
+
147
+ if ('embeds' in data) {
148
+ /**
149
+ * A list of embeds in the message - e.g. YouTube Player
150
+ * @type {MessageEmbed[]}
151
+ */
152
+ this.embeds = data.embeds.map(e => new Embed(e, true));
153
+ } else {
154
+ this.embeds = this.embeds?.slice() ?? [];
155
+ }
156
+
157
+ if ('components' in data) {
158
+ /**
159
+ * A list of MessageActionRows in the message
160
+ * @type {MessageActionRow[]}
161
+ */
162
+ this.components = data.components.map(c => BaseMessageComponent.create(c, this.client));
163
+ } else {
164
+ this.components = this.components?.slice() ?? [];
165
+ }
166
+
167
+ if ('attachments' in data) {
168
+ /**
169
+ * A collection of attachments in the message - e.g. Pictures - mapped by their ids
170
+ * @type {Collection<Snowflake, MessageAttachment>}
171
+ */
172
+ this.attachments = new Collection();
173
+ if (data.attachments) {
174
+ for (const attachment of data.attachments) {
175
+ this.attachments.set(attachment.id, new MessageAttachment(attachment.url, attachment.filename, attachment));
176
+ }
177
+ }
178
+ } else {
179
+ this.attachments = new Collection(this.attachments);
180
+ }
181
+
182
+ if ('sticker_items' in data || 'stickers' in data) {
183
+ /**
184
+ * A collection of stickers in the message
185
+ * @type {Collection<Snowflake, Sticker>}
186
+ */
187
+ this.stickers = new Collection(
188
+ (data.sticker_items ?? data.stickers)?.map(s => [s.id, new Sticker(this.client, s)]),
189
+ );
190
+ } else {
191
+ this.stickers = new Collection(this.stickers);
192
+ }
193
+
194
+ // Discord sends null if the message has not been edited
195
+ if (data.edited_timestamp) {
196
+ /**
197
+ * The timestamp the message was last edited at (if applicable)
198
+ * @type {?number}
199
+ */
200
+ this.editedTimestamp = new Date(data.edited_timestamp).getTime();
201
+ } else {
202
+ this.editedTimestamp ??= null;
203
+ }
204
+
205
+ if ('reactions' in data) {
206
+ /**
207
+ * A manager of the reactions belonging to this message
208
+ * @type {ReactionManager}
209
+ */
210
+ this.reactions = new ReactionManager(this);
211
+ if (data.reactions?.length > 0) {
212
+ for (const reaction of data.reactions) {
213
+ this.reactions._add(reaction);
214
+ }
215
+ }
216
+ } else {
217
+ this.reactions ??= new ReactionManager(this);
218
+ }
219
+
220
+ if (!this.mentions) {
221
+ /**
222
+ * All valid mentions that the message contains
223
+ * @type {MessageMentions}
224
+ */
225
+ this.mentions = new Mentions(
226
+ this,
227
+ data.mentions,
228
+ data.mention_roles,
229
+ data.mention_everyone,
230
+ data.mention_channels,
231
+ data.referenced_message?.author,
232
+ );
233
+ } else {
234
+ this.mentions = new Mentions(
235
+ this,
236
+ data.mentions ?? this.mentions.users,
237
+ data.mention_roles ?? this.mentions.roles,
238
+ data.mention_everyone ?? this.mentions.everyone,
239
+ data.mention_channels ?? this.mentions.crosspostedChannels,
240
+ data.referenced_message?.author ?? this.mentions.repliedUser,
241
+ );
242
+ }
243
+
244
+ if ('webhook_id' in data) {
245
+ /**
246
+ * The id of the webhook that sent the message, if applicable
247
+ * @type {?Snowflake}
248
+ */
249
+ this.webhookId = data.webhook_id;
250
+ } else {
251
+ this.webhookId ??= null;
252
+ }
253
+
254
+ /**
255
+ * A poll!
256
+ * @type {?MessagePoll}
257
+ */
258
+ if ('poll' in data) {
259
+ this.poll = new MessagePoll(data.poll, this.client);
260
+ } else {
261
+ this.poll = null;
262
+ }
263
+
264
+ if ('application' in data) {
265
+ /**
266
+ * Supplemental application information for group activities
267
+ * @type {?Application}
268
+ */
269
+ this.groupActivityApplication = new Application(this.client, data.application);
270
+ } else {
271
+ this.groupActivityApplication ??= null;
272
+ }
273
+
274
+ if ('application_id' in data) {
275
+ /**
276
+ * The id of the application of the interaction that sent this message, if any
277
+ * @type {?Snowflake}
278
+ */
279
+ this.applicationId = data.application_id;
280
+ } else {
281
+ this.applicationId ??= null;
282
+ }
283
+
284
+ if ('activity' in data) {
285
+ /**
286
+ * Group activity
287
+ * @type {?MessageActivity}
288
+ */
289
+ this.activity = {
290
+ partyId: data.activity.party_id,
291
+ type: data.activity.type,
292
+ };
293
+ } else {
294
+ this.activity ??= null;
295
+ }
296
+
297
+ if ('thread' in data) {
298
+ this.client.channels._add(data.thread, this.guild);
299
+ }
300
+
301
+ if (this.member && data.member) {
302
+ this.member._patch(data.member);
303
+ } else if (data.member && this.guild && this.author) {
304
+ this.guild.members._add(Object.assign(data.member, { user: this.author }));
305
+ }
306
+
307
+ if ('flags' in data) {
308
+ /**
309
+ * Flags that are applied to the message
310
+ * @type {Readonly<MessageFlags>}
311
+ */
312
+ this.flags = new MessageFlags(data.flags).freeze();
313
+ } else {
314
+ this.flags = new MessageFlags(this.flags).freeze();
315
+ }
316
+
317
+ /**
318
+ * Reference data sent in a message that contains ids identifying the referenced message.
319
+ * This can be present in the following types of message:
320
+ * * Crossposted messages (IS_CROSSPOST {@link MessageFlags.FLAGS message flag})
321
+ * * CHANNEL_FOLLOW_ADD
322
+ * * CHANNEL_PINNED_MESSAGE
323
+ * * REPLY
324
+ * * THREAD_STARTER_MESSAGE
325
+ * @see {@link https://discord.com/developers/docs/resources/channel#message-types}
326
+ * @typedef {Object} MessageReference
327
+ * @property {Snowflake} channelId The channel's id the message was referenced
328
+ * @property {?Snowflake} guildId The guild's id the message was referenced
329
+ * @property {?Snowflake} messageId The message's id that was referenced
330
+ */
331
+
332
+ if ('message_reference' in data) {
333
+ /**
334
+ * Message reference data
335
+ * @type {?MessageReference}
336
+ */
337
+ this.reference = {
338
+ channelId: data.message_reference.channel_id,
339
+ guildId: data.message_reference.guild_id,
340
+ messageId: data.message_reference.message_id,
341
+ };
342
+ } else {
343
+ this.reference ??= null;
344
+ }
345
+
346
+ if (data.referenced_message) {
347
+ this.channel?.messages._add({ guild_id: data.message_reference?.guild_id, ...data.referenced_message });
348
+ }
349
+
350
+ /**
351
+ * Partial data of the interaction that a message is a reply to
352
+ * @typedef {Object} MessageInteraction
353
+ * @property {Snowflake} id The interaction's id
354
+ * @property {InteractionType} type The type of the interaction
355
+ * @property {string} commandName The name of the interaction's application command,
356
+ * as well as the subcommand and subcommand group, where applicable
357
+ * @property {User} user The user that invoked the interaction
358
+ */
359
+
360
+ if (data.interaction) {
361
+ /**
362
+ * Partial data of the interaction that this message is a reply to
363
+ * @type {?MessageInteraction}
364
+ */
365
+ this.interaction = {
366
+ id: data.interaction.id,
367
+ type: InteractionTypes[data.interaction.type],
368
+ commandName: data.interaction.name,
369
+ user: this.client.users._add(data.interaction.user),
370
+ };
371
+ } else {
372
+ this.interaction ??= null;
373
+ }
374
+ }
375
+
376
+ /**
377
+ * Whether or not the structure has been deleted
378
+ * @type {boolean}
379
+ * @deprecated This will be removed in the next major version, see https://github.com/discordjs/discord.js/issues/7091
380
+ */
381
+ get deleted() {
382
+ if (!deprecationEmittedForDeleted) {
383
+ deprecationEmittedForDeleted = true;
384
+ process.emitWarning(
385
+ 'Message#deleted is deprecated, see https://github.com/discordjs/discord.js/issues/7091.',
386
+ 'DeprecationWarning',
387
+ );
388
+ }
389
+
390
+ return deletedMessages.has(this);
391
+ }
392
+
393
+ set deleted(value) {
394
+ if (!deprecationEmittedForDeleted) {
395
+ deprecationEmittedForDeleted = true;
396
+ process.emitWarning(
397
+ 'Message#deleted is deprecated, see https://github.com/discordjs/discord.js/issues/7091.',
398
+ 'DeprecationWarning',
399
+ );
400
+ }
401
+
402
+ if (value) deletedMessages.add(this);
403
+ else deletedMessages.delete(this);
404
+ }
405
+
406
+ /**
407
+ * The channel that the message was sent in
408
+ * @type {TextBasedChannels}
409
+ * @readonly
410
+ */
411
+ get channel() {
412
+ return this.client.channels.resolve(this.channelId);
413
+ }
414
+
415
+ /**
416
+ * Whether or not this message is a partial
417
+ * @type {boolean}
418
+ * @readonly
419
+ */
420
+ get partial() {
421
+ return typeof this.content !== 'string' || !this.author;
422
+ }
423
+
424
+ /**
425
+ * Represents the author of the message as a guild member.
426
+ * Only available if the message comes from a guild where the author is still a member
427
+ * @type {?GuildMember}
428
+ * @readonly
429
+ */
430
+ get member() {
431
+ return this.guild?.members.resolve(this.author) ?? null;
432
+ }
433
+
434
+ /**
435
+ * The time the message was sent at
436
+ * @type {Date}
437
+ * @readonly
438
+ */
439
+ get createdAt() {
440
+ return new Date(this.createdTimestamp);
441
+ }
442
+
443
+ /**
444
+ * The time the message was last edited at (if applicable)
445
+ * @type {?Date}
446
+ * @readonly
447
+ */
448
+ get editedAt() {
449
+ return this.editedTimestamp ? new Date(this.editedTimestamp) : null;
450
+ }
451
+
452
+ /**
453
+ * The guild the message was sent in (if in a guild channel)
454
+ * @type {?Guild}
455
+ * @readonly
456
+ */
457
+ get guild() {
458
+ return this.client.guilds.resolve(this.guildId) ?? this.channel?.guild ?? null;
459
+ }
460
+
461
+ /**
462
+ * Whether this message has a thread associated with it
463
+ * @type {boolean}
464
+ * @readonly
465
+ */
466
+ get hasThread() {
467
+ return this.flags.has(MessageFlags.FLAGS.HAS_THREAD);
468
+ }
469
+
470
+ /**
471
+ * The thread started by this message
472
+ * <info>This property is not suitable for checking whether a message has a thread,
473
+ * use {@link Message#hasThread} instead.</info>
474
+ * @type {?ThreadChannel}
475
+ * @readonly
476
+ */
477
+ get thread() {
478
+ return this.channel?.threads?.resolve(this.id) ?? null;
479
+ }
480
+
481
+ /**
482
+ * The URL to jump to this message
483
+ * @type {string}
484
+ * @readonly
485
+ */
486
+ get url() {
487
+ return `https://discord.com/channels/${this.guildId ?? '@me'}/${this.channelId}/${this.id}`;
488
+ }
489
+
490
+ /**
491
+ * The message contents with all mentions replaced by the equivalent text.
492
+ * If mentions cannot be resolved to a name, the relevant mention in the message content will not be converted.
493
+ * @type {?string}
494
+ * @readonly
495
+ */
496
+ get cleanContent() {
497
+ // eslint-disable-next-line eqeqeq
498
+ return this.content != null ? Util.cleanContent(this.content, this.channel) : null;
499
+ }
500
+
501
+ /**
502
+ * Creates a reaction collector.
503
+ * @param {ReactionCollectorOptions} [options={}] Options to send to the collector
504
+ * @returns {ReactionCollector}
505
+ * @example
506
+ * // Create a reaction collector
507
+ * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId';
508
+ * const collector = message.createReactionCollector({ filter, time: 15_000 });
509
+ * collector.on('collect', r => console.log(`Collected ${r.emoji.name}`));
510
+ * collector.on('end', collected => console.log(`Collected ${collected.size} items`));
511
+ */
512
+ createReactionCollector(options = {}) {
513
+ return new ReactionCollector(this, options);
514
+ }
515
+
516
+ /**
517
+ * An object containing the same properties as CollectorOptions, but a few more:
518
+ * @typedef {ReactionCollectorOptions} AwaitReactionsOptions
519
+ * @property {string[]} [errors] Stop/end reasons that cause the promise to reject
520
+ */
521
+
522
+ /**
523
+ * Similar to createReactionCollector but in promise form.
524
+ * Resolves with a collection of reactions that pass the specified filter.
525
+ * @param {AwaitReactionsOptions} [options={}] Optional options to pass to the internal collector
526
+ * @returns {Promise<Collection<string | Snowflake, MessageReaction>>}
527
+ * @example
528
+ * // Create a reaction collector
529
+ * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId'
530
+ * message.awaitReactions({ filter, time: 15_000 })
531
+ * .then(collected => console.log(`Collected ${collected.size} reactions`))
532
+ * .catch(console.error);
533
+ */
534
+ awaitReactions(options = {}) {
535
+ return new Promise((resolve, reject) => {
536
+ const collector = this.createReactionCollector(options);
537
+ collector.once('end', (reactions, reason) => {
538
+ if (options.errors?.includes(reason)) reject(reactions);
539
+ else resolve(reactions);
540
+ });
541
+ });
542
+ }
543
+
544
+ /**
545
+ * Whether the message is editable by the client user
546
+ * @type {boolean}
547
+ * @readonly
548
+ */
549
+ get editable() {
550
+ const precheck = Boolean(
551
+ this.author.id === this.client.user.id && !deletedMessages.has(this) && (!this.guild || this.channel?.viewable),
552
+ );
553
+
554
+ // Regardless of permissions thread messages cannot be edited if
555
+ // the thread is archived or the thread is locked and the bot does not have permission to manage threads.
556
+ if (this.channel?.isThread()) {
557
+ if (this.channel.archived) return false;
558
+ if (this.channel.locked) {
559
+ const permissions = this.channel.permissionsFor(this.client.user);
560
+ if (!permissions?.has(Permissions.FLAGS.MANAGE_THREADS, true)) return false;
561
+ }
562
+ }
563
+
564
+ return precheck;
565
+ }
566
+
567
+ /**
568
+ * Whether the message is deletable by the client user
569
+ * @type {boolean}
570
+ * @readonly
571
+ */
572
+ get deletable() {
573
+ if (deletedMessages.has(this)) {
574
+ return false;
575
+ }
576
+ if (!this.guild) {
577
+ return this.author.id === this.client.user.id;
578
+ }
579
+ // DMChannel does not have viewable property, so check viewable after proved that message is on a guild.
580
+ if (!this.channel?.viewable) {
581
+ return false;
582
+ }
583
+
584
+ const permissions = this.channel?.permissionsFor(this.client.user);
585
+ if (!permissions) return false;
586
+ // This flag allows deleting even if timed out
587
+ if (permissions.has(Permissions.FLAGS.ADMINISTRATOR, false)) return true;
588
+
589
+ return Boolean(
590
+ this.author.id === this.client.user.id ||
591
+ (permissions.has(Permissions.FLAGS.MANAGE_MESSAGES, false) &&
592
+ this.guild.members.me.communicationDisabledUntilTimestamp < Date.now()),
593
+ );
594
+ }
595
+
596
+ /**
597
+ * Whether the message is bulk deletable by the client user
598
+ * @type {boolean}
599
+ * @readonly
600
+ * @example
601
+ * // Filter for bulk deletable messages
602
+ * channel.bulkDelete(messages.filter(message => message.bulkDeletable));
603
+ */
604
+ get bulkDeletable() {
605
+ return false;
606
+ }
607
+
608
+ /**
609
+ * Whether the message is pinnable by the client user
610
+ * @type {boolean}
611
+ * @readonly
612
+ */
613
+ get pinnable() {
614
+ const { channel } = this;
615
+ return Boolean(
616
+ !this.system &&
617
+ !deletedMessages.has(this) &&
618
+ (!this.guild ||
619
+ (channel?.viewable &&
620
+ channel?.permissionsFor(this.client.user)?.has(Permissions.FLAGS.MANAGE_MESSAGES, false))),
621
+ );
622
+ }
623
+
624
+ /**
625
+ * Fetches the Message this crosspost/reply/pin-add references, if available to the client
626
+ * @returns {Promise<Message>}
627
+ */
628
+ async fetchReference() {
629
+ if (!this.reference) throw new Error('MESSAGE_REFERENCE_MISSING');
630
+ const { channelId, messageId } = this.reference;
631
+ const channel = this.client.channels.resolve(channelId);
632
+ if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE');
633
+ const message = await channel.messages.fetch(messageId);
634
+ return message;
635
+ }
636
+
637
+ /**
638
+ * Whether the message is crosspostable by the client user
639
+ * @type {boolean}
640
+ * @readonly
641
+ */
642
+ get crosspostable() {
643
+ const bitfield =
644
+ Permissions.FLAGS.SEND_MESSAGES |
645
+ (this.author.id === this.client.user.id ? Permissions.defaultBit : Permissions.FLAGS.MANAGE_MESSAGES);
646
+ const { channel } = this;
647
+ return Boolean(
648
+ channel?.type === 'GUILD_NEWS' &&
649
+ !this.flags.has(MessageFlags.FLAGS.CROSSPOSTED) &&
650
+ this.type === 'DEFAULT' &&
651
+ channel.viewable &&
652
+ channel.permissionsFor(this.client.user)?.has(bitfield, false) &&
653
+ !deletedMessages.has(this),
654
+ );
655
+ }
656
+
657
+ /**
658
+ * Options that can be passed into {@link Message#edit}.
659
+ * @typedef {Object} MessageEditOptions
660
+ * @property {?string} [content] Content to be edited
661
+ * @property {MessageEmbed[]|APIEmbed[]} [embeds] Embeds to be added/edited
662
+ * @property {MessageMentionOptions} [allowedMentions] Which mentions should be parsed from the message content
663
+ * @property {MessageFlags} [flags] Which flags to set for the message. Only `SUPPRESS_EMBEDS` can be edited.
664
+ * @property {MessageAttachment[]} [attachments] An array of attachments to keep,
665
+ * all attachments will be kept if omitted
666
+ * @property {FileOptions[]|BufferResolvable[]|MessageAttachment[]} [files] Files to add to the message
667
+ * @property {MessageActionRow[]|MessageActionRowOptions[]} [components]
668
+ * Action rows containing interactive components for the message (buttons, select menus)
669
+ */
670
+
671
+ /**
672
+ * Edits the content of the message.
673
+ * @param {string|MessagePayload|MessageEditOptions} options The options to provide
674
+ * @returns {Promise<Message>}
675
+ * @example
676
+ * // Update the content of a message
677
+ * message.edit('This is my new content!')
678
+ * .then(msg => console.log(`Updated the content of a message to ${msg.content}`))
679
+ * .catch(console.error);
680
+ */
681
+ edit(options) {
682
+ if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
683
+ return this.channel.messages.edit(this, options);
684
+ }
685
+
686
+ /**
687
+ * Publishes a message in an announcement channel to all channels following it.
688
+ * @returns {Promise<Message>}
689
+ * @example
690
+ * // Crosspost a message
691
+ * if (message.channel.type === 'GUILD_NEWS') {
692
+ * message.crosspost()
693
+ * .then(() => console.log('Crossposted message'))
694
+ * .catch(console.error);
695
+ * }
696
+ */
697
+ crosspost() {
698
+ if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
699
+ return this.channel.messages.crosspost(this.id);
700
+ }
701
+
702
+ /**
703
+ * Pins this message to the channel's pinned messages.
704
+ * @param {string} [reason] Reason for pinning
705
+ * @returns {Promise<Message>}
706
+ * @example
707
+ * // Pin a message
708
+ * message.pin()
709
+ * .then(console.log)
710
+ * .catch(console.error)
711
+ */
712
+ async pin(reason) {
713
+ if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
714
+ await this.channel.messages.pin(this.id, reason);
715
+ return this;
716
+ }
717
+
718
+ /**
719
+ * Unpins this message from the channel's pinned messages.
720
+ * @param {string} [reason] Reason for unpinning
721
+ * @returns {Promise<Message>}
722
+ * @example
723
+ * // Unpin a message
724
+ * message.unpin()
725
+ * .then(console.log)
726
+ * .catch(console.error)
727
+ */
728
+ async unpin(reason) {
729
+ if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
730
+ await this.channel.messages.unpin(this.id, reason);
731
+ return this;
732
+ }
733
+
734
+ /**
735
+ * Adds a reaction to the message.
736
+ * @param {EmojiIdentifierResolvable} emoji The emoji to react with
737
+ * @param {boolean} [burst=false] Super Reactions
738
+ * @returns {Promise<MessageReaction>}
739
+ * @example
740
+ * // React to a message with a unicode emoji
741
+ * message.react('🤔')
742
+ * .then(console.log)
743
+ * .catch(console.error);
744
+ * @example
745
+ * // React to a message with a custom emoji
746
+ * message.react(message.guild.emojis.cache.get('123456789012345678'))
747
+ * .then(console.log)
748
+ * .catch(console.error);
749
+ */
750
+ async react(emoji, burst = false) {
751
+ if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
752
+ await this.channel.messages.react(this.id, emoji, burst);
753
+
754
+ return this.client.actions.MessageReactionAdd.handle(
755
+ {
756
+ [this.client.actions.injectedUser]: this.client.user,
757
+ [this.client.actions.injectedChannel]: this.channel,
758
+ [this.client.actions.injectedMessage]: this,
759
+ emoji: Util.resolvePartialEmoji(emoji),
760
+ me_burst: burst,
761
+ },
762
+ true,
763
+ ).reaction;
764
+ }
765
+
766
+ /**
767
+ * Deletes the message.
768
+ * @returns {Promise<Message>}
769
+ * @example
770
+ * // Delete a message
771
+ * message.delete()
772
+ * .then(msg => console.log(`Deleted message from ${msg.author.username}`))
773
+ * .catch(console.error);
774
+ */
775
+ async delete() {
776
+ if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
777
+ await this.channel.messages.delete(this.id);
778
+ return this;
779
+ }
780
+
781
+ /**
782
+ * Options provided when sending a message as an inline reply.
783
+ * @typedef {BaseMessageOptions} ReplyMessageOptions
784
+ * @property {boolean} [failIfNotExists=true] Whether to error if the referenced message
785
+ * does not exist (creates a standard message in this case when false)
786
+ * @property {StickerResolvable[]} [stickers=[]] Stickers to send in the message
787
+ */
788
+
789
+ /**
790
+ * Send an inline reply to this message.
791
+ * @param {string|MessagePayload|ReplyMessageOptions} options The options to provide
792
+ * @returns {Promise<Message>}
793
+ * @example
794
+ * // Reply to a message
795
+ * message.reply('This is a reply!')
796
+ * .then(() => console.log(`Replied to message "${message.content}"`))
797
+ * .catch(console.error);
798
+ */
799
+ reply(options) {
800
+ if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
801
+ let data;
802
+
803
+ if (options instanceof MessagePayload) {
804
+ data = options;
805
+ } else {
806
+ data = MessagePayload.create(this, options, {
807
+ reply: {
808
+ messageReference: this,
809
+ failIfNotExists: options?.failIfNotExists ?? this.client.options.failIfNotExists,
810
+ },
811
+ });
812
+ }
813
+ return this.channel.send(data);
814
+ }
815
+
816
+ /**
817
+ * A number that is allowed to be the duration (in minutes) of inactivity after which a thread is automatically
818
+ * archived. This can be:
819
+ * * `60` (1 hour)
820
+ * * `1440` (1 day)
821
+ * * `4320` (3 days)
822
+ * * `10080` (7 days)
823
+ * * `'MAX'` (7 days)
824
+ * <warn>This option is deprecated and will be removed in the next major version.</warn>
825
+ * @typedef {number|string} ThreadAutoArchiveDuration
826
+ */
827
+
828
+ /**
829
+ * Options for starting a thread on a message.
830
+ * @typedef {Object} StartThreadOptions
831
+ * @property {string} name The name of the new thread
832
+ * @property {ThreadAutoArchiveDuration} [autoArchiveDuration=this.channel.defaultAutoArchiveDuration] The amount of
833
+ * time (in minutes) after which the thread should automatically archive in case of no recent activity
834
+ * @property {string} [reason] Reason for creating the thread
835
+ * @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the thread in seconds
836
+ */
837
+
838
+ /**
839
+ * Create a new public thread from this message
840
+ * @see GuildTextThreadManager#create
841
+ * @param {StartThreadOptions} [options] Options for starting a thread on this message
842
+ * @returns {Promise<ThreadChannel>}
843
+ */
844
+ startThread(options = {}) {
845
+ if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
846
+ if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(this.channel.type)) {
847
+ return Promise.reject(new Error('MESSAGE_THREAD_PARENT'));
848
+ }
849
+ if (this.hasThread) return Promise.reject(new Error('MESSAGE_EXISTING_THREAD'));
850
+ return this.channel.threads.create({ ...options, startMessage: this });
851
+ }
852
+
853
+ /**
854
+ * Submits a poll vote for the current user. Returns a 204 empty response on success.
855
+ * @param {...number[]} ids ID of the answer
856
+ * @returns {Promise<void>}
857
+ * @example
858
+ * // Vote multi choices
859
+ * message.vote(1,2);
860
+ * // Remove vote
861
+ * message.vote();
862
+ */
863
+ vote(...ids) {
864
+ return this.client.api
865
+ .channels(this.channel.id)
866
+ .polls(this.id)
867
+ .answers['@me'].put({
868
+ data: {
869
+ answer_ids: ids.flat(1).map(value => value.toString()),
870
+ },
871
+ });
872
+ }
873
+
874
+ /**
875
+ * Immediately ends the poll. You cannot end polls from other users.
876
+ * @returns {Promise<RawMessage>}
877
+ */
878
+ endPoll() {
879
+ return this.client.api.channels(this.channel.id).polls(this.id).expire.post();
880
+ }
881
+
882
+ /**
883
+ * Get a list of users that voted for this specific answer.
884
+ * @param {number} answerId Answer Id
885
+ * @param {Snowflake} [afterUserId] Get users after this user ID
886
+ * @param {number} [limit=25] Max number of users to return (1-100, default 25)
887
+ * @returns {Promise<{ users: Partial<RawUser> }>}
888
+ */
889
+ getAnswerVoter(answerId, afterUserId, limit = 25) {
890
+ return this.client.api
891
+ .channels(this.channel.id)
892
+ .polls(this.id)
893
+ .answers(answerId)
894
+ .get({
895
+ query: {
896
+ after: afterUserId,
897
+ limit,
898
+ },
899
+ });
900
+ }
901
+
902
+ /**
903
+ * Fetch this message.
904
+ * @param {boolean} [force=true] Whether to skip the cache check and request the API
905
+ * @returns {Promise<Message>}
906
+ */
907
+ fetch(force = true) {
908
+ if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
909
+ return this.channel.messages.fetch(this.id, { force });
910
+ }
911
+
912
+ /**
913
+ * Fetches the webhook used to create this message.
914
+ * @returns {Promise<?Webhook>}
915
+ */
916
+ fetchWebhook() {
917
+ if (!this.webhookId) return Promise.reject(new Error('WEBHOOK_MESSAGE'));
918
+ if (this.webhookId === this.applicationId) return Promise.reject(new Error('WEBHOOK_APPLICATION'));
919
+ return this.client.fetchWebhook(this.webhookId);
920
+ }
921
+
922
+ /**
923
+ * Suppresses or unsuppresses embeds on a message.
924
+ * @param {boolean} [suppress=true] If the embeds should be suppressed or not
925
+ * @returns {Promise<Message>}
926
+ */
927
+ suppressEmbeds(suppress = true) {
928
+ const flags = new MessageFlags(this.flags.bitfield);
929
+
930
+ if (suppress) {
931
+ flags.add(MessageFlags.FLAGS.SUPPRESS_EMBEDS);
932
+ } else {
933
+ flags.remove(MessageFlags.FLAGS.SUPPRESS_EMBEDS);
934
+ }
935
+
936
+ return this.edit({ flags });
937
+ }
938
+
939
+ /**
940
+ * Removes the attachments from this message.
941
+ * @returns {Promise<Message>}
942
+ */
943
+ removeAttachments() {
944
+ return this.edit({ attachments: [] });
945
+ }
946
+
947
+ /**
948
+ * Resolves a component by a custom id.
949
+ * @param {string} customId The custom id to resolve against
950
+ * @returns {?MessageActionRowComponent}
951
+ */
952
+ resolveComponent(customId) {
953
+ return this.components.flatMap(row => row.components).find(component => component.customId === customId) ?? null;
954
+ }
955
+
956
+ /**
957
+ * Used mainly internally. Whether two messages are identical in properties. If you want to compare messages
958
+ * without checking all the properties, use `message.id === message2.id`, which is much more efficient. This
959
+ * method allows you to see if there are differences in content, embeds, attachments, nonce and tts properties.
960
+ * @param {Message} message The message to compare it to
961
+ * @param {APIMessage} rawData Raw data passed through the WebSocket about this message
962
+ * @returns {boolean}
963
+ */
964
+ equals(message, rawData) {
965
+ if (!message) return false;
966
+ const embedUpdate = !message.author && !message.attachments;
967
+ if (embedUpdate) return this.id === message.id && this.embeds.length === message.embeds.length;
968
+
969
+ let equal =
970
+ this.id === message.id &&
971
+ this.author.id === message.author.id &&
972
+ this.content === message.content &&
973
+ this.tts === message.tts &&
974
+ this.nonce === message.nonce &&
975
+ this.embeds.length === message.embeds.length &&
976
+ this.attachments.length === message.attachments.length;
977
+
978
+ if (equal && rawData) {
979
+ equal =
980
+ this.mentions.everyone === message.mentions.everyone &&
981
+ this.createdTimestamp === new Date(rawData.timestamp).getTime() &&
982
+ this.editedTimestamp === new Date(rawData.edited_timestamp).getTime();
983
+ }
984
+
985
+ return equal;
986
+ }
987
+
988
+ /**
989
+ * Whether this message is from a guild.
990
+ * @returns {boolean}
991
+ */
992
+ inGuild() {
993
+ return Boolean(this.guildId);
994
+ }
995
+
996
+ /**
997
+ * When concatenated with a string, this automatically concatenates the message's content instead of the object.
998
+ * @returns {string}
999
+ * @example
1000
+ * // Logs: Message: This is a message!
1001
+ * console.log(`Message: ${message}`);
1002
+ */
1003
+ toString() {
1004
+ return this.content;
1005
+ }
1006
+
1007
+ toJSON() {
1008
+ return super.toJSON({
1009
+ channel: 'channelId',
1010
+ author: 'authorId',
1011
+ groupActivityApplication: 'groupActivityApplicationId',
1012
+ guild: 'guildId',
1013
+ cleanContent: true,
1014
+ member: false,
1015
+ reactions: false,
1016
+ });
1017
+ }
1018
+
1019
+ // TypeScript
1020
+ /**
1021
+ * Check data
1022
+ * @type {boolean}
1023
+ * @readonly
1024
+ */
1025
+ get isMessage() {
1026
+ return true;
1027
+ }
1028
+
1029
+ /**
1030
+ * Click specific button with X and Y
1031
+ * @typedef {Object} MessageButtonLocation
1032
+ * @property {number} X Index of the row
1033
+ * @property {number} Y Index of the column
1034
+ */
1035
+
1036
+ /**
1037
+ * Click specific button or automatically click first button if no button is specified.
1038
+ * @param {MessageButtonLocation|string|undefined} button button
1039
+ * @returns {Promise<Message|Modal>}
1040
+ * @example
1041
+ * // Demo msg
1042
+ * Some content
1043
+ * ――――――――――――――――――――――――――――――――> X from 0
1044
+ * │ [button1] [button2] [button3]
1045
+ * │ [button4] [button5] [button6]
1046
+ * ↓
1047
+ * Y from 0
1048
+ * // Click button6 with X and Y
1049
+ * [0,0] [1,0] [2,0]
1050
+ * [0,1] [1,1] [2,1]
1051
+ * // Code
1052
+ * message.clickButton({
1053
+ * X: 2, Y: 1,
1054
+ * });
1055
+ * // Click button with customId (Ex button 5)
1056
+ * message.clickButton('button5');
1057
+ * // Click button 1
1058
+ * message.clickButton();
1059
+ */
1060
+ clickButton(button) {
1061
+ if (typeof button == 'undefined') {
1062
+ button = this.components
1063
+ .flatMap(row => row.components)
1064
+ .find(b => b.type === 'BUTTON' && b.customId && !b.disabled);
1065
+ } else if (typeof button == 'string') {
1066
+ button = this.components.flatMap(row => row.components).find(b => b.type === 'BUTTON' && b.customId == button);
1067
+ } else {
1068
+ button = this.components[button.Y]?.components[button.X];
1069
+ }
1070
+ if (!button) throw new TypeError('BUTTON_NOT_FOUND');
1071
+ button = button.toJSON();
1072
+ if (!button.custom_id || button.disabled) throw new TypeError('BUTTON_CANNOT_CLICK');
1073
+ const nonce = SnowflakeUtil.generate();
1074
+ const data = {
1075
+ type: InteractionTypes.MESSAGE_COMPONENT,
1076
+ nonce,
1077
+ guild_id: this.guildId,
1078
+ channel_id: this.channelId,
1079
+ message_id: this.id,
1080
+ application_id: this.applicationId ?? this.author.id,
1081
+ session_id: this.client.sessionId,
1082
+ message_flags: this.flags.bitfield,
1083
+ data: {
1084
+ component_type: MessageComponentTypes.BUTTON,
1085
+ custom_id: button.custom_id,
1086
+ },
1087
+ };
1088
+ this.client.api.interactions.post({
1089
+ data,
1090
+ });
1091
+ return Util.createPromiseInteraction(this.client, nonce, 5_000, true, this);
1092
+ }
1093
+
1094
+ /**
1095
+ * Select specific menu
1096
+ * @param {number|string} menu Target
1097
+ * @param {Array<UserResolvable | RoleResolvable | ChannelResolvable | string>} values Any value
1098
+ * @returns {Promise<Message|Modal>}
1099
+ */
1100
+ selectMenu(menu, values = []) {
1101
+ let selectMenu = menu;
1102
+ if (/[0-4]/.test(menu)) {
1103
+ selectMenu = this.components[menu]?.components[0];
1104
+ } else if (typeof menu == 'string') {
1105
+ selectMenu = this.components
1106
+ .flatMap(row => row.components)
1107
+ .find(
1108
+ b =>
1109
+ ['STRING_SELECT', 'USER_SELECT', 'ROLE_SELECT', 'MENTIONABLE_SELECT', 'CHANNEL_SELECT'].includes(b.type) &&
1110
+ b.customId == menu &&
1111
+ !b.disabled,
1112
+ );
1113
+ }
1114
+ if (values.length < selectMenu.minValues) {
1115
+ throw new RangeError(`[SELECT_MENU_MIN_VALUES] The minimum number of values is ${selectMenu.minValues}`);
1116
+ }
1117
+ if (values.length > selectMenu?.maxValues) {
1118
+ throw new RangeError(`[SELECT_MENU_MAX_VALUES] The maximum number of values is ${selectMenu.maxValues}`);
1119
+ }
1120
+ values = values.map(value => {
1121
+ switch (selectMenu.type) {
1122
+ case 'STRING_SELECT': {
1123
+ return selectMenu.options.find(obj => obj.value === value || obj.label === value).value;
1124
+ }
1125
+ case 'USER_SELECT': {
1126
+ return this.client.users.resolveId(value);
1127
+ }
1128
+ case 'ROLE_SELECT': {
1129
+ return this.guild.roles.resolveId(value);
1130
+ }
1131
+ case 'MENTIONABLE_SELECT': {
1132
+ return this.client.users.resolveId(value) || this.guild.roles.resolveId(value);
1133
+ }
1134
+ case 'CHANNEL_SELECT': {
1135
+ return this.client.channels.resolveId(value);
1136
+ }
1137
+ default: {
1138
+ return value;
1139
+ }
1140
+ }
1141
+ });
1142
+ const nonce = SnowflakeUtil.generate();
1143
+ const data = {
1144
+ type: InteractionTypes.MESSAGE_COMPONENT,
1145
+ guild_id: this.guildId,
1146
+ channel_id: this.channelId,
1147
+ message_id: this.id,
1148
+ application_id: this.applicationId ?? this.author.id,
1149
+ session_id: this.client.sessionId,
1150
+ message_flags: this.flags.bitfield,
1151
+ data: {
1152
+ component_type: MessageComponentTypes[selectMenu.type],
1153
+ custom_id: selectMenu.customId,
1154
+ type: MessageComponentTypes[selectMenu.type],
1155
+ values,
1156
+ },
1157
+ nonce,
1158
+ };
1159
+ this.client.api.interactions.post({
1160
+ data,
1161
+ });
1162
+ return Util.createPromiseInteraction(this.client, nonce, 5_000, true, this);
1163
+ }
1164
+
1165
+ /**
1166
+ * Marks the message as unread.
1167
+ * @returns {Promise<void>}
1168
+ */
1169
+ markUnread() {
1170
+ return this.client.api.channels[this.channelId].messages[this.id].ack.post({
1171
+ data: {
1172
+ manual: true,
1173
+ mention_count:
1174
+ this.mentions.everyone ||
1175
+ this.mentions.repliedUser?.id === this.client.user.id ||
1176
+ this.mentions.users.has(this.client.user.id) ||
1177
+ (this.guildId && this.mentions.roles.some(r => this.guild.members.me._roles?.includes(r.id)))
1178
+ ? 1
1179
+ : 0,
1180
+ },
1181
+ });
1182
+ }
1183
+
1184
+ /**
1185
+ * Marks the message as read.
1186
+ * @returns {Promise<void>}
1187
+ */
1188
+ markRead() {
1189
+ return this.client.api.channels[this.channelId].messages[this.id].ack.post({
1190
+ data: {
1191
+ token: null,
1192
+ },
1193
+ });
1194
+ }
1195
+
1196
+ /**
1197
+ * Report Message
1198
+ * @param {Arrray<number>} breadcrumbs Options for reporting
1199
+ * @param {Object} [elements={}] Metadata
1200
+ * @returns {Promise<{ report_id: Snowflake }>}
1201
+ * @example
1202
+ * // GET https://discord.com/api/v9/reporting/menu/message?variant=4
1203
+ * // Report Category
1204
+ * // - <hidden>MESSAGE_WELCOME (3)</hidden>
1205
+ * // - Something else (28)
1206
+ * // - Hacks, cheats, phishing or malicious links (72)
1207
+ * message.report([3, 28, 72]).then(console.log);
1208
+ * // { "report_id": "1199663489988440124" }
1209
+ */
1210
+ report(breadcrumbs, elements = {}) {
1211
+ return this.client.api.reporting.message.post({
1212
+ data: {
1213
+ version: '1.0',
1214
+ variant: '4',
1215
+ language: 'en',
1216
+ breadcrumbs,
1217
+ elements,
1218
+ channel_id: this.channelId,
1219
+ message_id: this.id,
1220
+ name: 'message',
1221
+ },
1222
+ });
1223
+ }
1224
+ }
1225
+
1226
+ exports.Message = Message;
1227
+ exports.deletedMessages = deletedMessages;