discord-sb.js 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.
- package/LICENSE +674 -0
- package/README.md +2 -0
- package/package.json +91 -0
- package/src/WebSocket.js +39 -0
- package/src/client/BaseClient.js +86 -0
- package/src/client/Client.js +978 -0
- package/src/client/WebhookClient.js +61 -0
- package/src/client/actions/Action.js +116 -0
- package/src/client/actions/ActionsManager.js +80 -0
- package/src/client/actions/ApplicationCommandPermissionsUpdate.js +34 -0
- package/src/client/actions/AutoModerationActionExecution.js +27 -0
- package/src/client/actions/AutoModerationRuleCreate.js +28 -0
- package/src/client/actions/AutoModerationRuleDelete.js +32 -0
- package/src/client/actions/AutoModerationRuleUpdate.js +30 -0
- package/src/client/actions/ChannelCreate.js +23 -0
- package/src/client/actions/ChannelDelete.js +39 -0
- package/src/client/actions/ChannelUpdate.js +43 -0
- package/src/client/actions/GuildAuditLogEntryCreate.js +29 -0
- package/src/client/actions/GuildBanAdd.js +20 -0
- package/src/client/actions/GuildBanRemove.js +25 -0
- package/src/client/actions/GuildChannelsPositionUpdate.js +21 -0
- package/src/client/actions/GuildDelete.js +65 -0
- package/src/client/actions/GuildEmojiCreate.js +20 -0
- package/src/client/actions/GuildEmojiDelete.js +21 -0
- package/src/client/actions/GuildEmojiUpdate.js +20 -0
- package/src/client/actions/GuildEmojisUpdate.js +34 -0
- package/src/client/actions/GuildIntegrationsUpdate.js +19 -0
- package/src/client/actions/GuildMemberRemove.js +33 -0
- package/src/client/actions/GuildMemberUpdate.js +44 -0
- package/src/client/actions/GuildRoleCreate.js +25 -0
- package/src/client/actions/GuildRoleDelete.js +31 -0
- package/src/client/actions/GuildRoleUpdate.js +39 -0
- package/src/client/actions/GuildRolesPositionUpdate.js +21 -0
- package/src/client/actions/GuildScheduledEventCreate.js +27 -0
- package/src/client/actions/GuildScheduledEventDelete.js +31 -0
- package/src/client/actions/GuildScheduledEventUpdate.js +30 -0
- package/src/client/actions/GuildScheduledEventUserAdd.js +32 -0
- package/src/client/actions/GuildScheduledEventUserRemove.js +32 -0
- package/src/client/actions/GuildStickerCreate.js +20 -0
- package/src/client/actions/GuildStickerDelete.js +21 -0
- package/src/client/actions/GuildStickerUpdate.js +20 -0
- package/src/client/actions/GuildStickersUpdate.js +34 -0
- package/src/client/actions/GuildUpdate.js +33 -0
- package/src/client/actions/InviteCreate.js +28 -0
- package/src/client/actions/InviteDelete.js +30 -0
- package/src/client/actions/MessageCreate.js +50 -0
- package/src/client/actions/MessageDelete.js +32 -0
- package/src/client/actions/MessageDeleteBulk.js +46 -0
- package/src/client/actions/MessagePollVoteAdd.js +33 -0
- package/src/client/actions/MessagePollVoteRemove.js +33 -0
- package/src/client/actions/MessageReactionAdd.js +68 -0
- package/src/client/actions/MessageReactionRemove.js +50 -0
- package/src/client/actions/MessageReactionRemoveAll.js +33 -0
- package/src/client/actions/MessageReactionRemoveEmoji.js +28 -0
- package/src/client/actions/MessageUpdate.js +26 -0
- package/src/client/actions/PresenceUpdate.js +50 -0
- package/src/client/actions/StageInstanceCreate.js +28 -0
- package/src/client/actions/StageInstanceDelete.js +33 -0
- package/src/client/actions/StageInstanceUpdate.js +30 -0
- package/src/client/actions/ThreadCreate.js +24 -0
- package/src/client/actions/ThreadDelete.js +32 -0
- package/src/client/actions/ThreadListSync.js +59 -0
- package/src/client/actions/ThreadMemberUpdate.js +30 -0
- package/src/client/actions/ThreadMembersUpdate.js +34 -0
- package/src/client/actions/TypingStart.js +29 -0
- package/src/client/actions/UserUpdate.js +35 -0
- package/src/client/actions/VoiceStateUpdate.js +50 -0
- package/src/client/actions/WebhooksUpdate.js +20 -0
- package/src/client/voice/ClientVoiceManager.js +151 -0
- package/src/client/voice/VoiceConnection.js +1249 -0
- package/src/client/voice/dispatcher/AnnexBDispatcher.js +120 -0
- package/src/client/voice/dispatcher/AudioDispatcher.js +145 -0
- package/src/client/voice/dispatcher/BaseDispatcher.js +459 -0
- package/src/client/voice/dispatcher/VPxDispatcher.js +54 -0
- package/src/client/voice/dispatcher/VideoDispatcher.js +68 -0
- package/src/client/voice/networking/VoiceUDPClient.js +173 -0
- package/src/client/voice/networking/VoiceWebSocket.js +286 -0
- package/src/client/voice/player/MediaPlayer.js +321 -0
- package/src/client/voice/player/processing/AnnexBNalSplitter.js +244 -0
- package/src/client/voice/player/processing/IvfSplitter.js +106 -0
- package/src/client/voice/player/processing/PCMInsertSilence.js +37 -0
- package/src/client/voice/receiver/PacketHandler.js +260 -0
- package/src/client/voice/receiver/Receiver.js +96 -0
- package/src/client/voice/receiver/Recorder.js +173 -0
- package/src/client/voice/util/Function.js +116 -0
- package/src/client/voice/util/PlayInterface.js +122 -0
- package/src/client/voice/util/Secretbox.js +64 -0
- package/src/client/voice/util/Silence.js +16 -0
- package/src/client/voice/util/Socket.js +62 -0
- package/src/client/voice/util/VolumeInterface.js +104 -0
- package/src/client/websocket/WebSocketManager.js +392 -0
- package/src/client/websocket/WebSocketShard.js +907 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_CREATE.js +18 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_DELETE.js +20 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_UPDATE.js +20 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js +5 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js +5 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js +5 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/CALL_CREATE.js +14 -0
- package/src/client/websocket/handlers/CALL_DELETE.js +11 -0
- package/src/client/websocket/handlers/CALL_UPDATE.js +11 -0
- package/src/client/websocket/handlers/CHANNEL_CREATE.js +5 -0
- package/src/client/websocket/handlers/CHANNEL_DELETE.js +5 -0
- package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js +22 -0
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +19 -0
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +16 -0
- package/src/client/websocket/handlers/CHANNEL_UPDATE.js +16 -0
- package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_BAN_ADD.js +5 -0
- package/src/client/websocket/handlers/GUILD_BAN_REMOVE.js +5 -0
- package/src/client/websocket/handlers/GUILD_CREATE.js +52 -0
- package/src/client/websocket/handlers/GUILD_DELETE.js +5 -0
- package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js +39 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +20 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js +5 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_ROLE_CREATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_ROLE_DELETE.js +5 -0
- package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js +5 -0
- package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_UPDATE.js +5 -0
- package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +12 -0
- package/src/client/websocket/handlers/INVITE_CREATE.js +5 -0
- package/src/client/websocket/handlers/INVITE_DELETE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_CREATE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_DELETE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_UPDATE.js +16 -0
- package/src/client/websocket/handlers/PRESENCE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/READY.js +121 -0
- package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +19 -0
- package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +17 -0
- package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +41 -0
- package/src/client/websocket/handlers/RESUMED.js +14 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js +5 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js +5 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_CREATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_DELETE.js +5 -0
- package/src/client/websocket/handlers/THREAD_LIST_SYNC.js +5 -0
- package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_UPDATE.js +16 -0
- package/src/client/websocket/handlers/TYPING_START.js +5 -0
- package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +6 -0
- package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
- package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/USER_UPDATE.js +5 -0
- package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +16 -0
- package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
- package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js +6 -0
- package/src/client/websocket/handlers/VOICE_STATE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/WEBHOOKS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/index.js +84 -0
- package/src/errors/DJSError.js +61 -0
- package/src/errors/Messages.js +217 -0
- package/src/errors/index.js +4 -0
- package/src/index.js +172 -0
- package/src/managers/ApplicationCommandManager.js +264 -0
- package/src/managers/ApplicationCommandPermissionsManager.js +417 -0
- package/src/managers/AutoModerationRuleManager.js +296 -0
- package/src/managers/BaseGuildEmojiManager.js +80 -0
- package/src/managers/BaseManager.js +19 -0
- package/src/managers/BillingManager.js +66 -0
- package/src/managers/CachedManager.js +71 -0
- package/src/managers/ChannelManager.js +148 -0
- package/src/managers/ClientUserSettingManager.js +372 -0
- package/src/managers/DataManager.js +61 -0
- package/src/managers/DeveloperManager.js +254 -0
- package/src/managers/GuildBanManager.js +250 -0
- package/src/managers/GuildChannelManager.js +488 -0
- package/src/managers/GuildEmojiManager.js +171 -0
- package/src/managers/GuildEmojiRoleManager.js +118 -0
- package/src/managers/GuildForumThreadManager.js +108 -0
- package/src/managers/GuildInviteManager.js +213 -0
- package/src/managers/GuildManager.js +338 -0
- package/src/managers/GuildMemberManager.js +599 -0
- package/src/managers/GuildMemberRoleManager.js +195 -0
- package/src/managers/GuildScheduledEventManager.js +314 -0
- package/src/managers/GuildSettingManager.js +155 -0
- package/src/managers/GuildStickerManager.js +179 -0
- package/src/managers/GuildTextThreadManager.js +98 -0
- package/src/managers/InteractionManager.js +39 -0
- package/src/managers/MessageManager.js +423 -0
- package/src/managers/PermissionOverwriteManager.js +164 -0
- package/src/managers/PresenceManager.js +71 -0
- package/src/managers/QuestManager.js +353 -0
- package/src/managers/ReactionManager.js +67 -0
- package/src/managers/ReactionUserManager.js +73 -0
- package/src/managers/RelationshipManager.js +278 -0
- package/src/managers/RoleManager.js +448 -0
- package/src/managers/SessionManager.js +66 -0
- package/src/managers/StageInstanceManager.js +162 -0
- package/src/managers/ThreadManager.js +175 -0
- package/src/managers/ThreadMemberManager.js +186 -0
- package/src/managers/UserManager.js +136 -0
- package/src/managers/UserNoteManager.js +53 -0
- package/src/managers/VoiceStateManager.js +59 -0
- package/src/rest/APIRequest.js +154 -0
- package/src/rest/APIRouter.js +53 -0
- package/src/rest/DiscordAPIError.js +119 -0
- package/src/rest/HTTPError.js +62 -0
- package/src/rest/RESTManager.js +67 -0
- package/src/rest/RateLimitError.js +55 -0
- package/src/rest/RequestHandler.js +466 -0
- package/src/sharding/Shard.js +444 -0
- package/src/sharding/ShardClientUtil.js +279 -0
- package/src/sharding/ShardingManager.js +319 -0
- package/src/structures/AnonymousGuild.js +98 -0
- package/src/structures/ApplicationCommand.js +593 -0
- package/src/structures/ApplicationRoleConnectionMetadata.js +48 -0
- package/src/structures/AutoModerationActionExecution.js +89 -0
- package/src/structures/AutoModerationRule.js +294 -0
- package/src/structures/AutocompleteInteraction.js +107 -0
- package/src/structures/Base.js +43 -0
- package/src/structures/BaseCommandInteraction.js +211 -0
- package/src/structures/BaseGuild.js +116 -0
- package/src/structures/BaseGuildEmoji.js +56 -0
- package/src/structures/BaseGuildTextChannel.js +191 -0
- package/src/structures/BaseGuildVoiceChannel.js +241 -0
- package/src/structures/BaseMessageComponent.js +181 -0
- package/src/structures/ButtonInteraction.js +11 -0
- package/src/structures/CallState.js +63 -0
- package/src/structures/CategoryChannel.js +85 -0
- package/src/structures/Channel.js +284 -0
- package/src/structures/ClientPresence.js +77 -0
- package/src/structures/ClientUser.js +655 -0
- package/src/structures/CommandInteraction.js +41 -0
- package/src/structures/CommandInteractionOptionResolver.js +276 -0
- package/src/structures/ContainerComponent.js +68 -0
- package/src/structures/ContextMenuInteraction.js +65 -0
- package/src/structures/DMChannel.js +219 -0
- package/src/structures/DirectoryChannel.js +20 -0
- package/src/structures/Emoji.js +148 -0
- package/src/structures/FileComponent.js +49 -0
- package/src/structures/ForumChannel.js +31 -0
- package/src/structures/GroupDMChannel.js +394 -0
- package/src/structures/Guild.js +1791 -0
- package/src/structures/GuildAuditLogs.js +746 -0
- package/src/structures/GuildBan.js +59 -0
- package/src/structures/GuildBoost.js +108 -0
- package/src/structures/GuildChannel.js +470 -0
- package/src/structures/GuildEmoji.js +161 -0
- package/src/structures/GuildMember.js +636 -0
- package/src/structures/GuildPreview.js +191 -0
- package/src/structures/GuildPreviewEmoji.js +27 -0
- package/src/structures/GuildScheduledEvent.js +536 -0
- package/src/structures/GuildTemplate.js +236 -0
- package/src/structures/Integration.js +188 -0
- package/src/structures/IntegrationApplication.js +96 -0
- package/src/structures/Interaction.js +290 -0
- package/src/structures/InteractionCollector.js +248 -0
- package/src/structures/InteractionWebhook.js +43 -0
- package/src/structures/Invite.js +358 -0
- package/src/structures/InviteGuild.js +23 -0
- package/src/structures/InviteStageInstance.js +86 -0
- package/src/structures/MediaChannel.js +11 -0
- package/src/structures/MediaGalleryComponent.js +41 -0
- package/src/structures/MediaGalleryItem.js +47 -0
- package/src/structures/Message.js +1252 -0
- package/src/structures/MessageActionRow.js +105 -0
- package/src/structures/MessageAttachment.js +216 -0
- package/src/structures/MessageButton.js +166 -0
- package/src/structures/MessageCollector.js +146 -0
- package/src/structures/MessageComponentInteraction.js +120 -0
- package/src/structures/MessageContextMenuInteraction.js +20 -0
- package/src/structures/MessageEmbed.js +596 -0
- package/src/structures/MessageMentions.js +273 -0
- package/src/structures/MessagePayload.js +354 -0
- package/src/structures/MessageReaction.js +181 -0
- package/src/structures/MessageSelectMenu.js +141 -0
- package/src/structures/Modal.js +161 -0
- package/src/structures/ModalSubmitFieldsResolver.js +53 -0
- package/src/structures/ModalSubmitInteraction.js +119 -0
- package/src/structures/NewsChannel.js +32 -0
- package/src/structures/OAuth2Guild.js +28 -0
- package/src/structures/PermissionOverwrites.js +198 -0
- package/src/structures/Poll.js +108 -0
- package/src/structures/PollAnswer.js +88 -0
- package/src/structures/Presence.js +1157 -0
- package/src/structures/ReactionCollector.js +229 -0
- package/src/structures/ReactionEmoji.js +31 -0
- package/src/structures/Role.js +590 -0
- package/src/structures/SectionComponent.js +48 -0
- package/src/structures/SelectMenuInteraction.js +21 -0
- package/src/structures/SeparatorComponent.js +48 -0
- package/src/structures/Session.js +81 -0
- package/src/structures/StageChannel.js +104 -0
- package/src/structures/StageInstance.js +208 -0
- package/src/structures/Sticker.js +310 -0
- package/src/structures/StickerPack.js +95 -0
- package/src/structures/StoreChannel.js +56 -0
- package/src/structures/Team.js +118 -0
- package/src/structures/TeamMember.js +80 -0
- package/src/structures/TextChannel.js +33 -0
- package/src/structures/TextDisplayComponent.js +40 -0
- package/src/structures/TextInputComponent.js +132 -0
- package/src/structures/ThreadChannel.js +605 -0
- package/src/structures/ThreadMember.js +105 -0
- package/src/structures/ThreadOnlyChannel.js +249 -0
- package/src/structures/ThumbnailComponent.js +57 -0
- package/src/structures/Typing.js +74 -0
- package/src/structures/UnfurledMediaItem.js +29 -0
- package/src/structures/User.js +640 -0
- package/src/structures/UserContextMenuInteraction.js +29 -0
- package/src/structures/VoiceChannel.js +110 -0
- package/src/structures/VoiceChannelEffect.js +69 -0
- package/src/structures/VoiceRegion.js +53 -0
- package/src/structures/VoiceState.js +354 -0
- package/src/structures/WebEmbed.js +373 -0
- package/src/structures/Webhook.js +478 -0
- package/src/structures/WelcomeChannel.js +60 -0
- package/src/structures/WelcomeScreen.js +48 -0
- package/src/structures/Widget.js +87 -0
- package/src/structures/WidgetMember.js +99 -0
- package/src/structures/interfaces/Application.js +953 -0
- package/src/structures/interfaces/Collector.js +300 -0
- package/src/structures/interfaces/InteractionResponses.js +313 -0
- package/src/structures/interfaces/TextBasedChannel.js +821 -0
- package/src/util/APITypes.js +59 -0
- package/src/util/ActivityFlags.js +44 -0
- package/src/util/ApplicationFlags.js +76 -0
- package/src/util/AttachmentFlags.js +38 -0
- package/src/util/BitField.js +170 -0
- package/src/util/ChannelFlags.js +45 -0
- package/src/util/Constants.js +1914 -0
- package/src/util/DataResolver.js +146 -0
- package/src/util/Formatters.js +228 -0
- package/src/util/GuildMemberFlags.js +43 -0
- package/src/util/Intents.js +74 -0
- package/src/util/InviteFlags.js +34 -0
- package/src/util/LimitedCollection.js +131 -0
- package/src/util/MessageFlags.js +63 -0
- package/src/util/Options.js +358 -0
- package/src/util/Permissions.js +202 -0
- package/src/util/PremiumUsageFlags.js +31 -0
- package/src/util/PurchasedFlags.js +33 -0
- package/src/util/RemoteAuth.js +415 -0
- package/src/util/RoleFlags.js +37 -0
- package/src/util/SnowflakeUtil.js +92 -0
- package/src/util/Speaking.js +33 -0
- package/src/util/Sweepers.js +466 -0
- package/src/util/SystemChannelFlags.js +55 -0
- package/src/util/ThreadMemberFlags.js +30 -0
- package/src/util/UserFlags.js +104 -0
- package/src/util/Util.js +1048 -0
- package/typings/enums.d.ts +439 -0
- package/typings/index.d.ts +8505 -0
- package/typings/index.test-d.ts +0 -0
- package/typings/rawDataTypes.d.ts +403 -0
|
@@ -0,0 +1,1157 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { randomUUID } = require('node:crypto');
|
|
4
|
+
const Base = require('./Base');
|
|
5
|
+
const ActivityFlags = require('../util/ActivityFlags');
|
|
6
|
+
const { ActivityTypes } = require('../util/Constants');
|
|
7
|
+
const Util = require('../util/Util');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Activity sent in a message.
|
|
11
|
+
* @typedef {Object} MessageActivity
|
|
12
|
+
* @property {string} [partyId] Id of the party represented in activity
|
|
13
|
+
* @property {MessageActivityType} type Type of activity sent
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The status of this presence:
|
|
18
|
+
* * **`online`** - user is online
|
|
19
|
+
* * **`idle`** - user is AFK
|
|
20
|
+
* * **`offline`** - user is offline or invisible
|
|
21
|
+
* * **`dnd`** - user is in Do Not Disturb
|
|
22
|
+
* @typedef {string} PresenceStatus
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The status of this presence:
|
|
27
|
+
* * **`online`** - user is online
|
|
28
|
+
* * **`idle`** - user is AFK
|
|
29
|
+
* * **`dnd`** - user is in Do Not Disturb
|
|
30
|
+
* @typedef {string} ClientPresenceStatus
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Represents a user's presence.
|
|
35
|
+
* @extends {Base}
|
|
36
|
+
*/
|
|
37
|
+
class Presence extends Base {
|
|
38
|
+
constructor(client, data = {}) {
|
|
39
|
+
super(client);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The presence's user id
|
|
43
|
+
* @type {Snowflake}
|
|
44
|
+
*/
|
|
45
|
+
this.userId = data.user.id;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The guild this presence is in
|
|
49
|
+
* @type {?Guild}
|
|
50
|
+
*/
|
|
51
|
+
this.guild = data.guild ?? null;
|
|
52
|
+
|
|
53
|
+
this._patch(data);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The user of this presence
|
|
58
|
+
* @type {?User}
|
|
59
|
+
* @readonly
|
|
60
|
+
*/
|
|
61
|
+
get user() {
|
|
62
|
+
return this.client.users.resolve(this.userId);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The member of this presence
|
|
67
|
+
* @type {?GuildMember}
|
|
68
|
+
* @readonly
|
|
69
|
+
*/
|
|
70
|
+
get member() {
|
|
71
|
+
return this.guild.members.resolve(this.userId);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_patch(data) {
|
|
75
|
+
if ('status' in data) {
|
|
76
|
+
/**
|
|
77
|
+
* The status of this presence
|
|
78
|
+
* @type {PresenceStatus}
|
|
79
|
+
*/
|
|
80
|
+
this.status = data.status;
|
|
81
|
+
} else {
|
|
82
|
+
this.status ??= 'offline';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if ('activities' in data) {
|
|
86
|
+
/**
|
|
87
|
+
* The activities of this presence (Always `Activity[]` if not ClientUser)
|
|
88
|
+
* @type {CustomStatus[]|RichPresence[]|SpotifyRPC[]|Activity[]}
|
|
89
|
+
*/
|
|
90
|
+
this.activities = data.activities.map(activity => {
|
|
91
|
+
if (this.userId == this.client.user.id) {
|
|
92
|
+
if ([ActivityTypes.CUSTOM, 'CUSTOM'].includes(activity.type)) {
|
|
93
|
+
return new CustomStatus(this.client, activity);
|
|
94
|
+
} else if (activity.id == 'spotify:1') {
|
|
95
|
+
return new SpotifyRPC(this.client, activity);
|
|
96
|
+
} else {
|
|
97
|
+
return new RichPresence(this.client, activity);
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
return new Activity(this, activity);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
this.activities ??= [];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if ('client_status' in data) {
|
|
108
|
+
/**
|
|
109
|
+
* The devices this presence is on
|
|
110
|
+
* @type {?Object}
|
|
111
|
+
* @property {?ClientPresenceStatus} web The current presence in the web application
|
|
112
|
+
* @property {?ClientPresenceStatus} mobile The current presence in the mobile application
|
|
113
|
+
* @property {?ClientPresenceStatus} desktop The current presence in the desktop application
|
|
114
|
+
*/
|
|
115
|
+
this.clientStatus = data.client_status;
|
|
116
|
+
} else {
|
|
117
|
+
this.clientStatus ??= null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if ('last_modified' in data) {
|
|
121
|
+
/**
|
|
122
|
+
* The timestamp this presence was last updated
|
|
123
|
+
* @type {number}
|
|
124
|
+
*/
|
|
125
|
+
this.lastModified = data.last_modified;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if ('afk' in data) {
|
|
129
|
+
this.afk = data.afk;
|
|
130
|
+
} else {
|
|
131
|
+
this.afk ??= false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if ('since' in data) {
|
|
135
|
+
this.since = data.since;
|
|
136
|
+
} else {
|
|
137
|
+
this.since ??= 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
_clone() {
|
|
144
|
+
const clone = Object.assign(Object.create(this), this);
|
|
145
|
+
clone.activities = this.activities.map(activity => activity._clone());
|
|
146
|
+
return clone;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Whether this presence is equal to another.
|
|
151
|
+
* @param {Presence} presence The presence to compare with
|
|
152
|
+
* @returns {boolean}
|
|
153
|
+
*/
|
|
154
|
+
equals(presence) {
|
|
155
|
+
return (
|
|
156
|
+
this === presence ||
|
|
157
|
+
(presence &&
|
|
158
|
+
this.status === presence.status &&
|
|
159
|
+
this.clientStatus?.web === presence.clientStatus?.web &&
|
|
160
|
+
this.clientStatus?.mobile === presence.clientStatus?.mobile &&
|
|
161
|
+
this.clientStatus?.desktop === presence.clientStatus?.desktop &&
|
|
162
|
+
this.activities.length === presence.activities.length &&
|
|
163
|
+
this.activities.every((activity, index) => activity.equals(presence.activities[index])))
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
toJSON() {
|
|
168
|
+
return Util.flatten(this);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* The platform of this activity:
|
|
174
|
+
* * **`desktop`**
|
|
175
|
+
* * **`samsung`** - playing on Samsung Galaxy
|
|
176
|
+
* * **`xbox`** - playing on Xbox Live
|
|
177
|
+
* * **`ios`**
|
|
178
|
+
* * **`android`**
|
|
179
|
+
* * **`embedded`**
|
|
180
|
+
* * **`ps4`**
|
|
181
|
+
* * **`ps5`**
|
|
182
|
+
* @typedef {string} ActivityPlatform
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Represents an activity that is part of a user's presence.
|
|
187
|
+
*/
|
|
188
|
+
class Activity {
|
|
189
|
+
constructor(presence, data) {
|
|
190
|
+
if (!(presence instanceof Presence)) {
|
|
191
|
+
throw new Error("Class constructor Activity cannot be invoked without 'presence'");
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The presence of the Activity
|
|
195
|
+
* @type {Presence}
|
|
196
|
+
* @readonly
|
|
197
|
+
* @name Activity#presence
|
|
198
|
+
*/
|
|
199
|
+
Object.defineProperty(this, 'presence', { value: presence });
|
|
200
|
+
|
|
201
|
+
this._patch(data);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
_patch(data = {}) {
|
|
205
|
+
if ('id' in data) {
|
|
206
|
+
/**
|
|
207
|
+
* The activity's id
|
|
208
|
+
* @type {string}
|
|
209
|
+
*/
|
|
210
|
+
this.id = data.id;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if ('name' in data) {
|
|
214
|
+
/**
|
|
215
|
+
* The activity's name
|
|
216
|
+
* @type {string}
|
|
217
|
+
*/
|
|
218
|
+
this.name = data.name;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if ('type' in data) {
|
|
222
|
+
/**
|
|
223
|
+
* The activity status's type
|
|
224
|
+
* @type {ActivityType}
|
|
225
|
+
*/
|
|
226
|
+
this.type = typeof data.type === 'number' ? ActivityTypes[data.type] : data.type;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if ('url' in data) {
|
|
230
|
+
/**
|
|
231
|
+
* If the activity is being streamed, a link to the stream
|
|
232
|
+
* @type {?string}
|
|
233
|
+
*/
|
|
234
|
+
this.url = data.url;
|
|
235
|
+
} else {
|
|
236
|
+
this.url = null;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if ('created_at' in data || 'createdTimestamp' in data) {
|
|
240
|
+
/**
|
|
241
|
+
* Creation date of the activity
|
|
242
|
+
* @type {number}
|
|
243
|
+
*/
|
|
244
|
+
this.createdTimestamp = data.created_at || data.createdTimestamp;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if ('session_id' in data) {
|
|
248
|
+
/**
|
|
249
|
+
* The game's or Spotify session's id
|
|
250
|
+
* @type {?string}
|
|
251
|
+
*/
|
|
252
|
+
this.sessionId = data.session_id;
|
|
253
|
+
} else {
|
|
254
|
+
this.sessionId = this.presence.client?.sessionId;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if ('platform' in data) {
|
|
258
|
+
/**
|
|
259
|
+
* The platform the game is being played on
|
|
260
|
+
* @type {?ActivityPlatform}
|
|
261
|
+
*/
|
|
262
|
+
this.platform = data.platform;
|
|
263
|
+
} else {
|
|
264
|
+
this.platform = null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if ('timestamps' in data && data.timestamps) {
|
|
268
|
+
/**
|
|
269
|
+
* Represents timestamps of an activity
|
|
270
|
+
* @typedef {Object} ActivityTimestamps
|
|
271
|
+
* @property {?number} start When the activity started
|
|
272
|
+
* @property {?number} end When the activity will end
|
|
273
|
+
*/
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Timestamps for the activity
|
|
277
|
+
* @type {?ActivityTimestamps}
|
|
278
|
+
*/
|
|
279
|
+
this.timestamps = {
|
|
280
|
+
start: data.timestamps.start ? new Date(data.timestamps.start).getTime() : null,
|
|
281
|
+
end: data.timestamps.end ? new Date(data.timestamps.end).getTime() : null,
|
|
282
|
+
};
|
|
283
|
+
} else {
|
|
284
|
+
this.timestamps = null;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if ('application_id' in data || 'applicationId' in data) {
|
|
288
|
+
/**
|
|
289
|
+
* The id of the application associated with this activity
|
|
290
|
+
* @type {?Snowflake}
|
|
291
|
+
*/
|
|
292
|
+
this.applicationId = data.application_id || data.applicationId;
|
|
293
|
+
} else {
|
|
294
|
+
this.applicationId = null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if ('details' in data) {
|
|
298
|
+
/**
|
|
299
|
+
* Details about the activity
|
|
300
|
+
* @type {?string}
|
|
301
|
+
*/
|
|
302
|
+
this.details = data.details;
|
|
303
|
+
} else {
|
|
304
|
+
this.details = null;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if ('details_url' in data) {
|
|
308
|
+
/**
|
|
309
|
+
* URL for the details of the activity
|
|
310
|
+
* @type {?string}
|
|
311
|
+
*/
|
|
312
|
+
this.details_url = data.details_url;
|
|
313
|
+
} else {
|
|
314
|
+
this.details_url = null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if ('state' in data) {
|
|
318
|
+
/**
|
|
319
|
+
* State of the activity
|
|
320
|
+
* @type {?string}
|
|
321
|
+
*/
|
|
322
|
+
this.state = data.state;
|
|
323
|
+
} else {
|
|
324
|
+
this.state = null;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if ('state_url' in data) {
|
|
328
|
+
/**
|
|
329
|
+
* URL for the state of the activity
|
|
330
|
+
* @type {?string}
|
|
331
|
+
*/
|
|
332
|
+
this.state_url = data.state_url;
|
|
333
|
+
} else {
|
|
334
|
+
this.state_url = null;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if ('sync_id' in data || 'syncId' in data) {
|
|
338
|
+
/**
|
|
339
|
+
* The sync id of the activity
|
|
340
|
+
* <info>This property is not documented by Discord and represents the track id in spotify activities.</info>
|
|
341
|
+
* @type {?string}
|
|
342
|
+
*/
|
|
343
|
+
this.syncId = data.sync_id || data.syncId;
|
|
344
|
+
} else {
|
|
345
|
+
this.syncId = null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if ('flags' in data) {
|
|
349
|
+
/**
|
|
350
|
+
* Flags that describe the activity
|
|
351
|
+
* @type {Readonly<ActivityFlags>}
|
|
352
|
+
*/
|
|
353
|
+
this.flags = new ActivityFlags(data.flags).freeze();
|
|
354
|
+
} else {
|
|
355
|
+
this.flags = new ActivityFlags().freeze();
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if ('buttons' in data) {
|
|
359
|
+
/**
|
|
360
|
+
* The labels of the buttons of this rich presence
|
|
361
|
+
* @type {string[]}
|
|
362
|
+
*/
|
|
363
|
+
this.buttons = data.buttons;
|
|
364
|
+
} else {
|
|
365
|
+
this.buttons = [];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if ('emoji' in data && data.emoji) {
|
|
369
|
+
/**
|
|
370
|
+
* Emoji for a custom activity
|
|
371
|
+
* @type {?EmojiIdentifierResolvable}
|
|
372
|
+
*/
|
|
373
|
+
this.emoji = Util.resolvePartialEmoji(data.emoji);
|
|
374
|
+
} else {
|
|
375
|
+
this.emoji = null;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if ('party' in data) {
|
|
379
|
+
/**
|
|
380
|
+
* Represents a party of an activity
|
|
381
|
+
* @typedef {Object} ActivityParty
|
|
382
|
+
* @property {?string} id The party's id
|
|
383
|
+
* @property {number[]} size Size of the party as `[current, max]`
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Party of the activity
|
|
388
|
+
* @type {?ActivityParty}
|
|
389
|
+
*/
|
|
390
|
+
this.party = data.party;
|
|
391
|
+
} else {
|
|
392
|
+
this.party = null;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Assets for rich presence
|
|
397
|
+
* @type {?RichPresenceAssets}
|
|
398
|
+
*/
|
|
399
|
+
this.assets = new RichPresenceAssets(this, data.assets);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Whether this activity is equal to another activity.
|
|
404
|
+
* @param {Activity} activity The activity to compare with
|
|
405
|
+
* @returns {boolean}
|
|
406
|
+
*/
|
|
407
|
+
equals(activity) {
|
|
408
|
+
return (
|
|
409
|
+
this === activity ||
|
|
410
|
+
(activity &&
|
|
411
|
+
this.name === activity.name &&
|
|
412
|
+
this.type === activity.type &&
|
|
413
|
+
this.url === activity.url &&
|
|
414
|
+
this.state === activity.state &&
|
|
415
|
+
this.state_url === activity.state_url &&
|
|
416
|
+
this.details === activity.details &&
|
|
417
|
+
this.details_url == activity.details_url &&
|
|
418
|
+
this.emoji?.id === activity.emoji?.id &&
|
|
419
|
+
this.emoji?.name === activity.emoji?.name)
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* The time the activity was created at
|
|
425
|
+
* @type {Date}
|
|
426
|
+
* @readonly
|
|
427
|
+
*/
|
|
428
|
+
get createdAt() {
|
|
429
|
+
return new Date(this.createdTimestamp);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* When concatenated with a string, this automatically returns the activities' name instead of the Activity object.
|
|
434
|
+
* @returns {string}
|
|
435
|
+
*/
|
|
436
|
+
toString() {
|
|
437
|
+
return this.name;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
_clone() {
|
|
441
|
+
return Object.assign(Object.create(this), this);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
toJSON(...props) {
|
|
445
|
+
return Util.clearNullOrUndefinedObject({
|
|
446
|
+
...Util.flatten(this, ...props),
|
|
447
|
+
type: typeof this.type === 'number' ? this.type : ActivityTypes[this.type],
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Assets for a rich presence
|
|
454
|
+
*/
|
|
455
|
+
class RichPresenceAssets {
|
|
456
|
+
constructor(activity, assets) {
|
|
457
|
+
/**
|
|
458
|
+
* The activity of the RichPresenceAssets
|
|
459
|
+
* @type {Activity}
|
|
460
|
+
* @readonly
|
|
461
|
+
* @name RichPresenceAssets#activity
|
|
462
|
+
*/
|
|
463
|
+
Object.defineProperty(this, 'activity', { value: activity });
|
|
464
|
+
|
|
465
|
+
this._patch(assets);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
_patch(assets = {}) {
|
|
469
|
+
if ('large_text' in assets || 'largeText' in assets) {
|
|
470
|
+
/**
|
|
471
|
+
* Hover text for the large image
|
|
472
|
+
* @type {?string}
|
|
473
|
+
*/
|
|
474
|
+
this.largeText = assets.large_text || assets.largeText;
|
|
475
|
+
} else {
|
|
476
|
+
this.largeText = null;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if ('small_text' in assets || 'smallText' in assets) {
|
|
480
|
+
/**
|
|
481
|
+
* Hover text for the small image
|
|
482
|
+
* @type {?string}
|
|
483
|
+
*/
|
|
484
|
+
this.smallText = assets.small_text || assets.smallText;
|
|
485
|
+
} else {
|
|
486
|
+
this.smallText = null;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if ('large_image' in assets || 'largeImage' in assets) {
|
|
490
|
+
/**
|
|
491
|
+
* The large image asset's id
|
|
492
|
+
* @type {?Snowflake}
|
|
493
|
+
*/
|
|
494
|
+
this.largeImage = assets.large_image || assets.largeImage;
|
|
495
|
+
} else {
|
|
496
|
+
this.largeImage = null;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
if ('small_image' in assets || 'smallImage' in assets) {
|
|
500
|
+
/**
|
|
501
|
+
* The small image asset's id
|
|
502
|
+
* @type {?Snowflake}
|
|
503
|
+
*/
|
|
504
|
+
this.smallImage = assets.small_image || assets.smallImage;
|
|
505
|
+
} else {
|
|
506
|
+
this.smallImage = null;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Gets the URL of the small image asset
|
|
512
|
+
* @param {StaticImageURLOptions} [options] Options for the image URL
|
|
513
|
+
* @returns {?string}
|
|
514
|
+
*/
|
|
515
|
+
smallImageURL({ format, size } = {}) {
|
|
516
|
+
if (!this.smallImage) return null;
|
|
517
|
+
if (this.smallImage.includes(':')) {
|
|
518
|
+
const [platform, id] = this.smallImage.split(':');
|
|
519
|
+
switch (platform) {
|
|
520
|
+
case 'mp':
|
|
521
|
+
return `https://media.discordapp.net/${id}`;
|
|
522
|
+
case 'spotify':
|
|
523
|
+
return `https://i.scdn.co/image/${id}`;
|
|
524
|
+
case 'youtube':
|
|
525
|
+
return `https://i.ytimg.com/vi/${id}/hqdefault_live.jpg`;
|
|
526
|
+
case 'twitch':
|
|
527
|
+
return `https://static-cdn.jtvnw.net/previews-ttv/live_user_${id}.png`;
|
|
528
|
+
default:
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return this.activity.presence.client.rest.cdn.AppAsset(this.activity.applicationId, this.smallImage, {
|
|
534
|
+
format,
|
|
535
|
+
size,
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Gets the URL of the large image asset
|
|
541
|
+
* @param {StaticImageURLOptions} [options] Options for the image URL
|
|
542
|
+
* @returns {?string}
|
|
543
|
+
*/
|
|
544
|
+
largeImageURL({ format, size } = {}) {
|
|
545
|
+
if (!this.largeImage) return null;
|
|
546
|
+
if (this.largeImage.includes(':')) {
|
|
547
|
+
const [platform, id] = this.largeImage.split(':');
|
|
548
|
+
switch (platform) {
|
|
549
|
+
case 'mp':
|
|
550
|
+
return `https://media.discordapp.net/${id}`;
|
|
551
|
+
case 'spotify':
|
|
552
|
+
return `https://i.scdn.co/image/${id}`;
|
|
553
|
+
case 'youtube':
|
|
554
|
+
return `https://i.ytimg.com/vi/${id}/hqdefault_live.jpg`;
|
|
555
|
+
case 'twitch':
|
|
556
|
+
return `https://static-cdn.jtvnw.net/previews-ttv/live_user_${id}.png`;
|
|
557
|
+
default:
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
return this.activity.presence.client.rest.cdn.AppAsset(this.activity.applicationId, this.largeImage, {
|
|
563
|
+
format,
|
|
564
|
+
size,
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
static parseImage(image) {
|
|
569
|
+
if (typeof image != 'string') {
|
|
570
|
+
image = null;
|
|
571
|
+
} else if (URL.canParse(image) && ['http:', 'https:'].includes(new URL(image).protocol)) {
|
|
572
|
+
// Discord URL:
|
|
573
|
+
image = image
|
|
574
|
+
.replace('https://cdn.discordapp.com/', 'mp:')
|
|
575
|
+
.replace('http://cdn.discordapp.com/', 'mp:')
|
|
576
|
+
.replace('https://media.discordapp.net/', 'mp:')
|
|
577
|
+
.replace('http://media.discordapp.net/', 'mp:');
|
|
578
|
+
//
|
|
579
|
+
if (!image.startsWith('mp:')) {
|
|
580
|
+
throw new Error('INVALID_URL');
|
|
581
|
+
}
|
|
582
|
+
} else if (/^[0-9]{17,19}$/.test(image)) {
|
|
583
|
+
// ID Assets
|
|
584
|
+
} else if (['mp:', 'youtube:', 'spotify:', 'twitch:'].some(v => image.startsWith(v))) {
|
|
585
|
+
// Image
|
|
586
|
+
} else if (image.startsWith('external/')) {
|
|
587
|
+
image = `mp:${image}`;
|
|
588
|
+
}
|
|
589
|
+
return image;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
toJSON() {
|
|
593
|
+
if (!this.largeImage && !this.largeText && !this.smallImage && !this.smallText) return null;
|
|
594
|
+
return {
|
|
595
|
+
large_image: RichPresenceAssets.parseImage(this.largeImage),
|
|
596
|
+
large_text: this.largeText,
|
|
597
|
+
small_image: RichPresenceAssets.parseImage(this.smallImage),
|
|
598
|
+
small_text: this.smallText,
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* @typedef {string} RichPresenceImage
|
|
604
|
+
* Support:
|
|
605
|
+
* - cdn.discordapp.com
|
|
606
|
+
* - media.discordapp.net
|
|
607
|
+
* - Assets ID (https://discord.com/api/v9/oauth2/applications/{application_id}/assets)
|
|
608
|
+
* - Media Proxy (mp:external/{hash})
|
|
609
|
+
* - Twitch (twitch:{username})
|
|
610
|
+
* - YouTube (youtube:{video_id})
|
|
611
|
+
* - Spotify (spotify:{image_id})
|
|
612
|
+
*/
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Set the large image of this activity
|
|
616
|
+
* @param {?RichPresenceImage} image The large image asset's id
|
|
617
|
+
* @returns {RichPresenceAssets}
|
|
618
|
+
*/
|
|
619
|
+
setLargeImage(image) {
|
|
620
|
+
image = RichPresenceAssets.parseImage(image);
|
|
621
|
+
this.largeImage = image;
|
|
622
|
+
return this;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Set the small image of this activity
|
|
627
|
+
* @param {?RichPresenceImage} image The small image asset's id
|
|
628
|
+
* @returns {RichPresenceAssets}
|
|
629
|
+
*/
|
|
630
|
+
setSmallImage(image) {
|
|
631
|
+
image = RichPresenceAssets.parseImage(image);
|
|
632
|
+
this.smallImage = image;
|
|
633
|
+
return this;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Hover text for the large image
|
|
638
|
+
* @param {string} text Assets text
|
|
639
|
+
* @returns {RichPresenceAssets}
|
|
640
|
+
*/
|
|
641
|
+
setLargeText(text) {
|
|
642
|
+
this.largeText = text;
|
|
643
|
+
return this;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Hover text for the small image
|
|
648
|
+
* @param {string} text Assets text
|
|
649
|
+
* @returns {RichPresenceAssets}
|
|
650
|
+
*/
|
|
651
|
+
setSmallText(text) {
|
|
652
|
+
this.smallText = text;
|
|
653
|
+
return this;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
class CustomStatus extends Activity {
|
|
658
|
+
/**
|
|
659
|
+
* @typedef {Object} CustomStatusOptions
|
|
660
|
+
* @property {string} [state] The state to be displayed
|
|
661
|
+
* @property {EmojiIdentifierResolvable} [emoji] The emoji to be displayed
|
|
662
|
+
*/
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* @param {Client} client Discord Client
|
|
666
|
+
* @param {CustomStatus|CustomStatusOptions} [data={}] CustomStatus to clone or raw data
|
|
667
|
+
*/
|
|
668
|
+
constructor(client, data = {}) {
|
|
669
|
+
if (!client) throw new Error("Class constructor CustomStatus cannot be invoked without 'client'");
|
|
670
|
+
super('presence' in client ? client.presence : client, {
|
|
671
|
+
name: ' ',
|
|
672
|
+
type: ActivityTypes.CUSTOM,
|
|
673
|
+
...data,
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Set the emoji of this activity
|
|
679
|
+
* @param {EmojiIdentifierResolvable} emoji The emoji to be displayed
|
|
680
|
+
* @returns {CustomStatus}
|
|
681
|
+
*/
|
|
682
|
+
setEmoji(emoji) {
|
|
683
|
+
this.emoji = Util.resolvePartialEmoji(emoji);
|
|
684
|
+
return this;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Set state of this activity
|
|
689
|
+
* @param {string | null} state The state to be displayed
|
|
690
|
+
* @returns {CustomStatus}
|
|
691
|
+
*/
|
|
692
|
+
setState(state) {
|
|
693
|
+
if (typeof state == 'string' && state.length > 128) throw new Error('State must be less than 128 characters');
|
|
694
|
+
this.state = state;
|
|
695
|
+
return this;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Returns an object that can be used to set the status
|
|
700
|
+
* @returns {CustomStatus}
|
|
701
|
+
*/
|
|
702
|
+
toJSON() {
|
|
703
|
+
if (!this.emoji & !this.state) throw new Error('CustomStatus must have at least one of emoji or state');
|
|
704
|
+
return {
|
|
705
|
+
name: this.name,
|
|
706
|
+
emoji: this.emoji,
|
|
707
|
+
type: ActivityTypes.CUSTOM,
|
|
708
|
+
state: this.state,
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
class RichPresence extends Activity {
|
|
714
|
+
/**
|
|
715
|
+
* @param {Client} client Discord client
|
|
716
|
+
* @param {RichPresence} [data={}] RichPresence to clone or raw data
|
|
717
|
+
*/
|
|
718
|
+
constructor(client, data = {}) {
|
|
719
|
+
if (!client) throw new Error("Class constructor RichPresence cannot be invoked without 'client'");
|
|
720
|
+
super('presence' in client ? client.presence : client, { type: 0, ...data });
|
|
721
|
+
this.setup(data);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Sets the status from a JSON object
|
|
726
|
+
* @param {RichPresence} data data
|
|
727
|
+
* @private
|
|
728
|
+
*/
|
|
729
|
+
setup(data = {}) {
|
|
730
|
+
this.secrets = 'secrets' in data ? data.secrets : {};
|
|
731
|
+
this.metadata = 'metadata' in data ? data.metadata : {};
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* Set the large image of this activity
|
|
736
|
+
* @param {?RichPresenceImage} image The large image asset's id
|
|
737
|
+
* @returns {RichPresence}
|
|
738
|
+
*/
|
|
739
|
+
setAssetsLargeImage(image) {
|
|
740
|
+
this.assets.setLargeImage(image);
|
|
741
|
+
return this;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Set the small image of this activity
|
|
746
|
+
* @param {?RichPresenceImage} image The small image asset's id
|
|
747
|
+
* @returns {RichPresence}
|
|
748
|
+
*/
|
|
749
|
+
setAssetsSmallImage(image) {
|
|
750
|
+
this.assets.setSmallImage(image);
|
|
751
|
+
return this;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Hover text for the large image
|
|
756
|
+
* @param {string} text Assets text
|
|
757
|
+
* @returns {RichPresence}
|
|
758
|
+
*/
|
|
759
|
+
setAssetsLargeText(text) {
|
|
760
|
+
this.assets.setLargeText(text);
|
|
761
|
+
return this;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Hover text for the small image
|
|
766
|
+
* @param {string} text Assets text
|
|
767
|
+
* @returns {RichPresence}
|
|
768
|
+
*/
|
|
769
|
+
setAssetsSmallText(text) {
|
|
770
|
+
this.assets.setSmallText(text);
|
|
771
|
+
return this;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* Set the name of the activity
|
|
776
|
+
* @param {?string} name The activity's name
|
|
777
|
+
* @returns {RichPresence}
|
|
778
|
+
*/
|
|
779
|
+
setName(name) {
|
|
780
|
+
this.name = name;
|
|
781
|
+
return this;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* If the activity is being streamed, a link to the stream
|
|
786
|
+
* @param {?string} url URL of the stream
|
|
787
|
+
* @returns {RichPresence}
|
|
788
|
+
*/
|
|
789
|
+
setURL(url) {
|
|
790
|
+
if (typeof url == 'string' && !URL.canParse(url)) throw new Error('URL must be a valid URL');
|
|
791
|
+
this.url = url;
|
|
792
|
+
return this;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* The activity status's type
|
|
797
|
+
* @param {?ActivityTypes} type The type of activity
|
|
798
|
+
* @returns {RichPresence}
|
|
799
|
+
*/
|
|
800
|
+
setType(type) {
|
|
801
|
+
this.type = typeof type == 'number' ? type : ActivityTypes[type];
|
|
802
|
+
return this;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Set the application id of this activity
|
|
807
|
+
* @param {?Snowflake} id Bot's id
|
|
808
|
+
* @returns {RichPresence}
|
|
809
|
+
*/
|
|
810
|
+
setApplicationId(id) {
|
|
811
|
+
this.applicationId = id;
|
|
812
|
+
return this;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Set the state of the activity
|
|
817
|
+
* @param {?string} state The state of the activity
|
|
818
|
+
* @returns {RichPresence}
|
|
819
|
+
*/
|
|
820
|
+
setState(state) {
|
|
821
|
+
this.state = state;
|
|
822
|
+
return this;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Set the URL of the state of the activity
|
|
827
|
+
* @param {?string} url The url of the state
|
|
828
|
+
* @returns {RichPresence}
|
|
829
|
+
*/
|
|
830
|
+
setStateURL(url) {
|
|
831
|
+
if (!url) throw new Error('Detail URL must be a url');
|
|
832
|
+
|
|
833
|
+
if (typeof url !== 'string') throw new Error('Detail URL must be a url');
|
|
834
|
+
if (!URL.canParse(url)) throw new Error('Detail URL must be a valid url');
|
|
835
|
+
|
|
836
|
+
this.state_url = url;
|
|
837
|
+
return this;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Set the details of the activity
|
|
842
|
+
* @param {?string} details The details of the activity
|
|
843
|
+
* @returns {RichPresence}
|
|
844
|
+
*/
|
|
845
|
+
setDetails(details) {
|
|
846
|
+
this.details = details;
|
|
847
|
+
return this;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Set the URL of the details of the activity
|
|
852
|
+
* @param {?string} url The url of the details
|
|
853
|
+
* @returns {RichPresence}
|
|
854
|
+
*/
|
|
855
|
+
setDetailsURL(url) {
|
|
856
|
+
if (!url) throw new Error('Detail URL must be a url');
|
|
857
|
+
|
|
858
|
+
if (typeof url !== 'string') throw new Error('Detail URL must be a url');
|
|
859
|
+
if (!URL.canParse(url)) throw new Error('Detail URL must be a valid url');
|
|
860
|
+
|
|
861
|
+
this.details_url = url;
|
|
862
|
+
return this;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* @typedef {Object} RichParty
|
|
867
|
+
* @property {string} id The id of the party
|
|
868
|
+
* @property {number} max The maximum number of members in the party
|
|
869
|
+
* @property {number} current The current number of members in the party
|
|
870
|
+
*/
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Set the party of this activity
|
|
874
|
+
* @param {?RichParty} party The party to be displayed
|
|
875
|
+
* @returns {RichPresence}
|
|
876
|
+
*/
|
|
877
|
+
setParty(party) {
|
|
878
|
+
if (typeof party == 'object') {
|
|
879
|
+
if (!party.max || typeof party.max != 'number') throw new Error('Party must have max number');
|
|
880
|
+
if (!party.current || typeof party.current != 'number') throw new Error('Party must have current');
|
|
881
|
+
if (party.current > party.max) throw new Error('Party current must be less than max number');
|
|
882
|
+
if (!party.id || typeof party.id != 'string') party.id = randomUUID();
|
|
883
|
+
this.party = {
|
|
884
|
+
size: [party.current, party.max],
|
|
885
|
+
id: party.id,
|
|
886
|
+
};
|
|
887
|
+
} else {
|
|
888
|
+
this.party = null;
|
|
889
|
+
}
|
|
890
|
+
return this;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* Sets the start timestamp of the activity
|
|
895
|
+
* @param {Date|number|null} timestamp The timestamp of the start of the activity
|
|
896
|
+
* @returns {RichPresence}
|
|
897
|
+
*/
|
|
898
|
+
setStartTimestamp(timestamp) {
|
|
899
|
+
if (!this.timestamps) this.timestamps = {};
|
|
900
|
+
if (timestamp instanceof Date) timestamp = timestamp.getTime();
|
|
901
|
+
this.timestamps.start = timestamp;
|
|
902
|
+
return this;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Sets the end timestamp of the activity
|
|
907
|
+
* @param {Date|number|null} timestamp The timestamp of the end of the activity
|
|
908
|
+
* @returns {RichPresence}
|
|
909
|
+
*/
|
|
910
|
+
setEndTimestamp(timestamp) {
|
|
911
|
+
if (!this.timestamps) this.timestamps = {};
|
|
912
|
+
if (timestamp instanceof Date) timestamp = timestamp.getTime();
|
|
913
|
+
this.timestamps.end = timestamp;
|
|
914
|
+
return this;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* @typedef {object} RichButton
|
|
919
|
+
* @property {string} name The name of the button
|
|
920
|
+
* @property {string} url The url of the button
|
|
921
|
+
*/
|
|
922
|
+
/**
|
|
923
|
+
* Set the buttons of the rich presence
|
|
924
|
+
* @param {...?RichButton} button A list of buttons to set
|
|
925
|
+
* @returns {RichPresence}
|
|
926
|
+
*/
|
|
927
|
+
setButtons(...button) {
|
|
928
|
+
if (button.length == 0) {
|
|
929
|
+
this.buttons = [];
|
|
930
|
+
delete this.metadata.button_urls;
|
|
931
|
+
return this;
|
|
932
|
+
} else if (button.length > 2) {
|
|
933
|
+
throw new Error('RichPresence can only have up to 2 buttons');
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
this.buttons = [];
|
|
937
|
+
this.metadata.button_urls = [];
|
|
938
|
+
|
|
939
|
+
button.flat(2).forEach(b => {
|
|
940
|
+
if (b.name && b.url) {
|
|
941
|
+
this.buttons.push(b.name);
|
|
942
|
+
if (!URL.canParse(b.url)) throw new Error('Button url must be a valid url');
|
|
943
|
+
this.metadata.button_urls.push(b.url);
|
|
944
|
+
} else {
|
|
945
|
+
throw new Error('Button must have name and url');
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
return this;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* The platform the activity is being played on
|
|
953
|
+
* @param {ActivityPlatform | null} platform Any platform
|
|
954
|
+
* @returns {RichPresence}
|
|
955
|
+
*/
|
|
956
|
+
setPlatform(platform) {
|
|
957
|
+
this.platform = platform;
|
|
958
|
+
return this;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* Secrets for rich presence joining and spectating (send-only)
|
|
963
|
+
* @param {?string} join Secrets for rich presence joining
|
|
964
|
+
* @returns {RichPresence}
|
|
965
|
+
*/
|
|
966
|
+
setJoinSecret(join) {
|
|
967
|
+
this.secrets.join = join;
|
|
968
|
+
return this;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* Add a button to the rich presence
|
|
973
|
+
* @param {string} name The name of the button
|
|
974
|
+
* @param {string} url The url of the button
|
|
975
|
+
* @returns {RichPresence}
|
|
976
|
+
*/
|
|
977
|
+
addButton(name, url) {
|
|
978
|
+
if (!name || !url) {
|
|
979
|
+
throw new Error('Button must have name and url');
|
|
980
|
+
}
|
|
981
|
+
if (typeof name !== 'string') throw new Error('Button name must be a string');
|
|
982
|
+
if (!URL.canParse(url)) throw new Error('Button url must be a valid url');
|
|
983
|
+
this.buttons.push(name);
|
|
984
|
+
if (Array.isArray(this.metadata.button_urls)) this.metadata.button_urls.push(url);
|
|
985
|
+
else this.metadata.button_urls = [url];
|
|
986
|
+
return this;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Convert the rich presence to a JSON object
|
|
991
|
+
* @returns {Object}
|
|
992
|
+
*/
|
|
993
|
+
toJSON(...props) {
|
|
994
|
+
return super.toJSON(
|
|
995
|
+
{
|
|
996
|
+
applicationId: 'application_id',
|
|
997
|
+
sessionId: 'session_id',
|
|
998
|
+
syncId: 'sync_id',
|
|
999
|
+
createdTimestamp: 'created_at',
|
|
1000
|
+
},
|
|
1001
|
+
...props,
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* @typedef {Object} ExternalAssets
|
|
1007
|
+
* @property {?string} url Orginal url of the image
|
|
1008
|
+
* @property {?string} external_asset_path Proxy url of the image (Using to RPC)
|
|
1009
|
+
*/
|
|
1010
|
+
|
|
1011
|
+
/**
|
|
1012
|
+
* Retrieves external assets from a RichPresence
|
|
1013
|
+
* @param {Client} client - The Discord client instance.
|
|
1014
|
+
* @param {Snowflake} applicationId - The application ID associated with the Rich Presence.
|
|
1015
|
+
* @param {...string} images - 1 or 2 external image URLs (not hosted by Discord).
|
|
1016
|
+
* @returns {Promise<ExternalAssets[]>}
|
|
1017
|
+
*/
|
|
1018
|
+
static async getExternal(client, applicationId, ...images) {
|
|
1019
|
+
if (!client || !client.token || !client.api) throw new Error('Client must be set');
|
|
1020
|
+
// Check if applicationId is discord snowflake (17 , 18, 19 numbers)
|
|
1021
|
+
if (!/^[0-9]{17,19}$/.test(applicationId)) {
|
|
1022
|
+
throw new Error('Application id must be a Discord Snowflake');
|
|
1023
|
+
}
|
|
1024
|
+
// Check if images are 1 or 2
|
|
1025
|
+
if (images.length > 2) {
|
|
1026
|
+
throw new Error('RichPresence can only have up to 2 external images');
|
|
1027
|
+
}
|
|
1028
|
+
// Check if all images are valid URLs
|
|
1029
|
+
if (images.some(image => !URL.canParse(image))) {
|
|
1030
|
+
throw new Error('Each image must be a valid URL.');
|
|
1031
|
+
}
|
|
1032
|
+
const res = await client.api.applications[applicationId]['external-assets'].post({
|
|
1033
|
+
data: {
|
|
1034
|
+
urls: images,
|
|
1035
|
+
},
|
|
1036
|
+
});
|
|
1037
|
+
return res;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* When concatenated with a string, this automatically returns the activities' name instead of the Activity object.
|
|
1042
|
+
* @returns {string}
|
|
1043
|
+
*/
|
|
1044
|
+
toString() {
|
|
1045
|
+
return this.name;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
_clone() {
|
|
1049
|
+
return Object.assign(Object.create(this), this);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* @extends {RichPresence}
|
|
1055
|
+
*/
|
|
1056
|
+
class SpotifyRPC extends RichPresence {
|
|
1057
|
+
/**
|
|
1058
|
+
* Create a new RichPresence (Spotify style)
|
|
1059
|
+
* @param {Client} client Discord Client
|
|
1060
|
+
* @param {SpotifyRPC} [options] Options for the Spotify RPC
|
|
1061
|
+
*/
|
|
1062
|
+
constructor(client, options = {}) {
|
|
1063
|
+
if (!client) throw new Error("Class constructor SpotifyRPC cannot be invoked without 'client'");
|
|
1064
|
+
super(client, {
|
|
1065
|
+
name: 'Spotify',
|
|
1066
|
+
type: ActivityTypes.LISTENING,
|
|
1067
|
+
party: {
|
|
1068
|
+
id: `spotify:${client.user.id}`,
|
|
1069
|
+
},
|
|
1070
|
+
id: 'spotify:1',
|
|
1071
|
+
flags: 48, // Sync + Play (ActivityFlags)
|
|
1072
|
+
...options,
|
|
1073
|
+
});
|
|
1074
|
+
this.setup(options);
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Sets the status from a JSON object
|
|
1078
|
+
* @param {SpotifyRPC} options data
|
|
1079
|
+
* @private
|
|
1080
|
+
*/
|
|
1081
|
+
setup(options) {
|
|
1082
|
+
/**
|
|
1083
|
+
* @typedef {Object} SpotifyMetadata
|
|
1084
|
+
* @property {string} album_id The Spotify ID of the album of the song being played
|
|
1085
|
+
* @property {Array<string>} artist_ids The Spotify IDs of the artists of the song being played
|
|
1086
|
+
* @property {string} context_uri The Spotify URI of the current player context
|
|
1087
|
+
*/
|
|
1088
|
+
|
|
1089
|
+
/**
|
|
1090
|
+
* Spotify metadata
|
|
1091
|
+
* @type {SpotifyMetadata}
|
|
1092
|
+
*/
|
|
1093
|
+
this.metadata = {
|
|
1094
|
+
album_id: options.metadata?.album_id || null,
|
|
1095
|
+
artist_ids: options.metadata?.artist_ids || [],
|
|
1096
|
+
context_uri: options.metadata?.context_uri || null,
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Set Spotify song id to sync with
|
|
1102
|
+
* @param {string} id Song id
|
|
1103
|
+
* @returns {SpotifyRPC}
|
|
1104
|
+
*/
|
|
1105
|
+
setSongId(id) {
|
|
1106
|
+
this.syncId = id;
|
|
1107
|
+
return this;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Add the artist id
|
|
1112
|
+
* @param {string} id Artist id
|
|
1113
|
+
* @returns {SpotifyRPC}
|
|
1114
|
+
*/
|
|
1115
|
+
addArtistId(id) {
|
|
1116
|
+
if (!this.metadata.artist_ids) this.metadata.artist_ids = [];
|
|
1117
|
+
this.metadata.artist_ids.push(id);
|
|
1118
|
+
return this;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* Set the artist ids
|
|
1123
|
+
* @param {string | Array<string>} ids Artist ids
|
|
1124
|
+
* @returns {SpotifyRPC}
|
|
1125
|
+
*/
|
|
1126
|
+
setArtistIds(...ids) {
|
|
1127
|
+
if (!ids?.length) {
|
|
1128
|
+
this.metadata.artist_ids = [];
|
|
1129
|
+
return this;
|
|
1130
|
+
}
|
|
1131
|
+
if (!this.metadata.artist_ids) this.metadata.artist_ids = [];
|
|
1132
|
+
ids.flat(2).forEach(id => this.metadata.artist_ids.push(id));
|
|
1133
|
+
return this;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* Set the album id
|
|
1138
|
+
* @param {string} id Album id
|
|
1139
|
+
* @returns {SpotifyRPC}
|
|
1140
|
+
*/
|
|
1141
|
+
setAlbumId(id) {
|
|
1142
|
+
this.metadata.album_id = id;
|
|
1143
|
+
this.metadata.context_uri = `spotify:album:${id}`;
|
|
1144
|
+
return this;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
toJSON() {
|
|
1148
|
+
return super.toJSON({ id: false, emoji: false, platform: false, buttons: false });
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
exports.Presence = Presence;
|
|
1153
|
+
exports.Activity = Activity;
|
|
1154
|
+
exports.RichPresenceAssets = RichPresenceAssets;
|
|
1155
|
+
exports.CustomStatus = CustomStatus;
|
|
1156
|
+
exports.RichPresence = RichPresence;
|
|
1157
|
+
exports.SpotifyRPC = SpotifyRPC;
|