@velliajs/discord 1.0.0

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