diff --git a/src/main/java/net/dv8tion/jda/api/JDA.java b/src/main/java/net/dv8tion/jda/api/JDA.java index 37554db900..dc77c601b9 100644 --- a/src/main/java/net/dv8tion/jda/api/JDA.java +++ b/src/main/java/net/dv8tion/jda/api/JDA.java @@ -27,6 +27,8 @@ import net.dv8tion.jda.api.entities.emoji.CustomEmoji; import net.dv8tion.jda.api.entities.emoji.RichCustomEmoji; import net.dv8tion.jda.api.entities.sticker.*; +import net.dv8tion.jda.api.requests.restaction.pagination.SubscriptionPaginationAction; +import net.dv8tion.jda.internal.entities.subscription.Subscription; import net.dv8tion.jda.api.events.GenericEvent; import net.dv8tion.jda.api.hooks.IEventManager; import net.dv8tion.jda.api.interactions.commands.Command; @@ -2122,6 +2124,51 @@ default RestAction deleteTestEntitlement(@Nonnull String entitlementId) @CheckReturnValue RestAction deleteTestEntitlement(long entitlementId); + /** + * Retrieves a List of {@link Subscription} by SKU id + * + * @param skuId + * The SKU id of the List + * + * @return {@link SubscriptionPaginationAction} + */ + @Nonnull + @CheckReturnValue + SubscriptionPaginationAction retrieveSubscriptionsBySkuId(@Nonnull SkuSnowflake skuId); + + /** + * Retrieves a {@link Subscription} by its id and SKU id + * + * @param skuId + * The SKU id of the List where to find subscription + * @param subscriptionId + * The String id of the subscription to retrieve + * + * @return {@link RestAction} - Type: {@link Subscription} + *
The Subscription with the provided id + */ + @Nonnull + @CheckReturnValue + default RestAction retrieveSubscriptionBySkuId(@Nonnull SkuSnowflake skuId, @Nonnull String subscriptionId) + { + return retrieveSubscriptionBySkuId(skuId, MiscUtil.parseSnowflake(subscriptionId)); + } + + /** + * Retrieves a {@link Subscription} by its id and SKU id + * + * @param skuId + * The SKU id of the List where to find subscription + * @param subscriptionId + * The id of the subscription to retrieve + * + * @return {@link RestAction} - Type: {@link Subscription} + *
The Subscription with the provided id + */ + @Nonnull + @CheckReturnValue + RestAction retrieveSubscriptionBySkuId(@Nonnull SkuSnowflake skuId, long subscriptionId); + /** * 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/events/subscription/GenericSubscriptionEvent.java b/src/main/java/net/dv8tion/jda/api/events/subscription/GenericSubscriptionEvent.java new file mode 100644 index 0000000000..06a84a2141 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/subscription/GenericSubscriptionEvent.java @@ -0,0 +1,36 @@ +package net.dv8tion.jda.api.events.subscription; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.internal.entities.subscription.Subscription; +import net.dv8tion.jda.api.events.Event; + +import javax.annotation.Nonnull; + +/** + * Indicates that an {@link Subscription Subscription} was either created, updated, or deleted + * + * @see SubscriptionCreateEvent + * @see SubscriptionUpdateEvent + * @see SubscriptionDeleteEvent + */ +public abstract class GenericSubscriptionEvent extends Event +{ + protected final Subscription subscription; + + protected GenericSubscriptionEvent(@Nonnull JDA api, long responseNumber, @Nonnull Subscription subscription) + { + super(api, responseNumber); + this.subscription = subscription; + } + + /** + * The {@link Subscription} + * + * @return The {@link Subscription} + */ + @Nonnull + public Subscription getSubscription() + { + return subscription; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionCreateEvent.java new file mode 100644 index 0000000000..a0df272fba --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionCreateEvent.java @@ -0,0 +1,15 @@ +package net.dv8tion.jda.api.events.subscription; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.internal.entities.subscription.Subscription; + +/** + * Indicate that a Subscription for Premium app was created + */ +public class SubscriptionCreateEvent extends GenericSubscriptionEvent +{ + public SubscriptionCreateEvent(JDA api, long responseNumber, Subscription subscription) + { + super(api, responseNumber, subscription); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionDeleteEvent.java b/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionDeleteEvent.java new file mode 100644 index 0000000000..e424d95353 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionDeleteEvent.java @@ -0,0 +1,16 @@ +package net.dv8tion.jda.api.events.subscription; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.internal.entities.subscription.Subscription; +import org.jetbrains.annotations.NotNull; + +/** + * Indicate that a Subscription for Premium app was deleted + */ +public class SubscriptionDeleteEvent extends GenericSubscriptionEvent +{ + public SubscriptionDeleteEvent(@NotNull JDA api, long responseNumber, @NotNull Subscription subscription) + { + super(api, responseNumber, subscription); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionUpdateEvent.java b/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionUpdateEvent.java new file mode 100644 index 0000000000..bace07b1c5 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/subscription/SubscriptionUpdateEvent.java @@ -0,0 +1,16 @@ +package net.dv8tion.jda.api.events.subscription; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.internal.entities.subscription.Subscription; +import org.jetbrains.annotations.NotNull; + +/** + * Indicates that a Subscription for Premium app was updated + */ +public class SubscriptionUpdateEvent extends GenericSubscriptionEvent +{ + public SubscriptionUpdateEvent(@NotNull JDA api, long responseNumber, @NotNull Subscription subscription) + { + super(api, responseNumber, subscription); + } +} 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 f667acbfe3..cc02a4d6da 100644 --- a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java +++ b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java @@ -79,6 +79,10 @@ import net.dv8tion.jda.api.events.sticker.GuildStickerAddedEvent; import net.dv8tion.jda.api.events.sticker.GuildStickerRemovedEvent; import net.dv8tion.jda.api.events.sticker.update.*; +import net.dv8tion.jda.api.events.subscription.GenericSubscriptionEvent; +import net.dv8tion.jda.api.events.subscription.SubscriptionCreateEvent; +import net.dv8tion.jda.api.events.subscription.SubscriptionUpdateEvent; +import net.dv8tion.jda.api.events.subscription.SubscriptionDeleteEvent; import net.dv8tion.jda.api.events.thread.GenericThreadEvent; import net.dv8tion.jda.api.events.thread.ThreadHiddenEvent; import net.dv8tion.jda.api.events.thread.ThreadRevealedEvent; @@ -371,6 +375,11 @@ public void onGuildStickerUpdateTags(@Nonnull GuildStickerUpdateTagsEvent event) public void onGuildStickerUpdateDescription(@Nonnull GuildStickerUpdateDescriptionEvent event) {} public void onGuildStickerUpdateAvailable(@Nonnull GuildStickerUpdateAvailableEvent event) {} + //Subscription events + public void onSubscriptionCreate(@Nonnull SubscriptionCreateEvent event) {} + public void onSubscriptionUpdate(@Nonnull SubscriptionUpdateEvent event) {} + public void onSubscriptionDelete(@Nonnull SubscriptionDeleteEvent event) {} + // Entitlement events public void onEntitlementCreate(@Nonnull EntitlementCreateEvent event) {} public void onEntitlementUpdate(@Nonnull EntitlementUpdateEvent event) {} @@ -420,6 +429,7 @@ public void onGenericScheduledEventGateway(@Nonnull GenericScheduledEventGateway public void onGenericScheduledEventUser(@Nonnull GenericScheduledEventUserEvent event) {} public void onGenericForumTag(@Nonnull GenericForumTagEvent event) {} public void onGenericForumTagUpdate(@Nonnull GenericForumTagUpdateEvent event) {} + public void onGenericSubscription(@Nonnull GenericSubscriptionEvent event) {} private static final MethodHandles.Lookup lookup = MethodHandles.lookup(); private static final ConcurrentMap, MethodHandle> methods = new ConcurrentHashMap<>(); 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 a7578c6ee9..46cb59c240 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/Route.java +++ b/src/main/java/net/dv8tion/jda/api/requests/Route.java @@ -102,6 +102,12 @@ public static class Users public static final Route GET_USER = new Route(GET, "users/{user_id}"); } + public static class Sku + { + public static final Route GET_SUBSCRIPTIONS = new Route(GET, "skus/{sku.id}/subscriptions"); + public static final Route GET_SUBSCRIPTION = new Route(GET, "skus/{sku.id}/subscriptions/{subscription_id}"); + } + public static class Guilds { public static final Route GET_GUILD = new Route(GET, "guilds/{guild_id}"); diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/pagination/SubscriptionPaginationAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/pagination/SubscriptionPaginationAction.java new file mode 100644 index 0000000000..74940a8458 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/pagination/SubscriptionPaginationAction.java @@ -0,0 +1,40 @@ +package net.dv8tion.jda.api.requests.restaction.pagination; + +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.UserSnowflake; +import net.dv8tion.jda.internal.entities.subscription.Subscription; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * {@link PaginationAction PaginationAction} that paginates over + * {@link Subscription Subscriptions} returned from the + * List SKU Subscriptions endpoint. + *
This action allows retrieval of subscriptions for a specific SKU, optionally filtered by a user. + * + *

Use {@link #user(UserSnowflake)} to limit results to a specific user, or {@code null} to remove the filter. + *
Results are ordered according to {@link PaginationOrder} and support typical pagination + * parameters such as {@link #limit(int)} and {@link #cache(boolean)}. + * + * @see PaginationAction + * @see Subscription + */ +public interface SubscriptionPaginationAction extends PaginationAction +{ + + /** + * Filter {@link Subscription Subscription}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 SubscriptionPaginationAction SubscriptionPaginationAction} for chaining convenience + */ + @Nonnull + @CheckReturnValue + SubscriptionPaginationAction user(@Nullable UserSnowflake user); +} diff --git a/src/main/java/net/dv8tion/jda/internal/JDAImpl.java b/src/main/java/net/dv8tion/jda/internal/JDAImpl.java index 3a4267765d..c834219a3f 100644 --- a/src/main/java/net/dv8tion/jda/internal/JDAImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/JDAImpl.java @@ -35,6 +35,8 @@ import net.dv8tion.jda.api.entities.sticker.StickerPack; import net.dv8tion.jda.api.entities.sticker.StickerSnowflake; import net.dv8tion.jda.api.entities.sticker.StickerUnion; +import net.dv8tion.jda.api.requests.restaction.pagination.SubscriptionPaginationAction; +import net.dv8tion.jda.internal.entities.subscription.Subscription; import net.dv8tion.jda.api.events.GatewayPingEvent; import net.dv8tion.jda.api.events.GenericEvent; import net.dv8tion.jda.api.events.StatusChangeEvent; @@ -75,6 +77,7 @@ import net.dv8tion.jda.internal.requests.*; import net.dv8tion.jda.internal.requests.restaction.*; import net.dv8tion.jda.internal.requests.restaction.pagination.EntitlementPaginationActionImpl; +import net.dv8tion.jda.internal.requests.restaction.pagination.SubscriptionPaginationActionImpl; import net.dv8tion.jda.internal.utils.*; import net.dv8tion.jda.internal.utils.Helpers; import net.dv8tion.jda.internal.utils.cache.AbstractCacheView; @@ -1257,11 +1260,25 @@ public EntitlementPaginationAction retrieveEntitlements() @Nonnull @Override - public RestAction retrieveEntitlementById(long entitlementId) + public RestAction retrieveEntitlementById(@Nonnull long entitlementId) { return new RestActionImpl<>(this, Route.Applications.GET_ENTITLEMENT.compile(getSelfUser().getApplicationId(), Long.toUnsignedString(entitlementId))); } + @Nonnull + @Override + public SubscriptionPaginationAction retrieveSubscriptionsBySkuId(@Nonnull SkuSnowflake skuId) + { + return new SubscriptionPaginationActionImpl(this, skuId.getId()); + } + + @Nonnull + @Override + public RestAction retrieveSubscriptionBySkuId(@Nonnull SkuSnowflake skuId, @Nonnull long subscriptionId) + { + return new RestActionImpl<>(this, Route.Sku.GET_SUBSCRIPTION.compile(Long.toUnsignedString(skuId.getIdLong()), Long.toUnsignedString(subscriptionId))); + } + @Nonnull @Override public TestEntitlementCreateAction createTestEntitlement(long skuId, long ownerId, @Nonnull TestEntitlementCreateActionImpl.OwnerType ownerType) 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 14bb7e5189..f4ca7e7a87 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java @@ -48,6 +48,9 @@ import net.dv8tion.jda.api.entities.messages.MessagePoll; import net.dv8tion.jda.api.entities.messages.MessageSnapshot; import net.dv8tion.jda.api.entities.sticker.*; +import net.dv8tion.jda.internal.entities.subscription.Subscription; +import net.dv8tion.jda.internal.entities.subscription.SubscriptionImpl; +import net.dv8tion.jda.internal.entities.subscription.SubscriptionStatus; import net.dv8tion.jda.api.entities.templates.Template; import net.dv8tion.jda.api.entities.templates.TemplateChannel; import net.dv8tion.jda.api.entities.templates.TemplateGuild; @@ -392,7 +395,8 @@ public GuildImpl createGuild(long guildId, DataObject guildJson, TLongObjectMap< LOG.error("Guild is missing a SelfMember. GuildId: {}", guildId); LOG.debug("Guild is missing a SelfMember. GuildId: {} JSON: \n{}", guildId, guildJson); // This is actually a gateway request - guildObj.retrieveMembersByIds(api.getSelfUser().getIdLong()).onSuccess(m -> { + guildObj.retrieveMembersByIds(api.getSelfUser().getIdLong()).onSuccess(m -> + { if (m.isEmpty()) LOG.warn("Was unable to recover SelfMember for guild with id {}. This guild might be corrupted!", guildId); else @@ -2613,6 +2617,41 @@ public Entitlement createEntitlement(DataObject object) ); } + public Subscription createSubscription(DataObject object) + { + DataArray skuIDs = object.getArray("sku_ids"); + DataArray entitlementsIDs = object.getArray("entitlement_ids"); + DataArray renewalSkuIDs = object.optArray("renewal_sku_ids").orElse(null); + OffsetDateTime canceledAt = object.getOffsetDateTime("canceled_at", null); + + + List mappedSkuIds = mapToLongList(skuIDs); + List mappedEntitlementsIds = mapToLongList(entitlementsIDs); + List mappedRenewalSkuIds = Optional.ofNullable(renewalSkuIDs) + .map(this::mapToLongList) + .orElse(null); + + + return new SubscriptionImpl( + object.getUnsignedLong("id"), + object.getUnsignedLong("user_id"), + mappedSkuIds, + mappedEntitlementsIds, + mappedRenewalSkuIds, + object.getOffsetDateTime("current_period_start"), + object.getOffsetDateTime("current_period_end"), + canceledAt, + SubscriptionStatus.fromKey(object.getInt("status")) + ); + } + + public List mapToLongList(DataArray dataArray) + { + return IntStream.range(0, dataArray.length()) + .mapToObj(dataArray::getLong) + .collect(Collectors.toList()); + } + 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/subscription/Subscription.java b/src/main/java/net/dv8tion/jda/internal/entities/subscription/Subscription.java new file mode 100644 index 0000000000..8c3eac1f6b --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/subscription/Subscription.java @@ -0,0 +1,131 @@ +package net.dv8tion.jda.internal.entities.subscription; + +import net.dv8tion.jda.api.entities.ISnowflake; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.OffsetDateTime; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Representation of a Discord Subscription + * + * @see Discord Docs about Subscriptions + */ +public interface Subscription extends ISnowflake +{ + /** + * The user who subscribed + * + * @return a use who subscribed + */ + @Nonnull + long getSubscriberIdLong(); + + /** + * The user who subscribed + * + * @return a use who subscribed + */ + @Nonnull + default String getSubscriberId() + { + return Long.toUnsignedString(getSubscriberIdLong()); + } + + /** + * The SKU id's related to this + * + * @return The list of sku id's related to this {@link Subscription} + */ + @Nonnull + List getSkuIdsLong(); + + /** + * The SKU id's related to this + * + * @return The list sku id's related to this {@link Subscription} + */ + @Nonnull + default List getSkuIds() + { + return getSkuIdsLong().stream() + .map(Long::toUnsignedString) + .collect(Collectors.toList()); + } + + /** + * The entitlements id's related to this {@link Subscription} + * + * @return The sku id's related to this {@link Subscription} + */ + @Nonnull + List getEntitlementIdsLong(); + + /** + * The entitlements id's related to this {@link Subscription} + * + * @return The entitlements id's related to this {@link Subscription} + */ + @Nonnull + default List getEntitlementIds() + { + return getEntitlementIdsLong().stream() + .map(Long::toUnsignedString) + .collect(Collectors.toList()); + } + + /** + * The renewal SKU id's related to this {@link Subscription} + * + * @return The renewal sku id's related to this {@link Subscription} + */ + @Nullable + List getRenewalSkuIdsLong(); + + /** + * The renewal SKU id's related to this {@link Subscription} + * + * @return The renewal sku id's related to this {@link Subscription} + */ + @Nullable + default List getRenewalSkuIds() + { + return getRenewalSkuIdsLong().stream() + .map(Long::toUnsignedString) + .collect(Collectors.toList()); + } + + /** + * The start of period of this {@link Subscription} + * + * @return The start of period of this {@link Subscription} + */ + @Nonnull + OffsetDateTime getCurrentPeriodStart(); + + /** + * The end of period of this {@link Subscription} + * + * @return The end of period of this {@link Subscription} + */ + @Nonnull + OffsetDateTime getCurrentPeriodEnd(); + + /** + * The canceled time of this {@link Subscription} + * + * @return The canceled time of this {@link Subscription} + */ + @Nullable + OffsetDateTime getCanceledAt(); + + /** + * The status of this {@link Subscription} + * + * @return The status of this {@link Subscription} + */ + @Nonnull + SubscriptionStatus getStatus(); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/subscription/SubscriptionImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/subscription/SubscriptionImpl.java new file mode 100644 index 0000000000..c67163c4b2 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/subscription/SubscriptionImpl.java @@ -0,0 +1,111 @@ +package net.dv8tion.jda.internal.entities.subscription; + +import net.dv8tion.jda.internal.utils.EntityString; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.OffsetDateTime; +import java.util.List; + + +public class SubscriptionImpl implements Subscription +{ + private final long id; + private final long subscriberId; + private final List skuIDs; + private final List entitlementIDs; + private final List renewalSkuIDs; + private final OffsetDateTime currentPeriodStart; + private final OffsetDateTime currentPeriodEnd; + private final OffsetDateTime canceledAt; + private final SubscriptionStatus status; + + public SubscriptionImpl(final long id, final long subscriberId, @Nonnull final List skuIDs, + @Nonnull final List entitlementIDs, @Nullable final List renewalSkuIDs, + @Nonnull final OffsetDateTime currentPeriodStart, @Nonnull final OffsetDateTime currentPeriodEnd, @Nullable final OffsetDateTime canceledAt, + @Nonnull final SubscriptionStatus status) + { + + this.id = id; + this.subscriberId = subscriberId; + this.skuIDs = skuIDs; + this.entitlementIDs = entitlementIDs; + this.renewalSkuIDs = renewalSkuIDs; + this.currentPeriodStart = currentPeriodStart; + this.currentPeriodEnd = currentPeriodEnd; + this.canceledAt = canceledAt; + this.status = status; + } + + @Override + @Nonnull public long getIdLong() + { + return id; + } + + public @Nonnull long getSubscriberIdLong() + { + return subscriberId; + } + + public @Nonnull List getSkuIdsLong() + { + return skuIDs; + } + + public @Nonnull List getEntitlementIdsLong() + { + return entitlementIDs; + } + + public @Nullable List getRenewalSkuIdsLong() + { + return renewalSkuIDs; + } + + public @Nonnull OffsetDateTime getCurrentPeriodStart() + { + return currentPeriodStart; + } + + public @Nonnull OffsetDateTime getCurrentPeriodEnd() + { + return currentPeriodEnd; + } + + public @Nullable OffsetDateTime getCanceledAt() + { + return canceledAt; + } + + public @Nonnull SubscriptionStatus getStatus() + { + return status; + } + + @Override + public int hashCode() + { + return Long.hashCode(id); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (!(obj instanceof SubscriptionImpl)) + return false; + + SubscriptionImpl other = (SubscriptionImpl) obj; + return other.id == this.id; + } + + @Override + public String toString() + { + return new EntityString(this) + .addMetadata("id", id) + .toString(); + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/subscription/SubscriptionStatus.java b/src/main/java/net/dv8tion/jda/internal/entities/subscription/SubscriptionStatus.java new file mode 100644 index 0000000000..ca54166b98 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/subscription/SubscriptionStatus.java @@ -0,0 +1,45 @@ +package net.dv8tion.jda.internal.entities.subscription; + +import javax.annotation.Nonnull; + +/** + * Representation of a Discord Subscription Status + * + * @see Discord Docs about Subscription Statuses + */ +public enum SubscriptionStatus +{ + UNKNOWN(-1), ACTIVE(0), ENDING(1), INACTIVE(2); + + private final int id; + + SubscriptionStatus(int id) + { + this.id = id; + } + + /** + * Gets the Subscription status related to the provided key. + *
If an unknown key is provided, this returns {@link #UNKNOWN} + * + * @param key + * The Discord key referencing a Subscription status. + * + * @return The Subscription status that has the key provided, or {@link #UNKNOWN} for unknown key. + */ + @Nonnull + public static SubscriptionStatus fromKey(int key) + { + for (SubscriptionStatus status : values()) + { + if (status.id == key) + return status; + } + return UNKNOWN; + } + + public int getId() + { + return id; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionCreateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionCreateHandler.java new file mode 100644 index 0000000000..4f301e3a39 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionCreateHandler.java @@ -0,0 +1,20 @@ +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.events.subscription.SubscriptionCreateEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; + +public class SubscriptionCreateHandler extends SocketHandler +{ + public SubscriptionCreateHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + getJDA().handleEvent(new SubscriptionCreateEvent(getJDA(), responseNumber, getJDA().getEntityBuilder().createSubscription(content))); + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionDeleteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionDeleteHandler.java new file mode 100644 index 0000000000..13239ff439 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionDeleteHandler.java @@ -0,0 +1,20 @@ +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.events.subscription.SubscriptionDeleteEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; + +public class SubscriptionDeleteHandler extends SocketHandler +{ + public SubscriptionDeleteHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + getJDA().handleEvent(new SubscriptionDeleteEvent(getJDA(), responseNumber, getJDA().getEntityBuilder().createSubscription(content))); + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionUpdateHandler.java new file mode 100644 index 0000000000..bdacdafd5f --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/SubscriptionUpdateHandler.java @@ -0,0 +1,20 @@ +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.events.subscription.SubscriptionUpdateEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; + +public class SubscriptionUpdateHandler extends SocketHandler +{ + public SubscriptionUpdateHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + getJDA().handleEvent(new SubscriptionUpdateEvent(getJDA(), responseNumber, getJDA().getEntityBuilder().createSubscription(content))); + return null; + } +} 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 401bcbf683..5b91aeaaa3 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java @@ -1374,6 +1374,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("SUBSCRIPTION_CREATE", new SubscriptionCreateHandler(api)); + handlers.put("SUBSCRIPTION_UPDATE", new SubscriptionUpdateHandler(api)); + handlers.put("SUBSCRIPTION_DELETE", new SubscriptionDeleteHandler(api)); handlers.put("ENTITLEMENT_CREATE", new EntitlementCreateHandler(api)); handlers.put("ENTITLEMENT_UPDATE", new EntitlementUpdateHandler(api)); handlers.put("ENTITLEMENT_DELETE", new EntitlementDeleteHandler(api)); diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/pagination/SubscriptionPaginationActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/pagination/SubscriptionPaginationActionImpl.java new file mode 100644 index 0000000000..1babd3da64 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/pagination/SubscriptionPaginationActionImpl.java @@ -0,0 +1,97 @@ +package net.dv8tion.jda.internal.requests.restaction.pagination; + +import net.dv8tion.jda.api.JDA; +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.SubscriptionPaginationAction; +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.entities.subscription.Subscription; +import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +public class SubscriptionPaginationActionImpl + extends PaginationActionImpl + implements SubscriptionPaginationAction +{ + protected long userId; + + public SubscriptionPaginationActionImpl(JDA api, String skuId) + { + super(api, Route.Sku.GET_SUBSCRIPTIONS.compile(skuId),1,100,100); + this.userId = 0; + } + + @Nonnull + @Override + public EnumSet getSupportedOrders() + { + return EnumSet.of(PaginationOrder.BACKWARD, PaginationOrder.FORWARD); + } + + @Nonnull + @Override + public SubscriptionPaginationAction user(@Nullable UserSnowflake user) + { + if (user == null) + userId = 0; + else + userId = user.getIdLong(); + return this; + } + + @Override + protected Route.CompiledRoute finalizeRoute() + { + Route.CompiledRoute route = super.finalizeRoute(); + + if(userId != 0) + route = route.withQueryParams("user_id",Long.toUnsignedString(userId)); + + return route; + } + + @Override + protected void handleSuccess(Response response, Request> request) + { + DataArray array = response.getArray(); + List subscriptions = new ArrayList<>(array.length()); + EntityBuilder builder = api.getEntityBuilder(); + + for(int i = 0; i < array.length(); i++) + { + try + { + DataObject object = array.getObject(i); + Subscription subscription = builder.createSubscription(object); + subscriptions.add(subscription); + }catch (ParsingException | NullPointerException e) + { + LOG.warn("Encountered an exception in SubscriptionPaginationAction", e); + } + } + if(!subscriptions.isEmpty()) + { + if(useCache) + cached.addAll(subscriptions); + last = subscriptions.get(subscriptions.size() - 1); + lastKey = last.getIdLong(); + } + + request.onSuccess(subscriptions); + } + + @Override + protected long getKey(Subscription it) + { + return it.getIdLong(); + } +}