@ovencord/discord.js 14.16.3

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 (332) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +148 -0
  3. package/package.json +73 -0
  4. package/src/client/Client.ts +967 -0
  5. package/src/client/actions/Action.ts +141 -0
  6. package/src/client/actions/ActionsManager.ts +138 -0
  7. package/src/client/actions/ChannelCreate.ts +21 -0
  8. package/src/client/actions/ChannelDelete.ts +20 -0
  9. package/src/client/actions/ChannelUpdate.ts +38 -0
  10. package/src/client/actions/GuildChannelsPositionUpdate.ts +17 -0
  11. package/src/client/actions/GuildEmojiCreate.ts +17 -0
  12. package/src/client/actions/GuildEmojiDelete.ts +16 -0
  13. package/src/client/actions/GuildEmojiUpdate.ts +17 -0
  14. package/src/client/actions/GuildEmojisUpdate.ts +30 -0
  15. package/src/client/actions/GuildMemberRemove.ts +29 -0
  16. package/src/client/actions/GuildMemberUpdate.ts +41 -0
  17. package/src/client/actions/GuildRoleCreate.ts +23 -0
  18. package/src/client/actions/GuildRoleDelete.ts +26 -0
  19. package/src/client/actions/GuildRolesPositionUpdate.ts +17 -0
  20. package/src/client/actions/GuildScheduledEventDelete.ts +28 -0
  21. package/src/client/actions/GuildScheduledEventUserAdd.ts +29 -0
  22. package/src/client/actions/GuildScheduledEventUserRemove.ts +29 -0
  23. package/src/client/actions/GuildSoundboardSoundDelete.ts +26 -0
  24. package/src/client/actions/GuildStickerCreate.ts +17 -0
  25. package/src/client/actions/GuildStickerDelete.ts +16 -0
  26. package/src/client/actions/GuildStickerUpdate.ts +17 -0
  27. package/src/client/actions/GuildStickersUpdate.ts +30 -0
  28. package/src/client/actions/GuildUpdate.ts +30 -0
  29. package/src/client/actions/InteractionCreate.ts +104 -0
  30. package/src/client/actions/MessageCreate.ts +38 -0
  31. package/src/client/actions/MessageDelete.ts +29 -0
  32. package/src/client/actions/MessageDeleteBulk.ts +45 -0
  33. package/src/client/actions/MessagePollVoteAdd.ts +37 -0
  34. package/src/client/actions/MessagePollVoteRemove.ts +35 -0
  35. package/src/client/actions/MessageReactionAdd.ts +68 -0
  36. package/src/client/actions/MessageReactionRemove.ts +47 -0
  37. package/src/client/actions/MessageReactionRemoveAll.ts +30 -0
  38. package/src/client/actions/MessageReactionRemoveEmoji.ts +25 -0
  39. package/src/client/actions/MessageUpdate.ts +22 -0
  40. package/src/client/actions/StageInstanceCreate.ts +25 -0
  41. package/src/client/actions/StageInstanceDelete.ts +28 -0
  42. package/src/client/actions/StageInstanceUpdate.ts +27 -0
  43. package/src/client/actions/ThreadCreate.ts +22 -0
  44. package/src/client/actions/ThreadMembersUpdate.ts +45 -0
  45. package/src/client/actions/TypingStart.ts +26 -0
  46. package/src/client/actions/UserUpdate.ts +33 -0
  47. package/src/client/voice/ClientVoiceManager.ts +46 -0
  48. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts +19 -0
  49. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.ts +17 -0
  50. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.ts +18 -0
  51. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.ts +21 -0
  52. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.ts +20 -0
  53. package/src/client/websocket/handlers/CHANNEL_CREATE.ts +4 -0
  54. package/src/client/websocket/handlers/CHANNEL_DELETE.ts +4 -0
  55. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.ts +22 -0
  56. package/src/client/websocket/handlers/CHANNEL_UPDATE.ts +16 -0
  57. package/src/client/websocket/handlers/ENTITLEMENT_CREATE.ts +14 -0
  58. package/src/client/websocket/handlers/ENTITLEMENT_DELETE.ts +18 -0
  59. package/src/client/websocket/handlers/ENTITLEMENT_UPDATE.ts +16 -0
  60. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.ts +19 -0
  61. package/src/client/websocket/handlers/GUILD_BAN_ADD.ts +15 -0
  62. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.ts +20 -0
  63. package/src/client/websocket/handlers/GUILD_CREATE.ts +34 -0
  64. package/src/client/websocket/handlers/GUILD_DELETE.ts +36 -0
  65. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.ts +4 -0
  66. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.ts +15 -0
  67. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.ts +40 -0
  68. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.ts +17 -0
  69. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.ts +4 -0
  70. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.ts +4 -0
  71. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.ts +4 -0
  72. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.ts +4 -0
  73. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.ts +21 -0
  74. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.ts +17 -0
  75. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.ts +4 -0
  76. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.ts +19 -0
  77. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.ts +4 -0
  78. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts +4 -0
  79. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts +24 -0
  80. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.ts +18 -0
  81. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.ts +4 -0
  82. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.ts +20 -0
  83. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.ts +4 -0
  84. package/src/client/websocket/handlers/GUILD_UPDATE.ts +4 -0
  85. package/src/client/websocket/handlers/INTERACTION_CREATE.ts +4 -0
  86. package/src/client/websocket/handlers/INVITE_CREATE.ts +20 -0
  87. package/src/client/websocket/handlers/INVITE_DELETE.ts +23 -0
  88. package/src/client/websocket/handlers/MESSAGE_CREATE.ts +4 -0
  89. package/src/client/websocket/handlers/MESSAGE_DELETE.ts +4 -0
  90. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.ts +4 -0
  91. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.ts +4 -0
  92. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.ts +4 -0
  93. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.ts +4 -0
  94. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.ts +4 -0
  95. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.ts +4 -0
  96. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.ts +4 -0
  97. package/src/client/websocket/handlers/MESSAGE_UPDATE.ts +16 -0
  98. package/src/client/websocket/handlers/PRESENCE_UPDATE.ts +42 -0
  99. package/src/client/websocket/handlers/RATE_LIMITED.ts +23 -0
  100. package/src/client/websocket/handlers/READY.ts +29 -0
  101. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.ts +24 -0
  102. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.ts +4 -0
  103. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.ts +4 -0
  104. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.ts +4 -0
  105. package/src/client/websocket/handlers/SUBSCRIPTION_CREATE.ts +14 -0
  106. package/src/client/websocket/handlers/SUBSCRIPTION_DELETE.ts +16 -0
  107. package/src/client/websocket/handlers/SUBSCRIPTION_UPDATE.ts +16 -0
  108. package/src/client/websocket/handlers/THREAD_CREATE.ts +4 -0
  109. package/src/client/websocket/handlers/THREAD_DELETE.ts +17 -0
  110. package/src/client/websocket/handlers/THREAD_LIST_SYNC.ts +50 -0
  111. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.ts +4 -0
  112. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.ts +25 -0
  113. package/src/client/websocket/handlers/THREAD_UPDATE.ts +16 -0
  114. package/src/client/websocket/handlers/TYPING_START.ts +4 -0
  115. package/src/client/websocket/handlers/USER_UPDATE.ts +4 -0
  116. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.ts +16 -0
  117. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.ts +5 -0
  118. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.ts +37 -0
  119. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.ts +16 -0
  120. package/src/client/websocket/handlers/index.ts +74 -0
  121. package/src/errors/DJSError.ts +50 -0
  122. package/src/errors/ErrorCodes.ts +277 -0
  123. package/src/errors/Messages.ts +155 -0
  124. package/src/errors/index.ts +6 -0
  125. package/src/index.ts +241 -0
  126. package/src/managers/ApplicationCommandManager.ts +303 -0
  127. package/src/managers/ApplicationCommandPermissionsManager.ts +453 -0
  128. package/src/managers/ApplicationEmojiManager.ts +149 -0
  129. package/src/managers/AutoModerationRuleManager.ts +307 -0
  130. package/src/managers/BaseManager.ts +13 -0
  131. package/src/managers/CachedManager.ts +56 -0
  132. package/src/managers/CategoryChannelChildManager.ts +81 -0
  133. package/src/managers/ChannelManager.ts +194 -0
  134. package/src/managers/DMMessageManager.ts +15 -0
  135. package/src/managers/DataManager.ts +38 -0
  136. package/src/managers/EntitlementManager.ts +182 -0
  137. package/src/managers/GuildApplicationCommandManager.ts +29 -0
  138. package/src/managers/GuildBanManager.ts +221 -0
  139. package/src/managers/GuildChannelManager.ts +552 -0
  140. package/src/managers/GuildEmojiManager.ts +262 -0
  141. package/src/managers/GuildEmojiRoleManager.ts +134 -0
  142. package/src/managers/GuildForumThreadManager.ts +84 -0
  143. package/src/managers/GuildInviteManager.ts +236 -0
  144. package/src/managers/GuildManager.ts +265 -0
  145. package/src/managers/GuildMemberManager.ts +619 -0
  146. package/src/managers/GuildMemberRoleManager.ts +230 -0
  147. package/src/managers/GuildMessageManager.ts +31 -0
  148. package/src/managers/GuildScheduledEventManager.ts +330 -0
  149. package/src/managers/GuildSoundboardSoundManager.ts +157 -0
  150. package/src/managers/GuildStickerManager.ts +192 -0
  151. package/src/managers/GuildTextThreadManager.ts +91 -0
  152. package/src/managers/MessageManager.ts +352 -0
  153. package/src/managers/PartialGroupDMMessageManager.ts +15 -0
  154. package/src/managers/PermissionOverwriteManager.ts +174 -0
  155. package/src/managers/PollAnswerVoterManager.ts +59 -0
  156. package/src/managers/PresenceManager.ts +60 -0
  157. package/src/managers/ReactionManager.ts +72 -0
  158. package/src/managers/ReactionUserManager.ts +82 -0
  159. package/src/managers/RoleManager.ts +432 -0
  160. package/src/managers/StageInstanceManager.ts +166 -0
  161. package/src/managers/SubscriptionManager.ts +83 -0
  162. package/src/managers/ThreadManager.ts +210 -0
  163. package/src/managers/ThreadMemberManager.ts +194 -0
  164. package/src/managers/UserManager.ts +139 -0
  165. package/src/managers/VoiceStateManager.ts +61 -0
  166. package/src/sharding/Shard.ts +513 -0
  167. package/src/sharding/ShardClientUtil.ts +293 -0
  168. package/src/sharding/ShardingManager.ts +374 -0
  169. package/src/structures/ActionRow.ts +31 -0
  170. package/src/structures/AnnouncementChannel.ts +25 -0
  171. package/src/structures/AnonymousGuild.ts +110 -0
  172. package/src/structures/ApplicationCommand.ts +675 -0
  173. package/src/structures/ApplicationEmoji.ts +189 -0
  174. package/src/structures/ApplicationRoleConnectionMetadata.ts +54 -0
  175. package/src/structures/Attachment.ts +189 -0
  176. package/src/structures/AuthorizingIntegrationOwners.ts +63 -0
  177. package/src/structures/AutoModerationActionExecution.ts +138 -0
  178. package/src/structures/AutoModerationRule.ts +325 -0
  179. package/src/structures/AutocompleteInteraction.ts +115 -0
  180. package/src/structures/Base.ts +37 -0
  181. package/src/structures/BaseChannel.ts +188 -0
  182. package/src/structures/BaseGuild.ts +134 -0
  183. package/src/structures/BaseGuildEmoji.ts +113 -0
  184. package/src/structures/BaseGuildTextChannel.ts +230 -0
  185. package/src/structures/BaseGuildVoiceChannel.ts +270 -0
  186. package/src/structures/BaseInteraction.ts +393 -0
  187. package/src/structures/BaseInvite.ts +192 -0
  188. package/src/structures/BaseSelectMenuComponent.ts +58 -0
  189. package/src/structures/ButtonComponent.ts +68 -0
  190. package/src/structures/ButtonInteraction.ts +8 -0
  191. package/src/structures/CategoryChannel.ts +46 -0
  192. package/src/structures/ChannelSelectMenuComponent.ts +18 -0
  193. package/src/structures/ChannelSelectMenuInteraction.ts +34 -0
  194. package/src/structures/ChatInputCommandInteraction.ts +43 -0
  195. package/src/structures/ClientApplication.ts +470 -0
  196. package/src/structures/ClientPresence.ts +87 -0
  197. package/src/structures/ClientUser.ts +219 -0
  198. package/src/structures/CommandInteraction.ts +193 -0
  199. package/src/structures/CommandInteractionOptionResolver.ts +336 -0
  200. package/src/structures/Component.ts +59 -0
  201. package/src/structures/ContainerComponent.ts +63 -0
  202. package/src/structures/ContextMenuCommandInteraction.ts +68 -0
  203. package/src/structures/DMChannel.ts +148 -0
  204. package/src/structures/DirectoryChannel.ts +40 -0
  205. package/src/structures/Embed.ts +251 -0
  206. package/src/structures/Emoji.ts +61 -0
  207. package/src/structures/Entitlement.ts +206 -0
  208. package/src/structures/FileComponent.ts +41 -0
  209. package/src/structures/ForumChannel.ts +31 -0
  210. package/src/structures/GroupDMInvite.ts +34 -0
  211. package/src/structures/Guild.ts +1605 -0
  212. package/src/structures/GuildAuditLogs.ts +99 -0
  213. package/src/structures/GuildAuditLogsEntry.ts +557 -0
  214. package/src/structures/GuildBan.ts +65 -0
  215. package/src/structures/GuildChannel.ts +515 -0
  216. package/src/structures/GuildEmoji.ts +159 -0
  217. package/src/structures/GuildInvite.ts +233 -0
  218. package/src/structures/GuildMember.ts +643 -0
  219. package/src/structures/GuildOnboarding.ts +73 -0
  220. package/src/structures/GuildOnboardingPrompt.ts +93 -0
  221. package/src/structures/GuildOnboardingPromptOption.ts +100 -0
  222. package/src/structures/GuildPreview.ts +218 -0
  223. package/src/structures/GuildPreviewEmoji.ts +28 -0
  224. package/src/structures/GuildScheduledEvent.ts +593 -0
  225. package/src/structures/GuildTemplate.ts +229 -0
  226. package/src/structures/Integration.ts +257 -0
  227. package/src/structures/IntegrationApplication.ts +84 -0
  228. package/src/structures/InteractionCallback.ts +86 -0
  229. package/src/structures/InteractionCallbackResource.ts +57 -0
  230. package/src/structures/InteractionCallbackResponse.ts +35 -0
  231. package/src/structures/InteractionCollector.ts +260 -0
  232. package/src/structures/InteractionWebhook.ts +65 -0
  233. package/src/structures/InviteGuild.ts +22 -0
  234. package/src/structures/LabelComponent.ts +51 -0
  235. package/src/structures/MediaChannel.ts +8 -0
  236. package/src/structures/MediaGalleryComponent.ts +31 -0
  237. package/src/structures/MediaGalleryItem.ts +54 -0
  238. package/src/structures/MentionableSelectMenuComponent.ts +8 -0
  239. package/src/structures/MentionableSelectMenuInteraction.ts +76 -0
  240. package/src/structures/Message.ts +1202 -0
  241. package/src/structures/MessageCollector.ts +155 -0
  242. package/src/structures/MessageComponentInteraction.ts +132 -0
  243. package/src/structures/MessageContextMenuCommandInteraction.ts +18 -0
  244. package/src/structures/MessageMentions.ts +327 -0
  245. package/src/structures/MessagePayload.ts +325 -0
  246. package/src/structures/MessageReaction.ts +219 -0
  247. package/src/structures/ModalComponentResolver.ts +237 -0
  248. package/src/structures/ModalSubmitInteraction.ts +260 -0
  249. package/src/structures/OAuth2Guild.ts +30 -0
  250. package/src/structures/PartialGroupDMChannel.ts +151 -0
  251. package/src/structures/PermissionOverwrites.ts +222 -0
  252. package/src/structures/Poll.ts +195 -0
  253. package/src/structures/PollAnswer.ts +100 -0
  254. package/src/structures/Presence.ts +448 -0
  255. package/src/structures/PrimaryEntryPointCommandInteraction.ts +8 -0
  256. package/src/structures/ReactionCollector.ts +245 -0
  257. package/src/structures/ReactionEmoji.ts +30 -0
  258. package/src/structures/Role.ts +543 -0
  259. package/src/structures/RoleSelectMenuComponent.ts +8 -0
  260. package/src/structures/RoleSelectMenuInteraction.ts +34 -0
  261. package/src/structures/SKU.ts +62 -0
  262. package/src/structures/SectionComponent.ts +44 -0
  263. package/src/structures/SeparatorComponent.ts +29 -0
  264. package/src/structures/SoundboardSound.ts +176 -0
  265. package/src/structures/StageChannel.ts +118 -0
  266. package/src/structures/StageInstance.ts +173 -0
  267. package/src/structures/Sticker.ts +300 -0
  268. package/src/structures/StickerPack.ts +111 -0
  269. package/src/structures/StringSelectMenuComponent.ts +18 -0
  270. package/src/structures/StringSelectMenuInteraction.ts +21 -0
  271. package/src/structures/Subscription.ts +138 -0
  272. package/src/structures/Team.ts +131 -0
  273. package/src/structures/TeamMember.ts +77 -0
  274. package/src/structures/TextChannel.ts +33 -0
  275. package/src/structures/TextDisplayComponent.ts +18 -0
  276. package/src/structures/TextInputComponent.ts +28 -0
  277. package/src/structures/ThreadChannel.ts +680 -0
  278. package/src/structures/ThreadMember.ts +125 -0
  279. package/src/structures/ThreadOnlyChannel.ts +276 -0
  280. package/src/structures/ThumbnailComponent.ts +51 -0
  281. package/src/structures/Typing.ts +81 -0
  282. package/src/structures/UnfurledMediaItem.ts +33 -0
  283. package/src/structures/User.ts +511 -0
  284. package/src/structures/UserContextMenuCommandInteraction.ts +28 -0
  285. package/src/structures/UserSelectMenuComponent.ts +8 -0
  286. package/src/structures/UserSelectMenuInteraction.ts +54 -0
  287. package/src/structures/VoiceChannel.ts +119 -0
  288. package/src/structures/VoiceChannelEffect.ts +92 -0
  289. package/src/structures/VoiceRegion.ts +52 -0
  290. package/src/structures/VoiceState.ts +346 -0
  291. package/src/structures/Webhook.ts +526 -0
  292. package/src/structures/WelcomeChannel.ts +67 -0
  293. package/src/structures/WelcomeScreen.ts +53 -0
  294. package/src/structures/Widget.ts +110 -0
  295. package/src/structures/WidgetMember.ts +124 -0
  296. package/src/structures/interfaces/Application.ts +179 -0
  297. package/src/structures/interfaces/Collector.ts +372 -0
  298. package/src/structures/interfaces/InteractionResponses.ts +384 -0
  299. package/src/structures/interfaces/TextBasedChannel.ts +430 -0
  300. package/src/util/APITypes.ts +690 -0
  301. package/src/util/ActivityFlagsBitField.ts +26 -0
  302. package/src/util/ApplicationFlagsBitField.ts +43 -0
  303. package/src/util/AttachmentFlagsBitField.ts +26 -0
  304. package/src/util/BitField.ts +178 -0
  305. package/src/util/ChannelFlagsBitField.ts +43 -0
  306. package/src/util/Channels.ts +165 -0
  307. package/src/util/Colors.ts +72 -0
  308. package/src/util/Components.ts +285 -0
  309. package/src/util/Constants.ts +251 -0
  310. package/src/util/DataResolver.ts +146 -0
  311. package/src/util/Enums.ts +10 -0
  312. package/src/util/Events.ts +178 -0
  313. package/src/util/GuildMemberFlagsBitField.ts +43 -0
  314. package/src/util/IntentsBitField.ts +35 -0
  315. package/src/util/InviteFlagsBitField.ts +26 -0
  316. package/src/util/Invites.ts +27 -0
  317. package/src/util/LimitedCollection.ts +73 -0
  318. package/src/util/MessageFlagsBitField.ts +43 -0
  319. package/src/util/Options.ts +215 -0
  320. package/src/util/Partials.ts +50 -0
  321. package/src/util/PermissionsBitField.ts +113 -0
  322. package/src/util/RoleFlagsBitField.ts +26 -0
  323. package/src/util/SKUFlagsBitField.ts +26 -0
  324. package/src/util/ShardEvents.ts +26 -0
  325. package/src/util/Status.ts +16 -0
  326. package/src/util/Sweepers.ts +532 -0
  327. package/src/util/Symbols.ts +1 -0
  328. package/src/util/SystemChannelFlagsBitField.ts +45 -0
  329. package/src/util/ThreadMemberFlagsBitField.ts +33 -0
  330. package/src/util/Transformers.ts +123 -0
  331. package/src/util/UserFlagsBitField.ts +33 -0
  332. package/src/util/Util.ts +519 -0
@@ -0,0 +1,1202 @@
1
+ import { Collection } from '@ovencord/collection';
2
+ import { messageLink } from '@ovencord/formatters';
3
+ import { DiscordSnowflake } from '@sapphire/snowflake';
4
+ import { InteractionType,
5
+ ChannelType,
6
+ MessageType,
7
+ MessageFlags,
8
+ MessageReferenceType,
9
+ PermissionFlagsBits,
10
+ } from 'discord-api-types/v10';
11
+ import { DiscordjsError, ErrorCodes } from '../errors/index.js';
12
+ import { ReactionManager } from '../managers/ReactionManager.js';
13
+ import { createComponent, findComponentByCustomId } from '../util/Components.js';
14
+ import { NonSystemMessageTypes, MaxBulkDeletableMessageAge, UndeletableMessageTypes } from '../util/Constants.js';
15
+ import { MessageFlagsBitField } from '../util/MessageFlagsBitField.js';
16
+ import { PermissionsBitField } from '../util/PermissionsBitField.js';
17
+ import { _transformAPIMessageInteractionMetadata } from '../util/Transformers.js';
18
+ import { cleanContent, resolvePartialEmoji, transformResolved } from '../util/Util.js';
19
+ import { Attachment } from './Attachment.js';
20
+ import { Base } from './Base.js';
21
+ import { ClientApplication } from './ClientApplication.js';
22
+ import { Embed } from './Embed.js';
23
+ import { InteractionCollector } from './InteractionCollector.js';
24
+ import { MessageMentions } from './MessageMentions.js';
25
+ import { MessagePayload } from './MessagePayload.js';
26
+ import { Poll } from './Poll.js';
27
+ import { ReactionCollector } from './ReactionCollector.js';
28
+ import { Sticker } from './Sticker.js';
29
+
30
+ /**
31
+ * Represents a message on Discord.
32
+ *
33
+ * @extends {Base}
34
+ */
35
+ export class Message extends Base {
36
+ public client: any;
37
+ public channelId: any;
38
+ public guildId: any;
39
+ public id: any;
40
+ public createdTimestamp: any;
41
+ public type: any;
42
+ public system: any;
43
+ public content: any;
44
+ public author: any;
45
+ public pinned: any;
46
+ public tts: any;
47
+ public nonce: any;
48
+ public embeds: any;
49
+ public components: any;
50
+ public attachments: any;
51
+ public stickers: any;
52
+ public position: any;
53
+ public roleSubscriptionData: any;
54
+ public resolved: any;
55
+ public editedTimestamp: any;
56
+ public reactions: any;
57
+ public mentions: any;
58
+ public webhookId: any;
59
+ public groupActivityApplication: any;
60
+ public applicationId: any;
61
+ public activity: any;
62
+ public flags: any;
63
+ public reference: any;
64
+ public interactionMetadata: any;
65
+ public poll: any;
66
+ public messageSnapshots: any;
67
+ public call: any;
68
+ constructor(client, data) {
69
+ super(client);
70
+
71
+ /**
72
+ * The id of the channel the message was sent in
73
+ *
74
+ * @type {Snowflake}
75
+ */
76
+ this.channelId = data.channel_id;
77
+
78
+ /**
79
+ * The id of the guild the message was sent in, if any
80
+ *
81
+ * @type {?Snowflake}
82
+ */
83
+ this.guildId = data.guild_id ?? this.channel?.guild?.id ?? null;
84
+
85
+ this._patch(data);
86
+ }
87
+
88
+ _patch(data) {
89
+ /**
90
+ * The message's id
91
+ *
92
+ * @type {Snowflake}
93
+ */
94
+ this.id = data.id;
95
+
96
+ /**
97
+ * The timestamp the message was sent at
98
+ *
99
+ * @type {number}
100
+ */
101
+ this.createdTimestamp = DiscordSnowflake.timestampFrom(this.id);
102
+
103
+ if ('type' in data) {
104
+ /**
105
+ * The type of the message
106
+ *
107
+ * @type {?MessageType}
108
+ */
109
+ this.type = data.type;
110
+
111
+ /**
112
+ * Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications)
113
+ *
114
+ * @type {?boolean}
115
+ */
116
+ this.system = !NonSystemMessageTypes.includes(this.type);
117
+ } else {
118
+ this.system ??= null;
119
+ this.type ??= null;
120
+ }
121
+
122
+ if ('content' in data) {
123
+ /**
124
+ * The content of the message.
125
+ * <info>This property requires the {@link GatewayIntentBits.MessageContent} privileged intent
126
+ * in a guild for messages that do not mention the client.</info>
127
+ *
128
+ * @type {?string}
129
+ */
130
+ this.content = data.content;
131
+ } else {
132
+ this.content ??= null;
133
+ }
134
+
135
+ if ('author' in data) {
136
+ /**
137
+ * The author of the message
138
+ *
139
+ * @type {?User}
140
+ */
141
+ this.author = this.client.users._add(data.author, !data.webhook_id);
142
+ } else {
143
+ this.author ??= null;
144
+ }
145
+
146
+ if ('pinned' in data) {
147
+ /**
148
+ * Whether or not this message is pinned
149
+ *
150
+ * @type {?boolean}
151
+ */
152
+ this.pinned = Boolean(data.pinned);
153
+ } else {
154
+ this.pinned ??= null;
155
+ }
156
+
157
+ if ('tts' in data) {
158
+ /**
159
+ * Whether or not the message was Text-To-Speech
160
+ *
161
+ * @type {?boolean}
162
+ */
163
+ this.tts = data.tts;
164
+ } else {
165
+ this.tts ??= null;
166
+ }
167
+
168
+ if ('nonce' in data) {
169
+ /**
170
+ * A random number or string used for checking message delivery
171
+ * <warn>This is only received after the message was sent successfully, and
172
+ * lost if re-fetched</warn>
173
+ *
174
+ * @type {?string}
175
+ */
176
+ this.nonce = data.nonce;
177
+ } else {
178
+ this.nonce ??= null;
179
+ }
180
+
181
+ if ('embeds' in data) {
182
+ /**
183
+ * An array of embeds in the message - e.g. YouTube Player.
184
+ * <info>This property requires the {@link GatewayIntentBits.MessageContent} privileged intent
185
+ * in a guild for messages that do not mention the client.</info>
186
+ *
187
+ * @type {Embed[]}
188
+ */
189
+ this.embeds = data.embeds.map(embed => new Embed(embed));
190
+ } else {
191
+ this.embeds = this.embeds?.slice() ?? [];
192
+ }
193
+
194
+ if ('components' in data) {
195
+ /**
196
+ * An array of components in the message.
197
+ * <info>This property requires the {@link GatewayIntentBits.MessageContent} privileged intent
198
+ * in a guild for messages that do not mention the client.</info>
199
+ *
200
+ * @type {Component[]}
201
+ */
202
+ this.components = data.components.map(component => createComponent(component));
203
+ } else {
204
+ this.components = this.components?.slice() ?? [];
205
+ }
206
+
207
+ if ('attachments' in data) {
208
+ /**
209
+ * A collection of attachments in the message - e.g. Pictures - mapped by their ids.
210
+ * <info>This property requires the {@link GatewayIntentBits.MessageContent} privileged intent
211
+ * in a guild for messages that do not mention the client.</info>
212
+ *
213
+ * @type {Collection<Snowflake, Attachment>}
214
+ */
215
+ this.attachments = new Collection();
216
+ if (data.attachments) {
217
+ for (const attachment of data.attachments) {
218
+ this.attachments.set(attachment.id, new Attachment(attachment));
219
+ }
220
+ }
221
+ } else {
222
+ this.attachments = new Collection(this.attachments);
223
+ }
224
+
225
+ if ('sticker_items' in data || 'stickers' in data) {
226
+ /**
227
+ * A collection of stickers in the message
228
+ *
229
+ * @type {Collection<Snowflake, Sticker>}
230
+ */
231
+ this.stickers = new Collection(
232
+ (data.sticker_items ?? data.stickers)?.map(sticker => [sticker.id, new Sticker(this.client, sticker)]),
233
+ );
234
+ } else {
235
+ this.stickers = new Collection(this.stickers);
236
+ }
237
+
238
+ if ('position' in data) {
239
+ /**
240
+ * A generally increasing integer (there may be gaps or duplicates) that represents
241
+ * the approximate position of the message in a thread.
242
+ *
243
+ * @type {?number}
244
+ */
245
+ this.position = data.position;
246
+ } else {
247
+ this.position ??= null;
248
+ }
249
+
250
+ if ('role_subscription_data' in data) {
251
+ /**
252
+ * Role subscription data found on {@link MessageType.RoleSubscriptionPurchase} messages.
253
+ *
254
+ * @typedef {Object} RoleSubscriptionData
255
+ * @property {Snowflake} roleSubscriptionListingId The id of the SKU and listing the user is subscribed to
256
+ * @property {string} tierName The name of the tier the user is subscribed to
257
+ * @property {number} totalMonthsSubscribed The total number of months the user has been subscribed for
258
+ * @property {boolean} isRenewal Whether this notification is a renewal
259
+ */
260
+
261
+ /**
262
+ * The data of the role subscription purchase or renewal.
263
+ * <info>This is present on {@link MessageType.RoleSubscriptionPurchase} messages.</info>
264
+ *
265
+ * @type {?RoleSubscriptionData}
266
+ */
267
+ this.roleSubscriptionData = {
268
+ roleSubscriptionListingId: data.role_subscription_data.role_subscription_listing_id,
269
+ tierName: data.role_subscription_data.tier_name,
270
+ totalMonthsSubscribed: data.role_subscription_data.total_months_subscribed,
271
+ isRenewal: data.role_subscription_data.is_renewal,
272
+ };
273
+ } else {
274
+ this.roleSubscriptionData ??= null;
275
+ }
276
+
277
+ if ('resolved' in data) {
278
+ /**
279
+ * Resolved data from auto-populated select menus.
280
+ *
281
+ * @type {?CommandInteractionResolvedData}
282
+ */
283
+ this.resolved = transformResolved(
284
+ { client: this.client, guild: this.guild, channel: this.channel },
285
+ data.resolved,
286
+ );
287
+ } else {
288
+ this.resolved ??= null;
289
+ }
290
+
291
+ // Discord sends null if the message has not been edited
292
+ if (data.edited_timestamp) {
293
+ /**
294
+ * The timestamp the message was last edited at (if applicable)
295
+ *
296
+ * @type {?number}
297
+ */
298
+ this.editedTimestamp = Date.parse(data.edited_timestamp);
299
+ } else {
300
+ this.editedTimestamp ??= null;
301
+ }
302
+
303
+ if ('reactions' in data) {
304
+ /**
305
+ * A manager of the reactions belonging to this message
306
+ *
307
+ * @type {ReactionManager}
308
+ */
309
+ this.reactions = new ReactionManager(this);
310
+ if (data.reactions?.length > 0) {
311
+ for (const reaction of data.reactions) {
312
+ this.reactions._add(reaction);
313
+ }
314
+ }
315
+ } else {
316
+ this.reactions ??= new ReactionManager(this);
317
+ }
318
+
319
+ /**
320
+ * All valid mentions that the message contains
321
+ *
322
+ * @type {MessageMentions}
323
+ */
324
+ this.mentions = new MessageMentions(
325
+ this,
326
+ data.mentions ?? this.mentions?.users,
327
+ data.mention_roles ?? this.mentions?.roles,
328
+ data.mention_everyone ?? this.mentions?.everyone,
329
+ data.mention_channels ?? this.mentions?.crosspostedChannels,
330
+ data.referenced_message?.author ?? this.mentions?.repliedUser,
331
+ );
332
+
333
+ if ('webhook_id' in data) {
334
+ /**
335
+ * The id of the webhook that sent the message, if applicable
336
+ *
337
+ * @type {?Snowflake}
338
+ */
339
+ this.webhookId = data.webhook_id;
340
+ } else {
341
+ this.webhookId ??= null;
342
+ }
343
+
344
+ if ('application' in data) {
345
+ /**
346
+ * Supplemental application information for group activities
347
+ *
348
+ * @type {?ClientApplication}
349
+ */
350
+ this.groupActivityApplication = new ClientApplication(this.client, data.application);
351
+ } else {
352
+ this.groupActivityApplication ??= null;
353
+ }
354
+
355
+ if ('application_id' in data) {
356
+ /**
357
+ * The id of the application of the interaction that sent this message, if any
358
+ *
359
+ * @type {?Snowflake}
360
+ */
361
+ this.applicationId = data.application_id;
362
+ } else {
363
+ this.applicationId ??= null;
364
+ }
365
+
366
+ if ('activity' in data) {
367
+ /**
368
+ * Group activity
369
+ *
370
+ * @type {?MessageActivity}
371
+ */
372
+ this.activity = {
373
+ partyId: data.activity.party_id,
374
+ type: data.activity.type,
375
+ };
376
+ } else {
377
+ this.activity ??= null;
378
+ }
379
+
380
+ if ('thread' in data) {
381
+ this.client.channels._add(data.thread, this.guild);
382
+ }
383
+
384
+ if (this.member && data.member) {
385
+ this.member._patch(data.member);
386
+ } else if (data.member && this.guild && this.author) {
387
+ this.guild.members._add(Object.assign(data.member, { user: this.author }));
388
+ }
389
+
390
+ if ('flags' in data) {
391
+ /**
392
+ * Flags that are applied to the message
393
+ *
394
+ * @type {Readonly<MessageFlagsBitField>}
395
+ */
396
+ this.flags = new MessageFlagsBitField(data.flags).freeze();
397
+ } else {
398
+ this.flags = new MessageFlagsBitField(this.flags).freeze();
399
+ }
400
+
401
+ /**
402
+ * Reference data sent in a message that contains ids identifying the referenced message.
403
+ * This can be present in the following types of message:
404
+ * - {@link MessageFlags.Crossposted}
405
+ * - {@link MessageType.ChannelPinnedMessage}
406
+ * - {@link MessageType.ChannelFollowAdd}
407
+ * - {@link MessageType.Reply}
408
+ * - {@link MessageType.ThreadStarterMessage}
409
+ *
410
+ * @see {@link https://discord.com/developers/docs/resources/message#message-object-message-types}
411
+ * @typedef {Object} MessageReference
412
+ * @property {Snowflake} channelId The channel id that was referenced
413
+ * @property {Snowflake|undefined} guildId The guild id that was referenced
414
+ * @property {Snowflake|undefined} messageId The message id that was referenced
415
+ * @property {MessageReferenceType} type The type of message reference
416
+ */
417
+
418
+ if ('message_reference' in data) {
419
+ /**
420
+ * Message reference data
421
+ *
422
+ * @type {?MessageReference}
423
+ */
424
+ this.reference = {
425
+ channelId: data.message_reference.channel_id,
426
+ guildId: data.message_reference.guild_id,
427
+ messageId: data.message_reference.message_id,
428
+ type: data.message_reference.type,
429
+ };
430
+ } else {
431
+ this.reference ??= null;
432
+ }
433
+
434
+ if (data.referenced_message) {
435
+ this.channel?.messages._add({ guild_id: data.message_reference?.guild_id, ...data.referenced_message });
436
+ }
437
+
438
+ if (data.interaction_metadata) {
439
+ /**
440
+ * Partial data of the interaction that a message is a result of
441
+ *
442
+ * @typedef {Object} MessageInteractionMetadata
443
+ * @property {Snowflake} id The interaction's id
444
+ * @property {InteractionType} type The type of the interaction
445
+ * @property {User} user The user that invoked the interaction
446
+ * @property {AuthorizingIntegrationOwners} authorizingIntegrationOwners
447
+ * Mapping of integration types that the application was authorized for the related user or guild ids
448
+ * @property {?Snowflake} originalResponseMessageId
449
+ * Id of the original response message. Present only on follow-up messages
450
+ * @property {?Snowflake} interactedMessageId
451
+ * Id of the message that contained interactive component.
452
+ * Present only on messages created from component interactions
453
+ * @property {?MessageInteractionMetadata} triggeringInteractionMetadata
454
+ * Metadata for the interaction that was used to open the modal. Present only on modal submit interactions
455
+ */
456
+
457
+ /**
458
+ * Partial data of the interaction that this message is a result of
459
+ *
460
+ * @type {?MessageInteractionMetadata}
461
+ */
462
+ this.interactionMetadata = _transformAPIMessageInteractionMetadata(this.client, data.interaction_metadata);
463
+ } else {
464
+ this.interactionMetadata ??= null;
465
+ }
466
+
467
+ if (data.poll) {
468
+ if (this.poll) {
469
+ this.poll._patch(data.poll);
470
+ } else {
471
+ /**
472
+ * The poll that was sent with the message
473
+ *
474
+ * @type {?Poll}
475
+ */
476
+ this.poll = new Poll(this.client, data.poll, this, this.channel);
477
+ }
478
+ } else {
479
+ this.poll ??= null;
480
+ }
481
+
482
+ if (data.message_snapshots) {
483
+ /**
484
+ * The message snapshots associated with the message reference
485
+ *
486
+ * @type {Collection<Snowflake, Message>}
487
+ */
488
+ this.messageSnapshots = data.message_snapshots.reduce((coll, snapshot) => {
489
+ const channel = this.client.channels.resolve(this.reference.channelId);
490
+ const snapshotData = {
491
+ ...snapshot.message,
492
+ id: this.reference.messageId,
493
+ channel_id: this.reference.channelId,
494
+ guild_id: this.reference.guildId,
495
+ };
496
+
497
+ return coll.set(
498
+ this.reference.messageId,
499
+ channel ? channel.messages._add(snapshotData) : new this.constructor(this.client, snapshotData),
500
+ );
501
+ }, new Collection());
502
+ } else {
503
+ this.messageSnapshots ??= new Collection();
504
+ }
505
+
506
+ /**
507
+ * A call associated with a message
508
+ *
509
+ * @typedef {Object} MessageCall
510
+ * @property {Readonly<?Date>} endedAt The time the call ended
511
+ * @property {?number} endedTimestamp The timestamp the call ended
512
+ * @property {Snowflake[]} participants The ids of the users that participated in the call
513
+ */
514
+
515
+ if (data.call) {
516
+ /**
517
+ * The call associated with the message
518
+ *
519
+ * @type {?MessageCall}
520
+ */
521
+ this.call = {
522
+ endedTimestamp: data.call.ended_timestamp ? Date.parse(data.call.ended_timestamp) : null,
523
+ participants: data.call.participants,
524
+ get endedAt() {
525
+ return this.endedTimestamp && new Date(this.endedTimestamp);
526
+ },
527
+ };
528
+ } else {
529
+ this.call ??= null;
530
+ }
531
+ }
532
+
533
+ /**
534
+ * The channel that the message was sent in
535
+ *
536
+ * @type {TextBasedChannels}
537
+ * @readonly
538
+ */
539
+ get channel() {
540
+ return this.client.channels.resolve(this.channelId);
541
+ }
542
+
543
+ /**
544
+ * Whether or not this message is a partial
545
+ *
546
+ * @type {boolean}
547
+ * @readonly
548
+ */
549
+ get partial() {
550
+ return typeof this.content !== 'string' || !this.author;
551
+ }
552
+
553
+ /**
554
+ * Represents the author of the message as a guild member.
555
+ * Only available if the message comes from a guild where the author is still a member
556
+ *
557
+ * @type {?GuildMember}
558
+ * @readonly
559
+ */
560
+ get member() {
561
+ return this.guild?.members.resolve(this.author) ?? null;
562
+ }
563
+
564
+ /**
565
+ * The time the message was sent at
566
+ *
567
+ * @type {Date}
568
+ * @readonly
569
+ */
570
+ get createdAt() {
571
+ return new Date(this.createdTimestamp);
572
+ }
573
+
574
+ /**
575
+ * The time the message was last edited at (if applicable)
576
+ *
577
+ * @type {?Date}
578
+ * @readonly
579
+ */
580
+ get editedAt() {
581
+ return this.editedTimestamp && new Date(this.editedTimestamp);
582
+ }
583
+
584
+ /**
585
+ * The guild the message was sent in (if in a guild channel)
586
+ *
587
+ * @type {?Guild}
588
+ * @readonly
589
+ */
590
+ get guild() {
591
+ return this.client.guilds.resolve(this.guildId) ?? this.channel?.guild ?? null;
592
+ }
593
+
594
+ /**
595
+ * Whether this message has a thread associated with it
596
+ *
597
+ * @type {boolean}
598
+ * @readonly
599
+ */
600
+ get hasThread() {
601
+ return this.flags.has(MessageFlags.HasThread);
602
+ }
603
+
604
+ /**
605
+ * The thread started by this message
606
+ * <info>This property is not suitable for checking whether a message has a thread,
607
+ * use {@link Message#hasThread} instead.</info>
608
+ *
609
+ * @type {?ThreadChannel}
610
+ * @readonly
611
+ */
612
+ get thread() {
613
+ return this.channel?.threads?.cache.get(this.id) ?? null;
614
+ }
615
+
616
+ /**
617
+ * The URL to jump to this message
618
+ *
619
+ * @type {string}
620
+ * @readonly
621
+ */
622
+ get url() {
623
+ return this.inGuild() ? messageLink(this.channelId, this.id, this.guildId) : messageLink(this.channelId, this.id);
624
+ }
625
+
626
+ /**
627
+ * The message contents with all mentions replaced by the equivalent text.
628
+ * If mentions cannot be resolved to a name, the relevant mention in the message content will not be converted.
629
+ *
630
+ * @type {?string}
631
+ * @readonly
632
+ */
633
+ get cleanContent() {
634
+ // eslint-disable-next-line eqeqeq
635
+ return this.content != null && this.channel ? cleanContent(this.content, this.channel) : null;
636
+ }
637
+
638
+ /**
639
+ * Creates a reaction collector.
640
+ *
641
+ * @param {ReactionCollectorOptions} [options={}] Options to send to the collector
642
+ * @returns {ReactionCollector}
643
+ * @example
644
+ * // Create a reaction collector
645
+ * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId';
646
+ * const collector = message.createReactionCollector({ filter, time: 15_000 });
647
+ * collector.on('collect', r => console.log(`Collected ${r.emoji.name}`));
648
+ * collector.on('end', collected => console.log(`Collected ${collected.size} items`));
649
+ */
650
+ createReactionCollector(options = {}) {
651
+ return new ReactionCollector(this, options);
652
+ }
653
+
654
+ /**
655
+ * An object containing the same properties as CollectorOptions, but a few more:
656
+ *
657
+ * @typedef {ReactionCollectorOptions} AwaitReactionsOptions
658
+ * @property {string[]} [errors] Stop/end reasons that cause the promise to reject
659
+ */
660
+
661
+ /**
662
+ * Similar to createReactionCollector but in promise form.
663
+ * Resolves with a collection of reactions that pass the specified filter.
664
+ *
665
+ * @param {AwaitReactionsOptions} [options={}] Optional options to pass to the internal collector
666
+ * @returns {Promise<Collection<string|Snowflake, MessageReaction>>}
667
+ * @example
668
+ * // Create a reaction collector
669
+ * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId'
670
+ * message.awaitReactions({ filter, time: 15_000 })
671
+ * .then(collected => console.log(`Collected ${collected.size} reactions`))
672
+ * .catch(console.error);
673
+ */
674
+ async awaitReactions(options = {}) {
675
+ return new Promise((resolve, reject) => {
676
+ const collector = this.createReactionCollector(options);
677
+ collector.once('end', (reactions, reason) => {
678
+ if (options.errors?.includes(reason)) reject(reactions);
679
+ else resolve(reactions);
680
+ });
681
+ });
682
+ }
683
+
684
+ /**
685
+ * @typedef {CollectorOptions} MessageComponentCollectorOptions
686
+ * @property {ComponentType} [componentType] The type of component to listen for
687
+ * @property {number} [max] The maximum total amount of interactions to collect
688
+ * @property {number} [maxComponents] The maximum number of components to collect
689
+ * @property {number} [maxUsers] The maximum number of users to interact
690
+ */
691
+
692
+ /**
693
+ * Creates a message component interaction collector.
694
+ *
695
+ * @param {MessageComponentCollectorOptions} [options={}] Options to send to the collector
696
+ * @returns {InteractionCollector}
697
+ * @example
698
+ * // Create a message component interaction collector
699
+ * const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId';
700
+ * const collector = message.createMessageComponentCollector({ filter, time: 15_000 });
701
+ * collector.on('collect', i => console.log(`Collected ${i.customId}`));
702
+ * collector.on('end', collected => console.log(`Collected ${collected.size} items`));
703
+ */
704
+ createMessageComponentCollector(options = {}) {
705
+ return new InteractionCollector(this.client, {
706
+ ...options,
707
+ interactionType: InteractionType.MessageComponent,
708
+ message: this,
709
+ });
710
+ }
711
+
712
+ /**
713
+ * An object containing the same properties as CollectorOptions, but a few more:
714
+ *
715
+ * @typedef {Object} AwaitMessageComponentOptions
716
+ * @property {CollectorFilter} [filter] The filter applied to this collector
717
+ * @property {number} [time] Time to wait for an interaction before rejecting
718
+ * @property {ComponentType} [componentType] The type of component interaction to collect
719
+ * @property {number} [idle] Time to wait without another message component interaction before ending the collector
720
+ * @property {boolean} [dispose] Whether to remove the message component interaction after collecting
721
+ */
722
+
723
+ /**
724
+ * Collects a single component interaction that passes the filter.
725
+ * The Promise will reject if the time expires.
726
+ *
727
+ * @param {AwaitMessageComponentOptions} [options={}] Options to pass to the internal collector
728
+ * @returns {Promise<MessageComponentInteraction>}
729
+ * @example
730
+ * // Collect a message component interaction
731
+ * const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId';
732
+ * message.awaitMessageComponent({ filter, time: 15_000 })
733
+ * .then(interaction => console.log(`${interaction.customId} was clicked!`))
734
+ * .catch(console.error);
735
+ */
736
+ async awaitMessageComponent(options = {}) {
737
+ const _options = { ...options, max: 1 };
738
+ return new Promise((resolve, reject) => {
739
+ const collector = this.createMessageComponentCollector(_options);
740
+ collector.once('end', (interactions, reason) => {
741
+ const interaction = interactions.first();
742
+ if (interaction) resolve(interaction);
743
+ else reject(new DiscordjsError(ErrorCodes.InteractionCollectorError, reason));
744
+ });
745
+ });
746
+ }
747
+
748
+ /**
749
+ * Whether the message is editable by the client user
750
+ *
751
+ * @type {boolean}
752
+ * @readonly
753
+ */
754
+ get editable() {
755
+ const precheck = Boolean(
756
+ this.author.id === this.client.user.id &&
757
+ (!this.guild || this.channel?.viewable) &&
758
+ this.reference?.type !== MessageReferenceType.Forward,
759
+ );
760
+
761
+ // Regardless of permissions thread messages cannot be edited if
762
+ // the thread is archived or the thread is locked and the bot does not have permission to manage threads.
763
+ if (this.channel?.isThread()) {
764
+ if (this.channel.archived) return false;
765
+ if (this.channel.locked) {
766
+ const permissions = this.channel.permissionsFor(this.client.user);
767
+ if (!permissions?.has(PermissionFlagsBits.ManageThreads, true)) return false;
768
+ }
769
+ }
770
+
771
+ return precheck;
772
+ }
773
+
774
+ /**
775
+ * Whether the message is deletable by the client user
776
+ *
777
+ * @type {boolean}
778
+ * @readonly
779
+ */
780
+ get deletable() {
781
+ if (UndeletableMessageTypes.includes(this.type)) return false;
782
+
783
+ if (!this.guild) {
784
+ return this.author.id === this.client.user.id;
785
+ }
786
+
787
+ // DMChannel does not have viewable property, so check viewable after proved that message is on a guild.
788
+ if (!this.channel?.viewable) {
789
+ return false;
790
+ }
791
+
792
+ const permissions = this.channel?.permissionsFor(this.client.user);
793
+ if (!permissions) return false;
794
+ // This flag allows deleting even if timed out
795
+ if (permissions.has(PermissionFlagsBits.Administrator, false)) return true;
796
+
797
+ // The auto moderation action message author is the reference message author
798
+ return (
799
+ (this.type !== MessageType.AutoModerationAction && this.author.id === this.client.user.id) ||
800
+ (permissions.has(PermissionFlagsBits.ManageMessages, false) && !this.guild.members.me.isCommunicationDisabled())
801
+ );
802
+ }
803
+
804
+ /**
805
+ * Whether the message is bulk deletable by the client user
806
+ *
807
+ * @type {boolean}
808
+ * @readonly
809
+ * @example
810
+ * // Filter for bulk deletable messages
811
+ * channel.bulkDelete(messages.filter(message => message.bulkDeletable));
812
+ */
813
+ get bulkDeletable() {
814
+ return (
815
+ (this.inGuild() &&
816
+ Date.now() - this.createdTimestamp < MaxBulkDeletableMessageAge &&
817
+ this.deletable &&
818
+ this.channel?.permissionsFor(this.client.user).has(PermissionFlagsBits.ManageMessages, false)) ??
819
+ false
820
+ );
821
+ }
822
+
823
+ /**
824
+ * Whether the message is pinnable by the client user
825
+ *
826
+ * @type {boolean}
827
+ * @readonly
828
+ */
829
+ get pinnable() {
830
+ const { channel } = this;
831
+
832
+ if (this.system) return false;
833
+ if (!this.guild) return true;
834
+ if (!channel || channel.isVoiceBased() || !channel.viewable) return false;
835
+
836
+ const permissions = channel.permissionsFor(this.client.user);
837
+ if (!permissions) return false;
838
+
839
+ return permissions.has(PermissionFlagsBits.ReadMessageHistory | PermissionFlagsBits.PinMessages);
840
+ }
841
+
842
+ /**
843
+ * Fetches the Message this crosspost/reply/pin-add references, if available to the client
844
+ *
845
+ * @returns {Promise<Message>}
846
+ */
847
+ async fetchReference() {
848
+ if (!this.reference) throw new DiscordjsError(ErrorCodes.MessageReferenceMissing);
849
+ const { channelId, messageId } = this.reference;
850
+ if (!messageId) throw new DiscordjsError(ErrorCodes.MessageReferenceMissing);
851
+ const channel = this.client.channels.resolve(channelId);
852
+ if (!channel) throw new DiscordjsError(ErrorCodes.GuildChannelResolve);
853
+ return channel.messages.fetch(messageId);
854
+ }
855
+
856
+ /**
857
+ * Whether the message is crosspostable by the client user
858
+ *
859
+ * @type {boolean}
860
+ * @readonly
861
+ */
862
+ get crosspostable() {
863
+ const bitfield =
864
+ PermissionFlagsBits.SendMessages |
865
+ (this.author.id === this.client.user.id ? PermissionsBitField.DefaultBit : PermissionFlagsBits.ManageMessages);
866
+ const { channel } = this;
867
+ return Boolean(
868
+ channel?.type === ChannelType.GuildAnnouncement &&
869
+ !this.flags.has(MessageFlags.Crossposted) &&
870
+ this.reference?.type !== MessageReferenceType.Forward &&
871
+ this.type === MessageType.Default &&
872
+ !this.poll &&
873
+ channel.viewable &&
874
+ channel.permissionsFor(this.client.user)?.has(bitfield, false),
875
+ );
876
+ }
877
+
878
+ /**
879
+ * Edits the content of the message.
880
+ *
881
+ * @param {string|MessageEditOptions|MessagePayload|FileBodyEncodable<RESTPatchAPIChannelMessageJSONBody>|JSONEncodable<RESTPatchAPIChannelMessageJSONBody>} options The options to provide
882
+ * @returns {Promise<Message>}
883
+ * @example
884
+ * // Update the content of a message
885
+ * message.edit('This is my new content!')
886
+ * .then(msg => console.log(`Updated the content of a message to ${msg.content}`))
887
+ * .catch(console.error);
888
+ */
889
+ async edit(options) {
890
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
891
+ return this.channel.messages.edit(this, options);
892
+ }
893
+
894
+ /**
895
+ * Publishes a message in an announcement channel to all channels following it.
896
+ *
897
+ * @returns {Promise<Message>}
898
+ * @example
899
+ * // Crosspost a message
900
+ * if (message.channel.type === ChannelType.GuildAnnouncement) {
901
+ * message.crosspost()
902
+ * .then(() => console.log('Crossposted message'))
903
+ * .catch(console.error);
904
+ * }
905
+ */
906
+ async crosspost() {
907
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
908
+ return this.channel.messages.crosspost(this.id);
909
+ }
910
+
911
+ /**
912
+ * Pins this message to the channel's pinned messages.
913
+ *
914
+ * @param {string} [reason] Reason for pinning
915
+ * @returns {Promise<Message>}
916
+ * @example
917
+ * // Pin a message
918
+ * message.pin()
919
+ * .then(console.log)
920
+ * .catch(console.error)
921
+ */
922
+ async pin(reason) {
923
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
924
+ await this.channel.messages.pin(this.id, reason);
925
+ return this;
926
+ }
927
+
928
+ /**
929
+ * Unpins this message from the channel's pinned messages.
930
+ *
931
+ * @param {string} [reason] Reason for unpinning
932
+ * @returns {Promise<Message>}
933
+ * @example
934
+ * // Unpin a message
935
+ * message.unpin()
936
+ * .then(console.log)
937
+ * .catch(console.error)
938
+ */
939
+ async unpin(reason) {
940
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
941
+ await this.channel.messages.unpin(this.id, reason);
942
+ return this;
943
+ }
944
+
945
+ /**
946
+ * Adds a reaction to the message.
947
+ *
948
+ * @param {EmojiIdentifierResolvable} emoji The emoji to react with
949
+ * @returns {Promise<MessageReaction>}
950
+ * @example
951
+ * // React to a message with a unicode emoji
952
+ * message.react('🤔')
953
+ * .then(console.log)
954
+ * .catch(console.error);
955
+ * @example
956
+ * // React to a message with a custom emoji
957
+ * message.react(message.guild.emojis.cache.get('123456789012345678'))
958
+ * .then(console.log)
959
+ * .catch(console.error);
960
+ */
961
+ async react(emoji) {
962
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
963
+ await this.channel.messages.react(this.id, emoji);
964
+
965
+ return this.client.actions.MessageReactionAdd.handle(
966
+ {
967
+ [this.client.actions.injectedUser]: this.client.user,
968
+ [this.client.actions.injectedChannel]: this.channel,
969
+ [this.client.actions.injectedMessage]: this,
970
+ emoji: resolvePartialEmoji(emoji),
971
+ },
972
+ true,
973
+ ).reaction;
974
+ }
975
+
976
+ /**
977
+ * Deletes the message.
978
+ *
979
+ * @returns {Promise<Message>}
980
+ * @example
981
+ * // Delete a message
982
+ * message.delete()
983
+ * .then(msg => console.log(`Deleted message from ${msg.author.username}`))
984
+ * .catch(console.error);
985
+ */
986
+ async delete() {
987
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
988
+ await this.channel.messages.delete(this.id);
989
+ return this;
990
+ }
991
+
992
+ /**
993
+ * Options provided when sending a message as an inline reply.
994
+ *
995
+ * @typedef {BaseMessageCreateOptions} MessageReplyOptions
996
+ * @property {boolean} [failIfNotExists=this.client.options.failIfNotExists] Whether to error if the referenced
997
+ * message does not exist (creates a standard message in this case when false)
998
+ */
999
+
1000
+ /**
1001
+ * Send an inline reply to this message.
1002
+ *
1003
+ * @param {string|MessagePayload|MessageReplyOptions} options The options to provide
1004
+ * @returns {Promise<Message>}
1005
+ * @example
1006
+ * // Reply to a message
1007
+ * message.reply('This is a reply!')
1008
+ * .then(() => console.log(`Replied to message "${message.content}"`))
1009
+ * .catch(console.error);
1010
+ */
1011
+ async reply(options) {
1012
+ let data;
1013
+
1014
+ if (options instanceof MessagePayload) {
1015
+ data = options;
1016
+ } else {
1017
+ data = MessagePayload.create(this, options, {
1018
+ messageReference: {
1019
+ messageId: this.id,
1020
+ channelId: this.channelId,
1021
+ guildId: this.guildId ?? undefined,
1022
+ type: MessageReferenceType.Default,
1023
+ failIfNotExists: options?.failIfNotExists ?? this.client.options.failIfNotExists,
1024
+ },
1025
+ });
1026
+ }
1027
+
1028
+ return this.client.channels.createMessage(this.channelId, data);
1029
+ }
1030
+
1031
+ /**
1032
+ * Forwards this message.
1033
+ *
1034
+ * @param {TextChannelResolvable} channel The channel to forward this message to.
1035
+ * @returns {Promise<Message>}
1036
+ */
1037
+ async forward(channel) {
1038
+ return this.client.channels.createMessage(channel, {
1039
+ messageReference: {
1040
+ messageId: this.id,
1041
+ channelId: this.channelId,
1042
+ guildId: this.guildId ?? undefined,
1043
+ type: MessageReferenceType.Forward,
1044
+ },
1045
+ });
1046
+ }
1047
+
1048
+ /**
1049
+ * Options for starting a thread on a message.
1050
+ *
1051
+ * @typedef {Object} StartThreadOptions
1052
+ * @property {string} name The name of the new thread
1053
+ * @property {ThreadAutoArchiveDuration} [autoArchiveDuration=this.channel.defaultAutoArchiveDuration] The amount of
1054
+ * time after which the thread should automatically archive in case of no recent activity
1055
+ * @property {string} [reason] Reason for creating the thread
1056
+ * @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the thread in seconds
1057
+ */
1058
+
1059
+ /**
1060
+ * Create a new public thread from this message
1061
+ *
1062
+ * @see GuildTextThreadManager#create
1063
+ * @param {StartThreadOptions} [options] Options for starting a thread on this message
1064
+ * @returns {Promise<ThreadChannel>}
1065
+ */
1066
+ async startThread(options = {}) {
1067
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
1068
+ if (![ChannelType.GuildText, ChannelType.GuildAnnouncement].includes(this.channel.type)) {
1069
+ throw new DiscordjsError(ErrorCodes.MessageThreadParent);
1070
+ }
1071
+
1072
+ if (this.hasThread) throw new DiscordjsError(ErrorCodes.MessageExistingThread);
1073
+ return this.channel.threads.create({ ...options, startMessage: this });
1074
+ }
1075
+
1076
+ /**
1077
+ * Fetch this message.
1078
+ *
1079
+ * @param {boolean} [force=true] Whether to skip the cache check and request the API
1080
+ * @returns {Promise<Message>}
1081
+ */
1082
+ async fetch(force = true) {
1083
+ if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
1084
+ return this.channel.messages.fetch({ message: this.id, force });
1085
+ }
1086
+
1087
+ /**
1088
+ * Fetches the webhook used to create this message.
1089
+ *
1090
+ * @returns {Promise<?Webhook>}
1091
+ */
1092
+ async fetchWebhook() {
1093
+ if (!this.webhookId) throw new DiscordjsError(ErrorCodes.WebhookMessage);
1094
+ if (this.webhookId === this.applicationId) throw new DiscordjsError(ErrorCodes.WebhookApplication);
1095
+ return this.client.fetchWebhook(this.webhookId);
1096
+ }
1097
+
1098
+ /**
1099
+ * Suppresses or unsuppresses embeds on a message.
1100
+ *
1101
+ * @param {boolean} [suppress=true] If the embeds should be suppressed or not
1102
+ * @returns {Promise<Message>}
1103
+ */
1104
+ async suppressEmbeds(suppress = true) {
1105
+ const flags = new MessageFlagsBitField(this.flags.bitfield);
1106
+
1107
+ if (suppress) {
1108
+ flags.add(MessageFlags.SuppressEmbeds);
1109
+ } else {
1110
+ flags.remove(MessageFlags.SuppressEmbeds);
1111
+ }
1112
+
1113
+ return this.edit({ flags });
1114
+ }
1115
+
1116
+ /**
1117
+ * Removes the attachments from this message.
1118
+ *
1119
+ * @returns {Promise<Message>}
1120
+ */
1121
+ async removeAttachments() {
1122
+ return this.edit({ attachments: [] });
1123
+ }
1124
+
1125
+ /**
1126
+ * Resolves a component by a custom id.
1127
+ *
1128
+ * @param {string} customId The custom id to resolve against
1129
+ * @returns {?MessageActionRowComponent}
1130
+ */
1131
+ resolveComponent(customId) {
1132
+ return findComponentByCustomId(this.components, customId);
1133
+ }
1134
+
1135
+ /**
1136
+ * Used mainly internally. Whether two messages are identical in properties. If you want to compare messages
1137
+ * without checking all the properties, use `message.id === message2.id`, which is much more efficient. This
1138
+ * method allows you to see if there are differences in content, embeds, attachments, nonce and tts properties.
1139
+ *
1140
+ * @param {Message} message The message to compare it to
1141
+ * @param {APIMessage} [rawData] Raw data passed through the WebSocket about this message
1142
+ * @returns {boolean}
1143
+ */
1144
+ equals(message, rawData) {
1145
+ if (!message) return false;
1146
+ const embedUpdate = !message.author && !message.attachments;
1147
+ if (embedUpdate) return this.id === message.id && this.embeds.length === message.embeds.length;
1148
+
1149
+ let equal =
1150
+ this.id === message.id &&
1151
+ this.author.id === message.author.id &&
1152
+ this.content === message.content &&
1153
+ this.nonce === message.nonce &&
1154
+ this.tts === message.tts &&
1155
+ this.attachments.size === message.attachments.size &&
1156
+ this.embeds.length === message.embeds.length &&
1157
+ this.attachments.every(attachment => message.attachments.has(attachment.id)) &&
1158
+ this.embeds.every((embed, index) => embed.equals(message.embeds[index]));
1159
+
1160
+ if (equal && rawData) {
1161
+ equal =
1162
+ this.mentions.everyone === message.mentions.everyone &&
1163
+ this.createdTimestamp === Date.parse(rawData.timestamp) &&
1164
+ this.editedTimestamp === Date.parse(rawData.edited_timestamp);
1165
+ }
1166
+
1167
+ return equal;
1168
+ }
1169
+
1170
+ /**
1171
+ * Whether this message is from a guild.
1172
+ *
1173
+ * @returns {boolean}
1174
+ */
1175
+ inGuild() {
1176
+ return Boolean(this.guildId);
1177
+ }
1178
+
1179
+ /**
1180
+ * When concatenated with a string, this automatically concatenates the message's content instead of the object.
1181
+ *
1182
+ * @returns {string}
1183
+ * @example
1184
+ * // Logs: Message: This is a message!
1185
+ * console.log(`Message: ${message}`);
1186
+ */
1187
+ toString() {
1188
+ return this.content;
1189
+ }
1190
+
1191
+ toJSON() {
1192
+ return super.toJSON({
1193
+ channel: 'channelId',
1194
+ author: 'authorId',
1195
+ groupActivityApplication: 'groupActivityApplicationId',
1196
+ guild: 'guildId',
1197
+ cleanContent: true,
1198
+ member: false,
1199
+ reactions: false,
1200
+ });
1201
+ }
1202
+ }