Skip to content

Commit

Permalink
Add support for premium app subscriptions (#2583)
Browse files Browse the repository at this point in the history
- New gateway events
- New interaction response type
- Contextual entitlement information in interactions
  • Loading branch information
Giuliopime authored Apr 6, 2024
1 parent 398c23d commit c3b85d9
Show file tree
Hide file tree
Showing 36 changed files with 1,194 additions and 31 deletions.
11 changes: 11 additions & 0 deletions src/main/java/net/dv8tion/jda/api/JDA.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1883,6 +1884,16 @@ default List<RichCustomEmoji> getEmojisByName(@Nonnull String name, boolean igno
@CheckReturnValue
RestAction<ApplicationInfo> 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.
* <br>To use slash commands you must add {@code "applications.commands"} to these scopes. The scope {@code "bot"} is always applied.
Expand Down
188 changes: 188 additions & 0 deletions src/main/java/net/dv8tion/jda/api/entities/Entitlement.java
Original file line number Diff line number Diff line change
@@ -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 <a href="https://discord.com/developers/docs/monetization/entitlements" target="_blank">Discord Docs about Entitlements</a>
*/
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
* <br>The only possible type of Entitlement currently is {@link EntitlementType#APPLICATION_SUBSCRIPTION}
* <br>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.
* <br>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;
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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:
* <ul>
* <li>Discord issues a refund for a subscription; or</li>
* <li>Discord removes an {@link Entitlement Entitlement} via internal tooling</li>
* </ul>
*
* @see #getEntitlement()
* @see EntitlementUpdateEvent
*/
public class EntitlementDeleteEvent extends GenericEntitlementEvent
{
public EntitlementDeleteEvent(@Nonnull JDA api, long responseNumber, @Nonnull Entitlement entitlement)
{
super(api, responseNumber, entitlement);
}
}
Original file line number Diff line number Diff line change
@@ -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.
*
* <p><b>Notice</b><br>
* 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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Loading

0 comments on commit c3b85d9

Please sign in to comment.