diff --git a/src/main/java/net/dv8tion/jda/api/JDA.java b/src/main/java/net/dv8tion/jda/api/JDA.java index 48581126ae..eefea53fc8 100644 --- a/src/main/java/net/dv8tion/jda/api/JDA.java +++ b/src/main/java/net/dv8tion/jda/api/JDA.java @@ -37,6 +37,7 @@ import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.api.requests.restaction.*; +import net.dv8tion.jda.api.requests.restaction.pagination.EntitlementPaginationAction; import net.dv8tion.jda.api.sharding.ShardManager; import net.dv8tion.jda.api.utils.MiscUtil; import net.dv8tion.jda.api.utils.cache.CacheFlag; @@ -1883,6 +1884,16 @@ default List getEmojisByName(@Nonnull String name, boolean igno @CheckReturnValue RestAction retrieveApplicationInfo(); + /** + * A {@link net.dv8tion.jda.api.requests.restaction.pagination.PaginationAction PaginationAction} implementation + * which allows you to {@link Iterable iterate} over {@link Entitlement}s that are applicable to the logged in application. + * + * @return {@link EntitlementPaginationAction EntitlementPaginationAction} + */ + @Nonnull + @CheckReturnValue + EntitlementPaginationAction retrieveEntitlements(); + /** * Configures the required scopes applied to the {@link #getInviteUrl(Permission...)} and similar methods. *
To use slash commands you must add {@code "applications.commands"} to these scopes. The scope {@code "bot"} is always applied. diff --git a/src/main/java/net/dv8tion/jda/api/entities/Entitlement.java b/src/main/java/net/dv8tion/jda/api/entities/Entitlement.java new file mode 100644 index 0000000000..94fb94dfa3 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/Entitlement.java @@ -0,0 +1,188 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.OffsetDateTime; + +/** + * Represents a user or guild that has access to a premium offering in your application. + * + * @see Discord Docs about Entitlements + */ +public interface Entitlement extends ISnowflake +{ + + /** + * The id of the SKU related to this {@link Entitlement Entitlement} + * + * @return The id of the SKU related to this {@link Entitlement Entitlement} + */ + long getSkuIdLong(); + + /** + * The id of the SKU related to this {@link Entitlement Entitlement} + * + * @return The id of the SKU related to this {@link Entitlement Entitlement} + */ + @Nonnull + default String getSkuId() + { + return Long.toUnsignedString(getSkuIdLong()); + } + + /** + * The id of the parent application of this {@link Entitlement Entitlement} + * + * @return The id of the parent application of this {@link Entitlement Entitlement} + */ + long getApplicationIdLong(); + + /** + * The id of the parent application of this {@link Entitlement Entitlement} + * + * @return The id of the parent application of this {@link Entitlement Entitlement} + */ + @Nonnull + default String getApplicationId() + { + return Long.toUnsignedString(getApplicationIdLong()); + } + + /** + * The id of the user that purchased the {@link Entitlement Entitlement} + * + * @return The id of the user that purchased the {@link Entitlement Entitlement} + */ + long getUserIdLong(); + + /** + * The id of the user that purchased the {@link Entitlement Entitlement} + * + * @return The id of the user that purchased the {@link Entitlement Entitlement} + */ + default String getUserId() + { + return Long.toUnsignedString(getUserIdLong()); + } + + /** + * The guild id that is granted access to the {@link Entitlement Entitlement}s SKU + * + * @return The id of the guild that purchased the {@link Entitlement Entitlement} or 0 if this is not a guild subscription + */ + long getGuildIdLong(); + + /** + * The guild id that is granted access to the {@link Entitlement Entitlement}s SKU + * + * @return The id of the guild that purchased the {@link Entitlement Entitlement} or {@code null} if this is not a guild subscription + */ + @Nullable + default String getGuildId() + { + if (getGuildIdLong() == 0) + return null; + + return Long.toUnsignedString(getGuildIdLong()); + } + + /** + * The type of the Entitlement + *
The only possible type of Entitlement currently is {@link EntitlementType#APPLICATION_SUBSCRIPTION} + *
Discord doesn't currently support other types for entitlements. + * + * @return the {@link Entitlement Entitlement} type + */ + @Nonnull + EntitlementType getType(); + + /** + * Whether the {@link Entitlement Entitlement} has been deleted or not. + * + * @return True if the {@link Entitlement Entitlement} was deleted, False otherwise + * + * @see net.dv8tion.jda.api.events.entitlement.EntitlementDeleteEvent + */ + boolean isDeleted(); + + /** + * The start date at which the {@link Entitlement Entitlement} is valid. + * + * @return Start date at which the {@link Entitlement Entitlement} is valid. Not present when using test entitlements. + */ + @Nullable + OffsetDateTime getTimeStarting(); + + /** + * Date at which the {@link Entitlement Entitlement} is no longer valid. + * + * @return Date at which the {@link Entitlement Entitlement} is no longer valid. Not present when using test entitlements. + */ + @Nullable + OffsetDateTime getTimeEnding(); + + /** + * Represents the type of this Entitlement + */ + enum EntitlementType + { + APPLICATION_SUBSCRIPTION(8), + /** + * Placeholder for unsupported types. + */ + UNKNOWN(-1); + + private final int key; + + EntitlementType(int key) + { + this.key = key; + } + + /** + * The Discord defined id key for this EntitlementType. + * + * @return the id key. + */ + public int getKey() + { + return key; + } + + /** + * Gets the EntitlementType related to the provided key. + *
If an unknown key is provided, this returns {@link #UNKNOWN} + * + * @param key + * The Discord key referencing a EntitlementType. + * + * @return The EntitlementType that has the key provided, or {@link #UNKNOWN} for unknown key. + */ + @Nonnull + public static EntitlementType fromKey(int key) + { + for (EntitlementType type : values()) + { + if (type.getKey() == key) + return type; + } + return UNKNOWN; + } + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementCreateEvent.java new file mode 100644 index 0000000000..b52fe994df --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementCreateEvent.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.entitlement; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Entitlement; + +import javax.annotation.Nonnull; + +/** + * Indicates that a user subscribed to a SKU. + * + * @see #getEntitlement() + */ +public class EntitlementCreateEvent extends GenericEntitlementEvent +{ + public EntitlementCreateEvent(@Nonnull JDA api, long responseNumber, @Nonnull Entitlement entitlement) + { + super(api, responseNumber, entitlement); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementDeleteEvent.java b/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementDeleteEvent.java new file mode 100644 index 0000000000..3325ed636c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementDeleteEvent.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.entitlement; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Entitlement; + +import javax.annotation.Nonnull; + +/** + * Indicates that an {@link Entitlement Entitlement} was deleted. {@link Entitlement Entitlement} deletions are infrequent and occur strictly when: + * + * + * @see #getEntitlement() + * @see EntitlementUpdateEvent + */ +public class EntitlementDeleteEvent extends GenericEntitlementEvent +{ + public EntitlementDeleteEvent(@Nonnull JDA api, long responseNumber, @Nonnull Entitlement entitlement) + { + super(api, responseNumber, entitlement); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementUpdateEvent.java b/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementUpdateEvent.java new file mode 100644 index 0000000000..8602dad960 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/entitlement/EntitlementUpdateEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.entitlement; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Entitlement; + +import javax.annotation.Nonnull; + +/** + * Indicates an {@link Entitlement Entitlement} has renewed for the next billing period. + * The {@link Entitlement#getTimeEnding() timeEnding} will have an updated value with the new expiration date. + * + *

Notice
+ * The {@link Entitlement#getTimeEnding() timeEnding} is updated for active subscriptions at the end of every billing period to + * indicate renewal. When an {@link Entitlement Entitlement} has not been renewed, Discord will indicate this by not emitting + * an {@link EntitlementUpdateEvent} with the new {@link Entitlement#getTimeEnding() timeEnding} date + * + * @see #getEntitlement() + */ +public class EntitlementUpdateEvent extends GenericEntitlementEvent +{ + public EntitlementUpdateEvent(@Nonnull JDA api, long responseNumber, @Nonnull Entitlement entitlement) + { + super(api, responseNumber, entitlement); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/entitlement/GenericEntitlementEvent.java b/src/main/java/net/dv8tion/jda/api/events/entitlement/GenericEntitlementEvent.java new file mode 100644 index 0000000000..fa8071aeeb --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/entitlement/GenericEntitlementEvent.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.entitlement; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Entitlement; +import net.dv8tion.jda.api.events.Event; + +import javax.annotation.Nonnull; + +/** + * Indicates that an {@link Entitlement Entitlement} was either created, updated, or deleted + * + * @see EntitlementCreateEvent + * @see EntitlementUpdateEvent + * @see EntitlementDeleteEvent + */ +public abstract class GenericEntitlementEvent extends Event +{ + protected final Entitlement entitlement; + + protected GenericEntitlementEvent(@Nonnull JDA api, long responseNumber, @Nonnull Entitlement entitlement) + { + super(api, responseNumber); + this.entitlement = entitlement; + } + + /** + * The {@link Entitlement Entitlement} + * + * @return The {@link Entitlement Entitlement} + */ + @Nonnull + public Entitlement getEntitlement() + { + return entitlement; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/entitlement/package-info.java b/src/main/java/net/dv8tion/jda/api/events/entitlement/package-info.java new file mode 100644 index 0000000000..a963879c61 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/entitlement/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Events that indicate that a {@link net.dv8tion.jda.api.entities.Entitlement Entitlement} + * is either created, updated, or deleted. + */ +package net.dv8tion.jda.api.events.entitlement; diff --git a/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java index 2f1eac6ced..24d40d8f20 100644 --- a/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/interaction/GenericInteractionCreateEvent.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.api.events.interaction; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Entitlement; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; @@ -27,6 +28,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; /** * Indicates that an {@link Interaction} was created. @@ -121,6 +123,13 @@ public User getUser() return interaction.getUser(); } + @Nonnull + @Override + public List getEntitlements() + { + return interaction.getEntitlements(); + } + @Override public long getIdLong() { diff --git a/src/main/java/net/dv8tion/jda/api/events/interaction/command/GenericCommandInteractionEvent.java b/src/main/java/net/dv8tion/jda/api/events/interaction/command/GenericCommandInteractionEvent.java index 37f69103cb..b81d5c5fb2 100644 --- a/src/main/java/net/dv8tion/jda/api/events/interaction/command/GenericCommandInteractionEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/interaction/command/GenericCommandInteractionEvent.java @@ -24,6 +24,7 @@ import net.dv8tion.jda.api.interactions.commands.OptionMapping; import net.dv8tion.jda.api.interactions.modals.Modal; import net.dv8tion.jda.api.requests.restaction.interactions.ModalCallbackAction; +import net.dv8tion.jda.api.requests.restaction.interactions.PremiumRequiredCallbackAction; import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; import javax.annotation.Nonnull; @@ -118,4 +119,11 @@ public ModalCallbackAction replyModal(@Nonnull Modal modal) { return getInteraction().replyModal(modal); } + + @Nonnull + @Override + public PremiumRequiredCallbackAction replyWithPremiumRequired() + { + return getInteraction().replyWithPremiumRequired(); + } } diff --git a/src/main/java/net/dv8tion/jda/api/events/interaction/component/GenericComponentInteractionCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/interaction/component/GenericComponentInteractionCreateEvent.java index 82ef4c9a60..2a04315b09 100644 --- a/src/main/java/net/dv8tion/jda/api/events/interaction/component/GenericComponentInteractionCreateEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/interaction/component/GenericComponentInteractionCreateEvent.java @@ -27,6 +27,7 @@ import net.dv8tion.jda.api.interactions.modals.Modal; import net.dv8tion.jda.api.requests.restaction.interactions.MessageEditCallbackAction; import net.dv8tion.jda.api.requests.restaction.interactions.ModalCallbackAction; +import net.dv8tion.jda.api.requests.restaction.interactions.PremiumRequiredCallbackAction; import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; import javax.annotation.Nonnull; @@ -124,4 +125,11 @@ public ModalCallbackAction replyModal(@Nonnull Modal modal) { return interaction.replyModal(modal); } + + @Nonnull + @Override + public PremiumRequiredCallbackAction replyWithPremiumRequired() + { + return interaction.replyWithPremiumRequired(); + } } diff --git a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java index 3df7247bae..fa764c405e 100644 --- a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java +++ b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java @@ -36,6 +36,10 @@ import net.dv8tion.jda.api.events.emoji.update.EmojiUpdateNameEvent; import net.dv8tion.jda.api.events.emoji.update.EmojiUpdateRolesEvent; import net.dv8tion.jda.api.events.emoji.update.GenericEmojiUpdateEvent; +import net.dv8tion.jda.api.events.entitlement.EntitlementCreateEvent; +import net.dv8tion.jda.api.events.entitlement.EntitlementDeleteEvent; +import net.dv8tion.jda.api.events.entitlement.EntitlementUpdateEvent; +import net.dv8tion.jda.api.events.entitlement.GenericEntitlementEvent; import net.dv8tion.jda.api.events.guild.*; import net.dv8tion.jda.api.events.guild.invite.GenericGuildInviteEvent; import net.dv8tion.jda.api.events.guild.invite.GuildInviteCreateEvent; @@ -363,6 +367,11 @@ public void onGuildStickerUpdateTags(@Nonnull GuildStickerUpdateTagsEvent event) public void onGuildStickerUpdateDescription(@Nonnull GuildStickerUpdateDescriptionEvent event) {} public void onGuildStickerUpdateAvailable(@Nonnull GuildStickerUpdateAvailableEvent event) {} + // Entitlement events + public void onEntitlementCreate(@Nonnull EntitlementCreateEvent event) {} + public void onEntitlementUpdate(@Nonnull EntitlementUpdateEvent event) {} + public void onEntitlementDelete(@Nonnull EntitlementDeleteEvent event) {} + // Debug Events public void onHttpRequest(@Nonnull HttpRequestEvent event) {} @@ -403,6 +412,7 @@ public void onGenericEmoji(@Nonnull GenericEmojiEvent event) {} public void onGenericEmojiUpdate(@Nonnull GenericEmojiUpdateEvent event) {} public void onGenericGuildSticker(@Nonnull GenericGuildStickerEvent event) {} public void onGenericGuildStickerUpdate(@Nonnull GenericGuildStickerUpdateEvent event) {} + public void onGenericEntitlement(@Nonnull GenericEntitlementEvent event) {} public void onGenericPermissionOverride(@Nonnull GenericPermissionOverrideEvent event) {} public void onGenericScheduledEventUpdate(@Nonnull GenericScheduledEventUpdateEvent event) {} public void onGenericScheduledEventGateway(@Nonnull GenericScheduledEventGatewayEvent event) {} diff --git a/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java b/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java index 19f773c434..32fbb0d545 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/Interaction.java @@ -17,10 +17,7 @@ package net.dv8tion.jda.api.interactions; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.ISnowflake; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; @@ -33,6 +30,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; /** * Abstract representation for any kind of Discord interaction. @@ -50,6 +48,8 @@ *
Which supports choice suggestions for auto-complete interactions via {@link IAutoCompleteCallback#replyChoices(Command.Choice...)} *

  • {@link IModalCallback} *
    Which supports replying using a {@link Modal} via {@link IModalCallback#replyModal(Modal)}
  • + *
  • {@link IPremiumRequiredReplyCallback} + *
    Which will reply stating that an {@link Entitlement Entitlement} is required
  • * * *

    Once the interaction is acknowledged, you can not reply with these methods again. If the interaction is a {@link IDeferrableCallback deferrable}, @@ -231,6 +231,15 @@ default DiscordLocale getGuildLocale() return getGuild().getLocale(); } + /** + * Returns the list of {@link Entitlement entitlements} for the current guild and user. + *
    If this interaction is not from a guild, it will only contain entitlements of the user. + * + * @return The {@link List List} of {@link Entitlement Entitlement} + */ + @Nonnull + List getEntitlements(); + /** * Returns the {@link net.dv8tion.jda.api.JDA JDA} instance of this interaction * diff --git a/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IPremiumRequiredReplyCallback.java b/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IPremiumRequiredReplyCallback.java new file mode 100644 index 0000000000..a25b923c94 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IPremiumRequiredReplyCallback.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.interactions.callbacks; + +import net.dv8tion.jda.api.requests.restaction.interactions.PremiumRequiredCallbackAction; +import net.dv8tion.jda.api.entities.Entitlement; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; + +/** + * Replies with an in-built client message stating that an {@link Entitlement Entitlement} is required. + * + *

    Replying with {@link #replyWithPremiumRequired()} will automatically acknowledge this interaction. + * + *

    Note:This interaction requires monetization to be enabled. + */ +public interface IPremiumRequiredReplyCallback extends IDeferrableCallback +{ + @Nonnull + @CheckReturnValue + PremiumRequiredCallbackAction replyWithPremiumRequired(); +} diff --git a/src/main/java/net/dv8tion/jda/api/interactions/commands/CommandInteraction.java b/src/main/java/net/dv8tion/jda/api/interactions/commands/CommandInteraction.java index 7312595642..d0a87b1ed5 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/commands/CommandInteraction.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/commands/CommandInteraction.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.api.interactions.commands; import net.dv8tion.jda.api.interactions.callbacks.IModalCallback; +import net.dv8tion.jda.api.interactions.callbacks.IPremiumRequiredReplyCallback; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.interactions.commands.context.ContextInteraction; @@ -28,6 +29,6 @@ * @see ContextInteraction * @see SlashCommandInteraction */ -public interface CommandInteraction extends IReplyCallback, CommandInteractionPayload, IModalCallback +public interface CommandInteraction extends IReplyCallback, CommandInteractionPayload, IModalCallback, IPremiumRequiredReplyCallback { } diff --git a/src/main/java/net/dv8tion/jda/api/interactions/components/ComponentInteraction.java b/src/main/java/net/dv8tion/jda/api/interactions/components/ComponentInteraction.java index f56895df12..2b2290c213 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/components/ComponentInteraction.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/components/ComponentInteraction.java @@ -21,6 +21,7 @@ import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion; import net.dv8tion.jda.api.interactions.callbacks.IMessageEditCallback; import net.dv8tion.jda.api.interactions.callbacks.IModalCallback; +import net.dv8tion.jda.api.interactions.callbacks.IPremiumRequiredReplyCallback; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import javax.annotation.Nonnull; @@ -31,7 +32,7 @@ *

    Instead of {@link #deferReply()} and {@link #reply(String)} you can use {@link #deferEdit()} and {@link #editMessage(String)} with these interactions! * You can only acknowledge an interaction once! */ -public interface ComponentInteraction extends IReplyCallback, IMessageEditCallback, IModalCallback +public interface ComponentInteraction extends IReplyCallback, IMessageEditCallback, IModalCallback, IPremiumRequiredReplyCallback { /** * The custom component ID provided to the component when it was originally created. diff --git a/src/main/java/net/dv8tion/jda/api/requests/Route.java b/src/main/java/net/dv8tion/jda/api/requests/Route.java index d454255048..a522a1943e 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/Route.java +++ b/src/main/java/net/dv8tion/jda/api/requests/Route.java @@ -45,6 +45,7 @@ public static class Applications public static final Route GET_BOT_APPLICATION = new Route(GET, "oauth2/applications/@me"); public static final Route GET_ROLE_CONNECTION_METADATA = new Route(GET, "applications/{application_id}/role-connections/metadata"); public static final Route UPDATE_ROLE_CONNECTION_METADATA = new Route(PUT, "applications/{application_id}/role-connections/metadata"); + public static final Route GET_ENTITLEMENTS = new Route(GET, "applications/{application_id}/entitlements"); } public static class Interactions diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/InteractionCallbackAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/InteractionCallbackAction.java index e15775a004..90d3b045bc 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/InteractionCallbackAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/InteractionCallbackAction.java @@ -55,6 +55,8 @@ enum ResponseType COMMAND_AUTOCOMPLETE_CHOICES(8), /** Respond with a modal */ MODAL(9), + /** Respond with the "Premium required" default Discord message for premium App subscriptions **/ + PREMIUM_REQUIRED(10), ; private final int raw; diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/PremiumRequiredCallbackAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/PremiumRequiredCallbackAction.java new file mode 100644 index 0000000000..4d2031865a --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/interactions/PremiumRequiredCallbackAction.java @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.requests.restaction.interactions; + +import net.dv8tion.jda.api.requests.FluentRestAction; + +/** + * An {@link InteractionCallbackAction} that can be used to send the "Premium required" interaction response. + * + * @see net.dv8tion.jda.api.interactions.callbacks.IPremiumRequiredReplyCallback + */ +public interface PremiumRequiredCallbackAction extends InteractionCallbackAction, FluentRestAction +{ + +} diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/pagination/EntitlementPaginationAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/pagination/EntitlementPaginationAction.java new file mode 100644 index 0000000000..e850d0f7f0 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/pagination/EntitlementPaginationAction.java @@ -0,0 +1,149 @@ +package net.dv8tion.jda.api.requests.restaction.pagination; + +import net.dv8tion.jda.api.entities.Entitlement; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.UserSnowflake; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; + +/** + * {@link PaginationAction PaginationAction} that paginates the application entitlements endpoint. + *

    By default, JDA will include {@link Entitlement Entitlement}s which have ended, that is, {@link Entitlement Entitlement}s which + * have gone past their {@link Entitlement#getTimeEnding() timeEnding}. You may use {@link EntitlementPaginationAction#excludeEnded excludeEnded(true)} + * to only return {@link Entitlement}s which are still active + * + *

    Limits
    + * Minimum - 1
    + * Maximum - 100 + *
    Default - 100 + * + *

    Example
    + *

    {@code
    + * //Fetch all entitlements for a given SKU id
    + * public static void fetchEntitlements(JDA api, String skuId, Consumer> callback) {
    + *     List entitlements = new ArrayList<>()
    + *     EntitlementPaginationAction action = api.retrieveEntitlements().skuIds(skuId).excludeEnded(true)
    + *     action.forEachAsync((entitlement) -> {
    + *           entitlements.add(entitlement)
    + *           return true; //continues to retrieve all entitlements until there are none left to retrieve
    + *     }.thenRun(() -> callback.accept(entitlements));
    + * }
    + * }
    + */ +public interface EntitlementPaginationAction extends PaginationAction +{ + /** + * Filter {@link Entitlement Entitlement}s to retrieve by the given user ID + * + * @param user + * The {@link UserSnowflake UserSnowflake} used to filter or {@code null} to remove user filtering. + * This can be a member or user instance of {@link User#fromId(long)} + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + EntitlementPaginationAction user(@Nullable UserSnowflake user); + + /** + * Filters {@link Entitlement Entitlement}s by their SKU id + * + * @param skuIds + * The SKU ids to filter by + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + EntitlementPaginationAction skuIds(long... skuIds); + + /** + * Filters {@link Entitlement Entitlement}s by their SKU id + * + * @param skuIds + * The SKU ids to filter by + * + * @throws java.lang.IllegalArgumentException + * If any of the provided {@code skuIds} are {@code null}, empty or are not a valid snowflake + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + EntitlementPaginationAction skuIds(@Nonnull String... skuIds); + + /** + * Filters {@link Entitlement Entitlement}s by their SKU id + * + * @param skuIds + * The SKU ids to filter by + * + * @throws java.lang.IllegalArgumentException + * If any of the provided {@code skuIds} are {@code null}, empty or invalid snowflakes + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + EntitlementPaginationAction skuIds(@Nonnull Collection skuIds); + + /** + * Filters {@link Entitlement Entitlement}s by a guild id + * + * @param guildId + * The guild id to filter by + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + EntitlementPaginationAction guild(long guildId); + + /** + * Filters {@link Entitlement Entitlement}s by a guild id + * + * @param guildId + * The guild id to filter by + * + * @throws java.lang.IllegalArgumentException + * If the provided {@code guildId} is {@code null}, empty or is not a valid snowflake + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + default EntitlementPaginationAction guild(@Nonnull String guildId) + { + Checks.notNull(guildId, "guildId"); + Checks.isSnowflake(guildId, "guildId"); + return guild(Long.parseUnsignedLong(guildId)); + } + + /** + * Filters {@link Entitlement Entitlement}s by a {@link Guild Guild} + * + * @param guild + * The {@link Guild Guild} to filter by + * + * @throws java.lang.IllegalArgumentException + * If the provided {@code guild} is {@code null} + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + default EntitlementPaginationAction guild(@Nonnull Guild guild) + { + Checks.notNull(guild, "guild"); + return guild(guild.getIdLong()); + } + + /** + * Whether to exclude subscriptions which have gone past their end date. + *

    Test entitlements which are created through the API do not have an end date. + * + * @param excludeEnded + * Whether to exclude ended subscriptions from returned {@link Entitlement Entitlement}s + * + * @return The current {@link EntitlementPaginationAction EntitlementPaginationAction} for chaining convenience + */ + @Nonnull + EntitlementPaginationAction excludeEnded(boolean excludeEnded); +} diff --git a/src/main/java/net/dv8tion/jda/internal/JDAImpl.java b/src/main/java/net/dv8tion/jda/internal/JDAImpl.java index f55f980111..01f84c3a50 100644 --- a/src/main/java/net/dv8tion/jda/internal/JDAImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/JDAImpl.java @@ -52,6 +52,7 @@ import net.dv8tion.jda.api.requests.restaction.CommandCreateAction; import net.dv8tion.jda.api.requests.restaction.CommandEditAction; import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction; +import net.dv8tion.jda.api.requests.restaction.pagination.EntitlementPaginationAction; import net.dv8tion.jda.api.sharding.ShardManager; import net.dv8tion.jda.api.utils.*; import net.dv8tion.jda.api.utils.cache.CacheFlag; @@ -75,6 +76,7 @@ import net.dv8tion.jda.internal.requests.restaction.CommandEditActionImpl; import net.dv8tion.jda.internal.requests.restaction.CommandListUpdateActionImpl; import net.dv8tion.jda.internal.requests.restaction.GuildActionImpl; +import net.dv8tion.jda.internal.requests.restaction.pagination.EntitlementPaginationActionImpl; import net.dv8tion.jda.internal.utils.Helpers; import net.dv8tion.jda.internal.utils.*; import net.dv8tion.jda.internal.utils.cache.AbstractCacheView; @@ -1164,6 +1166,13 @@ public RestAction retrieveApplicationInfo() }); } + @Nonnull + @Override + public EntitlementPaginationAction retrieveEntitlements() + { + return new EntitlementPaginationActionImpl(this); + } + @Nonnull @Override public JDA setRequiredScopes(@Nonnull Collection scopes) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/AbstractWebhookClient.java b/src/main/java/net/dv8tion/jda/internal/entities/AbstractWebhookClient.java index 87d0c8d18b..1e636eb5e0 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/AbstractWebhookClient.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/AbstractWebhookClient.java @@ -33,7 +33,6 @@ import net.dv8tion.jda.internal.requests.restaction.WebhookMessageDeleteActionImpl; import net.dv8tion.jda.internal.requests.restaction.WebhookMessageEditActionImpl; import net.dv8tion.jda.internal.utils.Checks; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import java.util.Collection; @@ -91,7 +90,7 @@ public WebhookMessageCreateAction sendMessageEmbeds(@Nonnull Collection sendMessageComponents(@NotNull Collection components) + public WebhookMessageCreateAction sendMessageComponents(@Nonnull Collection components) { return sendRequest().setComponents(components); } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntitlementImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/EntitlementImpl.java new file mode 100644 index 0000000000..e77d790477 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntitlementImpl.java @@ -0,0 +1,106 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities; + +import net.dv8tion.jda.api.entities.Entitlement; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.OffsetDateTime; + +public class EntitlementImpl implements Entitlement +{ + private long id; + private long skuId; + private long applicationId; + private long userId; + private long guildId; + private EntitlementType type; + private boolean deleted; + private OffsetDateTime startsAt; + private OffsetDateTime endsAt; + + public EntitlementImpl(long id, long skuId, long applicationId, long userId, long guildId, EntitlementType type, boolean deleted, @Nullable OffsetDateTime startsAt, @Nullable OffsetDateTime endsAt) + { + this.id = id; + this.skuId = skuId; + this.applicationId = applicationId; + this.userId = userId; + this.guildId = guildId; + this.type = type; + this.deleted = deleted; + this.startsAt = startsAt; + this.endsAt = endsAt; + } + + @Override + public long getIdLong() + { + return id; + } + + @Override + public long getSkuIdLong() + { + return skuId; + } + + @Override + public long getApplicationIdLong() + { + return applicationId; + } + + @Override + public long getUserIdLong() + { + return userId; + } + + @Override + public long getGuildIdLong() + { + return guildId; + } + + @Nonnull + @Override + public EntitlementType getType() + { + return type; + } + + @Override + public boolean isDeleted() + { + return deleted; + } + + @Nullable + @Override + public OffsetDateTime getTimeStarting() + { + return startsAt; + } + + @Nullable + @Override + public OffsetDateTime getTimeEnding() + { + return endsAt; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java index 00440cd534..65fef6f639 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java @@ -2557,6 +2557,21 @@ public AuditLogChange createAuditLogChange(DataObject change) return new AuditLogChange(oldValue, newValue, key); } + public Entitlement createEntitlement(DataObject object) + { + return new EntitlementImpl( + object.getLong("id"), + object.getLong("sku_id"), + object.getLong("application_id"), + object.getLong("user_id", 0), + object.getLong("guild_id", 0), + Entitlement.EntitlementType.fromKey(object.getInt("type")), + object.getBoolean("deleted"), + object.getOffsetDateTime("starts_at", null), + object.getOffsetDateTime("ends_at", null) + ); + } + private Map changeToMap(Set changesList) { return changesList.stream().collect(Collectors.toMap(AuditLogChange::getKey, UnaryOperator.identity())); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java index 9bfbd75cad..2f07ecc677 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java @@ -29,8 +29,8 @@ import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.utils.EntityString; import net.dv8tion.jda.internal.utils.Helpers; -import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -68,7 +68,7 @@ public long getIdLong() return id; } - @NotNull + @Nonnull @Override public Guild getGuild() { @@ -84,21 +84,21 @@ public long getCreatorIdLong() return ownerId; } - @NotNull + @Nonnull @Override public String getName() { return name; } - @NotNull + @Nonnull @Override public AutoModEventType getEventType() { return eventType; } - @NotNull + @Nonnull @Override public AutoModTriggerType getTriggerType() { @@ -111,7 +111,7 @@ public boolean isEnabled() return enabled; } - @NotNull + @Nonnull @Override public List getExemptRoles() { @@ -126,7 +126,7 @@ public List getExemptRoles() return Collections.unmodifiableList(roles); } - @NotNull + @Nonnull @Override public List getExemptChannels() { @@ -141,35 +141,35 @@ public List getExemptChannels() return Collections.unmodifiableList(channels); } - @NotNull + @Nonnull @Override public List getActions() { return actions; } - @NotNull + @Nonnull @Override public List getFilteredKeywords() { return filteredKeywords; } - @NotNull + @Nonnull @Override public List getFilteredRegex() { return filteredRegex; } - @NotNull + @Nonnull @Override public EnumSet getFilteredPresets() { return Helpers.copyEnumSet(KeywordPreset.class, filteredPresets); } - @NotNull + @Nonnull @Override public List getAllowlist() { diff --git a/src/main/java/net/dv8tion/jda/internal/handle/EntitlementCreateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/EntitlementCreateHandler.java new file mode 100644 index 0000000000..32367ecff4 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/EntitlementCreateHandler.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.events.entitlement.EntitlementCreateEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; + +public class EntitlementCreateHandler extends SocketHandler +{ + public EntitlementCreateHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + getJDA().handleEvent(new EntitlementCreateEvent(getJDA(), responseNumber, getJDA().getEntityBuilder().createEntitlement(content))); + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/EntitlementDeleteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/EntitlementDeleteHandler.java new file mode 100644 index 0000000000..22a54e3bbd --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/EntitlementDeleteHandler.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.events.entitlement.EntitlementDeleteEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; + +public class EntitlementDeleteHandler extends SocketHandler +{ + public EntitlementDeleteHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + getJDA().handleEvent(new EntitlementDeleteEvent(getJDA(), responseNumber, getJDA().getEntityBuilder().createEntitlement(content))); + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/EntitlementUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/EntitlementUpdateHandler.java new file mode 100644 index 0000000000..c2a8617752 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/EntitlementUpdateHandler.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; +import net.dv8tion.jda.api.events.entitlement.EntitlementUpdateEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; + +public class EntitlementUpdateHandler extends SocketHandler +{ + public EntitlementUpdateHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + getJDA().handleEvent(new EntitlementUpdateEvent(getJDA(), responseNumber, getJDA().getEntityBuilder().createEntitlement(content))); + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/interactions/InteractionImpl.java b/src/main/java/net/dv8tion/jda/internal/interactions/InteractionImpl.java index 9c334a9d38..cce804a8bd 100644 --- a/src/main/java/net/dv8tion/jda/internal/interactions/InteractionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/interactions/InteractionImpl.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.internal.interactions; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Entitlement; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; @@ -26,15 +27,17 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.interactions.DiscordLocale; import net.dv8tion.jda.api.interactions.Interaction; +import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; -import net.dv8tion.jda.internal.entities.GuildImpl; -import net.dv8tion.jda.internal.entities.MemberImpl; -import net.dv8tion.jda.internal.entities.UserImpl; +import net.dv8tion.jda.internal.entities.*; import net.dv8tion.jda.internal.entities.channel.concrete.PrivateChannelImpl; +import net.dv8tion.jda.internal.utils.Helpers; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.List; +import java.util.stream.Collectors; public class InteractionImpl implements Interaction { @@ -47,6 +50,7 @@ public class InteractionImpl implements Interaction protected final User user; protected final Channel channel; protected final DiscordLocale userLocale; + protected final List entitlements; protected final JDAImpl api; //This is used to give a proper error when an interaction is ack'd twice @@ -104,6 +108,11 @@ public InteractionImpl(JDAImpl jda, DataObject data) } this.user = user; } + + this.entitlements = data.optArray("entitlements").orElseGet(DataArray::empty) + .stream(DataArray::getObject) + .map(jda.getEntityBuilder()::createEntitlement) + .collect(Helpers.toUnmodifiableList()); } // Used to allow interaction hook to send messages after acknowledgements @@ -183,6 +192,13 @@ public Member getMember() return member; } + @Nonnull + @Override + public List getEntitlements() + { + return entitlements; + } + @Nonnull @Override public JDA getJDA() diff --git a/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandInteractionImpl.java b/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandInteractionImpl.java index 2940a5ad99..9d437bac2c 100644 --- a/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandInteractionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/interactions/command/CommandInteractionImpl.java @@ -20,11 +20,13 @@ import net.dv8tion.jda.api.interactions.commands.CommandInteractionPayload; import net.dv8tion.jda.api.interactions.modals.Modal; import net.dv8tion.jda.api.requests.restaction.interactions.ModalCallbackAction; +import net.dv8tion.jda.api.requests.restaction.interactions.PremiumRequiredCallbackAction; import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.interactions.DeferrableInteractionImpl; import net.dv8tion.jda.internal.requests.restaction.interactions.ModalCallbackActionImpl; +import net.dv8tion.jda.internal.requests.restaction.interactions.PremiumRequiredCallbackActionImpl; import net.dv8tion.jda.internal.requests.restaction.interactions.ReplyCallbackActionImpl; import net.dv8tion.jda.internal.utils.Checks; @@ -60,4 +62,11 @@ public ModalCallbackAction replyModal(@Nonnull Modal modal) Checks.notNull(modal, "Modal"); return new ModalCallbackActionImpl(this, modal); } + + @Nonnull + @Override + public PremiumRequiredCallbackAction replyWithPremiumRequired() + { + return new PremiumRequiredCallbackActionImpl(this); + } } diff --git a/src/main/java/net/dv8tion/jda/internal/interactions/component/ComponentInteractionImpl.java b/src/main/java/net/dv8tion/jda/internal/interactions/component/ComponentInteractionImpl.java index e6e735eae3..e7ec45268b 100644 --- a/src/main/java/net/dv8tion/jda/internal/interactions/component/ComponentInteractionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/interactions/component/ComponentInteractionImpl.java @@ -23,6 +23,7 @@ import net.dv8tion.jda.api.interactions.components.ComponentInteraction; import net.dv8tion.jda.api.interactions.modals.Modal; import net.dv8tion.jda.api.requests.restaction.interactions.ModalCallbackAction; +import net.dv8tion.jda.api.requests.restaction.interactions.PremiumRequiredCallbackAction; import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; @@ -30,6 +31,7 @@ import net.dv8tion.jda.internal.interactions.DeferrableInteractionImpl; import net.dv8tion.jda.internal.requests.restaction.interactions.MessageEditCallbackActionImpl; import net.dv8tion.jda.internal.requests.restaction.interactions.ModalCallbackActionImpl; +import net.dv8tion.jda.internal.requests.restaction.interactions.PremiumRequiredCallbackActionImpl; import net.dv8tion.jda.internal.requests.restaction.interactions.ReplyCallbackActionImpl; import net.dv8tion.jda.internal.utils.Checks; @@ -115,4 +117,11 @@ public ModalCallbackAction replyModal(@Nonnull Modal modal) return new ModalCallbackActionImpl(this, modal); } + + @Nonnull + @Override + public PremiumRequiredCallbackAction replyWithPremiumRequired() + { + return new PremiumRequiredCallbackActionImpl(this); + } } diff --git a/src/main/java/net/dv8tion/jda/internal/interactions/component/EntitySelectMenuImpl.java b/src/main/java/net/dv8tion/jda/internal/interactions/component/EntitySelectMenuImpl.java index a760810b6e..f2a7540aea 100644 --- a/src/main/java/net/dv8tion/jda/internal/interactions/component/EntitySelectMenuImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/interactions/component/EntitySelectMenuImpl.java @@ -22,7 +22,6 @@ import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.utils.Helpers; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import java.util.Collections; @@ -99,7 +98,7 @@ public List getDefaultValues() return defaultValues; } - @NotNull + @Nonnull @Override public DataObject toData() { diff --git a/src/main/java/net/dv8tion/jda/internal/requests/IncomingWebhookClientImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/IncomingWebhookClientImpl.java index 9f7bd21f56..2f32deb30c 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/IncomingWebhookClientImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/IncomingWebhookClientImpl.java @@ -33,7 +33,6 @@ import net.dv8tion.jda.internal.requests.restaction.WebhookMessageEditActionImpl; import net.dv8tion.jda.internal.requests.restaction.WebhookMessageRetrieveActionImpl; import net.dv8tion.jda.internal.utils.Checks; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import java.util.function.Function; @@ -82,7 +81,7 @@ public WebhookMessageRetrieveAction retrieveMessageById(@Nonnull String messageI @Nonnull @Override - public WebhookMessageDeleteAction deleteMessageById(@NotNull String messageId) + public WebhookMessageDeleteAction deleteMessageById(@Nonnull String messageId) { WebhookMessageDeleteActionImpl action = (WebhookMessageDeleteActionImpl) super.deleteMessageById(messageId); action.run(); diff --git a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java index 1a7c1fca7f..08f24d1ad5 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java @@ -1361,6 +1361,9 @@ protected void setupHandlers() handlers.put("CHANNEL_CREATE", new ChannelCreateHandler(api)); handlers.put("CHANNEL_DELETE", new ChannelDeleteHandler(api)); handlers.put("CHANNEL_UPDATE", new ChannelUpdateHandler(api)); + handlers.put("ENTITLEMENT_CREATE", new EntitlementCreateHandler(api)); + handlers.put("ENTITLEMENT_UPDATE", new EntitlementUpdateHandler(api)); + handlers.put("ENTITLEMENT_DELETE", new EntitlementDeleteHandler(api)); handlers.put("GUILD_AUDIT_LOG_ENTRY_CREATE", new GuildAuditLogEntryCreateHandler(api)); handlers.put("GUILD_BAN_ADD", new GuildBanHandler(api, true)); handlers.put("GUILD_BAN_REMOVE", new GuildBanHandler(api, false)); diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java index ba7873b7f5..fdd02e0db1 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/CommandCreateActionImpl.java @@ -34,7 +34,6 @@ import net.dv8tion.jda.internal.interactions.command.CommandImpl; import net.dv8tion.jda.internal.requests.RestActionImpl; import okhttp3.RequestBody; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import java.util.List; @@ -225,19 +224,19 @@ public LocalizationMap getDescriptionLocalizations() } @Override - public boolean removeOptions(@NotNull Predicate condition) + public boolean removeOptions(@Nonnull Predicate condition) { return data.removeOptions(condition); } @Override - public boolean removeSubcommands(@NotNull Predicate condition) + public boolean removeSubcommands(@Nonnull Predicate condition) { return data.removeSubcommands(condition); } @Override - public boolean removeSubcommandGroups(@NotNull Predicate condition) + public boolean removeSubcommandGroups(@Nonnull Predicate condition) { return data.removeSubcommandGroups(condition); } diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/interactions/PremiumRequiredCallbackActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/interactions/PremiumRequiredCallbackActionImpl.java new file mode 100644 index 0000000000..45ca3752f2 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/interactions/PremiumRequiredCallbackActionImpl.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.requests.restaction.interactions; + +import net.dv8tion.jda.api.interactions.callbacks.IPremiumRequiredReplyCallback; +import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction; +import net.dv8tion.jda.api.requests.restaction.interactions.PremiumRequiredCallbackAction; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.interactions.InteractionImpl; +import okhttp3.RequestBody; + +import javax.annotation.Nonnull; +import java.util.function.BooleanSupplier; + +public class PremiumRequiredCallbackActionImpl extends InteractionCallbackImpl implements PremiumRequiredCallbackAction +{ + + public PremiumRequiredCallbackActionImpl(IPremiumRequiredReplyCallback interaction) + { + super((InteractionImpl) interaction); + } + + @Override + protected RequestBody finalizeData() + { + return getRequestBody(DataObject.empty() + .put("type", InteractionCallbackAction.ResponseType.PREMIUM_REQUIRED.getRaw()) + .put("data", DataObject.empty())); + } + + @Nonnull + @Override + public PremiumRequiredCallbackAction setCheck(BooleanSupplier checks) + { + return (PremiumRequiredCallbackAction) super.setCheck(checks); + } + + @Nonnull + @Override + public PremiumRequiredCallbackAction deadline(long timestamp) + { + return (PremiumRequiredCallbackAction) super.deadline(timestamp); + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/pagination/EntitlementPaginationActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/pagination/EntitlementPaginationActionImpl.java new file mode 100644 index 0000000000..c51e54c534 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/pagination/EntitlementPaginationActionImpl.java @@ -0,0 +1,183 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.requests.restaction.pagination; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Entitlement; +import net.dv8tion.jda.api.entities.UserSnowflake; +import net.dv8tion.jda.api.exceptions.ParsingException; +import net.dv8tion.jda.api.requests.Request; +import net.dv8tion.jda.api.requests.Response; +import net.dv8tion.jda.api.requests.Route; +import net.dv8tion.jda.api.requests.restaction.pagination.EntitlementPaginationAction; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.entities.EntityBuilder; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; + +public class EntitlementPaginationActionImpl + extends PaginationActionImpl + implements EntitlementPaginationAction +{ + protected List skuIds; + protected long guildId; + protected long userId; + protected boolean excludeEnded; + + public EntitlementPaginationActionImpl(JDA api) + { + super(api, Route.Applications.GET_ENTITLEMENTS.compile(api.getSelfUser().getApplicationId()), 1, 100, 100); + this.skuIds = new ArrayList<>(); + this.guildId = 0; + this.userId = 0; + } + + @Nonnull + @Override + public EnumSet getSupportedOrders() + { + return EnumSet.of(PaginationOrder.BACKWARD, PaginationOrder.FORWARD); + } + + @Nonnull + @Override + public EntitlementPaginationAction user(@Nullable UserSnowflake user) + { + if (user == null) + userId = 0; + else + userId = user.getIdLong(); + return this; + } + + @Nonnull + @Override + public EntitlementPaginationAction skuIds(long... skuIds) + { + this.skuIds.clear(); + for (long skuId : skuIds) + this.skuIds.add(Long.toUnsignedString(skuId)); + return this; + } + + @Nonnull + @Override + public EntitlementPaginationAction skuIds(@Nonnull String... skuIds) + { + Checks.noneNull(skuIds, "skuIds"); + for (String skuId : skuIds) + Checks.isSnowflake(skuId, "skuId"); + + this.skuIds.clear(); + + Collections.addAll(this.skuIds, skuIds); + return this; + } + + @Nonnull + @Override + public EntitlementPaginationAction skuIds(@Nonnull Collection skuIds) + { + Checks.noneNull(skuIds, "skuIds"); + + this.skuIds.clear(); + for (String skuId : skuIds) + { + Checks.isSnowflake(skuId, "skuId"); + this.skuIds.add(skuId); + } + + return this; + } + + @Nonnull + @Override + public EntitlementPaginationAction guild(long guildId) + { + this.guildId = guildId; + return this; + } + + @Nonnull + @Override + public EntitlementPaginationAction excludeEnded(boolean excludeEnded) + { + this.excludeEnded = excludeEnded; + return this; + } + + @Override + protected Route.CompiledRoute finalizeRoute() + { + Route.CompiledRoute route = super.finalizeRoute(); + + if (userId != 0) + route = route.withQueryParams("user_id", Long.toUnsignedString(userId)); + + if (!skuIds.isEmpty()) + route = route.withQueryParams("sku_ids", String.join(",", skuIds)); + + if (guildId != 0) + route = route.withQueryParams("guild_id", Long.toUnsignedString(guildId)); + + if (excludeEnded) + route = route.withQueryParams("exclude_ended", String.valueOf(true)); + + return route; + } + + @Override + protected void handleSuccess(Response response, Request> request) + { + DataArray array = response.getArray(); + List entitlements = new ArrayList<>(array.length()); + EntityBuilder builder = api.getEntityBuilder(); + for (int i = 0; i < array.length(); i++) + { + try + { + DataObject object = array.getObject(i); + Entitlement entitlement = builder.createEntitlement(object); + entitlements.add(entitlement); + } + catch(ParsingException | NullPointerException e) + { + LOG.warn("Encountered an exception in EntitlementPaginationAction", e); + } + } + + if (!entitlements.isEmpty()) + { + if (useCache) + cached.addAll(entitlements); + last = entitlements.get(entitlements.size() - 1); + lastKey = last.getIdLong(); + } + + request.onSuccess(entitlements); + } + + @Override + protected long getKey(Entitlement it) + { + return it.getIdLong(); + } +}