diff --git a/docs/Change_Log.md b/docs/Change_Log.md index d28f8ae277..e73e50d19c 100644 --- a/docs/Change_Log.md +++ b/docs/Change_Log.md @@ -1,5 +1,29 @@ # Change Log +## Premium Apps: New Premium Button Style & Deep Linking URL Schemes + +#### June 17, 2024 + +**New Premium Button Style** + +Introduces a new `premium` [button style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) to be used with a `sku_id` which points to an active [SKU](#DOCS_MONETIZATION_SKUS/sku-object). This allows developers to customize their premium experience by returning specific subscription or one-time purchase products. + +Learn more about using [button components with interactions](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/buttons). + +> warn +> This change deprecates Interaction Response Type 10 + +The `PREMIUM_REQUIRED (10)` interaction response type is now deprecated in favor of using custom premium buttons. This will continue to function but may be eventually unsupported. It is recommended to migrate your bots to use the more flexible [premium button component](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles). + +Learn more about [gating features with premium interactions](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS/gating-premium-interactions). + +**Deep Linking URL Schemes for SKUs and Store** + +Introduces two new url schemes for linking directly to the Application Directory. When these links are used in chat, they are rendered as rich embeds that users can interact with to launch an app's store or open a SKU detail modal. + +- New [Store URL Scheme](#DOCS_MONETIZATION_MANAGING_YOUR_STORE/linking-to-your-store): `https://discord.com/application-directory/:appID/store` +- New [SKU URL Scheme](#DOCS_MONETIZATION_SKUS/linking-to-your-skus): `https://discord.com/application-directory/:appID/store/:skuID` + ## Auto Moderation Member Profile Rule #### May 31, 2024 @@ -30,7 +54,7 @@ To explore these features, eligibility details, and how to enable monetization f The following were added to our public Monetization documentation with this update: -- New [SKU Object Types](#DOCS_MONETIZATION_SKUS/sku-object-sku-types) +- New [SKU Object Types](#DOCS_MONETIZATION_SKUS/sku-object-sku-types) - New [Entitlement Object Types](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object-entitlement-types) - [Consume an Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/consume-an-entitlement) API endpoint - `consumed` field on the [Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS) resource @@ -44,7 +68,7 @@ Update permissions necessary to modify the `flags` field when calling the [Modif #### April 2, 2024 -For apps with [Monetization](#DOCS_MONETIZATION_OVERVIEW) enabled, we have released the ability to export your SKU analytics to CSV. These exports allow you to use your preferred data tools to report on your premium offerings. +For apps with [Monetization](#DOCS_MONETIZATION_OVERVIEW) enabled, we have released the ability to export your SKU analytics to CSV. These exports allow you to use your preferred data tools to report on your premium offerings. You can find the export at the bottom of the `Monetization → Analytics` tab of your app to export data points such as `sales_count`, `sales_amount`, `sales_currencies`, `cancellation_count`, `refund_amount`, and `refund_count`, aggregated by each of your offerings for the selected month. @@ -67,7 +91,7 @@ This change introduces new concepts and fields across the API that apps will now - [Installation context](#DOCS_RESOURCES_APPLICATION/installation-context) defines how an app was installed: to a user, a guild (server), or both. Currently, apps will default to only support the guild installation context, but the default may change in the future. - Commands can also support one or both installation contexts, with the default being the same as the app's supported installation context(s) at the time of command creation. - [Interaction context](#DOCS_INTERACTIONS_APPLICATION_COMMANDS/interaction-contexts) defines where a command can be used in Discord—within guilds, DM with your app's bot user, and/or within group DMs and DMs other than with your app's bot user. -- The installation flow for apps have been updated so users can select whether they want to install an app to their account or to a server. +- The installation flow for apps have been updated so users can select whether they want to install an app to their account or to a server. **API Fields:** - New `integration_types_config` field for [Applications](#DOCS_RESOURCES_APPLICATION/application-object) include the default scopes and permissions for app's supported installation contexts @@ -135,7 +159,7 @@ To support added controls for expressions and events, new [permissions](#DOCS_TO - `CREATE_GUILD_EXPRESSIONS`: `1 << 43` - `CREATE_EVENTS`: `1 << 44` -These allow for creating new expressions and events, as well as editing and deleting those created by the current user. +These allow for creating new expressions and events, as well as editing and deleting those created by the current user. > warn > These were rolled out in July 2023 to users and roles and have been added to our developer documentation but **are not yet available to app developers**. We will share an update here when these new permissions are available in your apps. @@ -145,17 +169,17 @@ These allow for creating new expressions and events, as well as editing and dele #### What’s Happening? -As outlined in [a blog post earlier this year](https://discord.com/blog/encryption-for-voice-and-video-on-discord), we are experimenting with end-to-end encryption (e2ee) for voice and video channels. +As outlined in [a blog post earlier this year](https://discord.com/blog/encryption-for-voice-and-video-on-discord), we are experimenting with end-to-end encryption (e2ee) for voice and video channels. End-to-end encryption is designed to only allow the participants in a call to decipher its contents. One of the protocols we’re experimenting with is called Messaging Layer Security, which we believe would allow us to deliver end-to-end encryption at scale. Intermediaries, including platforms like Discord, are unable to access the content of communications encrypted with end-to-end encryption. #### How do I prepare for the changes? -During this testing phase, there is nothing developers need to do to support end-to-end encryption. Voice channels will automatically downgrade to documented, non-e2ee protocols when a bot user joins the channel. This is transparent to the connecting client but may result in a slight delay between establishing a connection and receiving audio. +During this testing phase, there is nothing developers need to do to support end-to-end encryption. Voice channels will automatically downgrade to documented, non-e2ee protocols when a bot user joins the channel. This is transparent to the connecting client but may result in a slight delay between establishing a connection and receiving audio. #### What is planned for the future? -We will be continuing our testing and will share updates along with developer documentation and sample code once it is available. +We will be continuing our testing and will share updates along with developer documentation and sample code once it is available. Once this information is published, we will provide developers with a substantial timeframe to implement end-to-end encryption when interacting with voice and video. @@ -179,7 +203,7 @@ Previously, some message edit interaction response actions would use the default ## Premium App Subscriptions Now Available in the EU and UK #### Oct 19, 2023 -Starting today, eligible developers based in EU and UK can now monetize their verified apps with App Subscriptions. [App Subscriptions](#DOCS_MONETIZATION_OVERVIEW) let you to charge your users for premium functionality with a recurring, monthly subscription. +Starting today, eligible developers based in EU and UK can now monetize their verified apps with App Subscriptions. [App Subscriptions](#DOCS_MONETIZATION_OVERVIEW) let you to charge your users for premium functionality with a recurring, monthly subscription. > info > New features for Premium App Subscriptions are documented in the [App Subscriptions overview](#DOCS_MONETIZATION_OVERVIEW) and in [the changelog for the previous App Subscriptions release](#DOCS_CHANGE_LOG/premium-app-subscriptions-available-in-the-us). @@ -189,7 +213,7 @@ To learn more about eligibility details and how to enable monetization for your ## Global Rate Limit added to discordapp.com/* #### Oct 17, 2023 -We have added a global rate limit for API requests made to `discordapp.com/*` and may further restrict requests in the future. +We have added a global rate limit for API requests made to `discordapp.com/*` and may further restrict requests in the future. To limit impact on your app, please make sure you are making calls to `discord.com/*`. @@ -203,7 +227,7 @@ Refer to the [API Reference](https://discord.com/developers/docs/reference) for ## Premium App Subscriptions Available in the US #### Sep 26, 2023 -Starting today, eligible US-based developers can monetize their verified apps with App Subscriptions. [App Subscriptions](#DOCS_MONETIZATION_OVERVIEW) let you to charge your users for premium functionality with a recurring, monthly subscription. +Starting today, eligible US-based developers can monetize their verified apps with App Subscriptions. [App Subscriptions](#DOCS_MONETIZATION_OVERVIEW) let you to charge your users for premium functionality with a recurring, monthly subscription. - Manage subscription SKUs in the Developer Portal - View monetization analytics in the Developer Portal @@ -213,7 +237,7 @@ Starting today, eligible US-based developers can monetize their verified apps wi - [List Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS/list-entitlements) `GET /applications//entitlements` - [Create Test Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/create-test-entitlement) `POST /applications//entitlements` - [Delete Test Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/delete-test-entitlement) `DELETE /applications//entitlements/` -- [Gateway Events](#DOCS_MONETIZATION_ENTITLEMENTS/gateway-events) for working with entitlements: `ENTITLEMENT_CREATE`, `ENTITLEMENT_UPDATE`, `ENTITLEMENT_DELETE` +- [Gateway Events](#DOCS_MONETIZATION_ENTITLEMENTS/gateway-events) for working with entitlements: `ENTITLEMENT_CREATE`, `ENTITLEMENT_UPDATE`, `ENTITLEMENT_DELETE` - New [`PREMIUM_REQUIRED (10)` interaction response type](#DOCS_MONETIZATION_ENTITLEMENTS/premiumrequired-interaction-response) is available to prompt users to upgrade - New `entitlements` field, which is an array of [entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/) objects, available in interaction data payloads when [receiving and responding to interactions](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object-interaction-structure) diff --git a/docs/interactions/Message_Components.md b/docs/interactions/Message_Components.md index a213562288..798737a21f 100644 --- a/docs/interactions/Message_Components.md +++ b/docs/interactions/Message_Components.md @@ -90,21 +90,24 @@ Buttons are interactive components that render in messages. They can be clicked ###### Button Structure -| Field | Type | Description | -|------------|-----------------------------------------------------|-------------------------------------------------------------------------------------| -| type | integer | `2` for a button | -| style | integer | A [button style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) | -| label? | string | Text that appears on the button; max 80 characters | -| emoji? | partial [emoji](#DOCS_RESOURCES_EMOJI/emoji-object) | `name`, `id`, and `animated` | -| custom_id? | string | Developer-defined identifier for the button; max 100 characters | -| url? | string | URL for link-style buttons | -| disabled? | boolean | Whether the button is disabled (defaults to `false`) | +| Field | Type | Description | +|------------|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| type | integer | `2` for a button | +| style | integer | A [button style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) | +| label? | string | Text that appears on the button; max 80 characters | +| emoji? | partial [emoji](#DOCS_RESOURCES_EMOJI/emoji-object) | `name`, `id`, and `animated` | +| custom_id? | string | Developer-defined identifier for the button; max 100 characters | +| sku_id? | snowflake | Identifier for a purchasable [SKU](#DOCS_MONETIZATION_SKUS/sku-object), only available when using premium-style buttons | +| url? | string | URL for link-style buttons | +| disabled? | boolean | Whether the button is disabled (defaults to `false`) | Buttons come in a variety of styles to convey different types of actions. These styles also define what fields are valid for a button. -- Non-link buttons **must** have a `custom_id`, and cannot have a `url` +- Non-link and Non-premium buttons **must** have a `custom_id`, and cannot have a `url` or a `sku_id`. - Link buttons **must** have a `url`, and cannot have a `custom_id` - Link buttons do not send an [interaction](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object) to your app when clicked +- Premium buttons **must** contain a `sku_id`, and cannot have a `custom_id`, `label`, `url`, or `emoji`. +- Premium buttons do not send an [interaction](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object) to your app when clicked ###### Button Styles @@ -115,11 +118,46 @@ Buttons come in a variety of styles to convey different types of actions. These | Success | 3 | green | `custom_id` | | Danger | 4 | red | `custom_id` | | Link | 5 | grey, navigates to a URL | `url` | +| Premium | 6 | blurple | `sku_id` | ![An image showing the different button styles](button-styles.png) When a user clicks on a button, your app will receive an [interaction](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object) including the message the button was on: +### Button Design Guidelines + +###### General Button copy + +- 34 characters max with icon or emoji. +- 38 characters max without icon or emoji. +- Keep text concise and to the point. +- Use clear and easily understandable language. Avoid jargon or overly technical terms. +- Use verbs that indicate the outcome of the action. +- Maintain consistency in language and tone across buttons. +- Anticipate the need for translation, test for expansion or contraction in different languages. + +###### Multiple Buttons + +Use different button styles to create a hierarchy. Use only one `Primary` button per group. + +![Example showing one primary button per button group](multiple-buttons-example-1.png) + +If there are multiple buttons of equal significance, use the `Secondary` button style for all buttons + +![Example showing multiple buttons in a group with equal significance](multiple-buttons-example-2.png) + +###### Premium Buttons + +Premium buttons will automatically have: + +- Shop Icon +- Blurple Background +- SKU name +- SKU price +- 34 character max for this button. Longer titles will be truncated + +![A premium button](premium-button.png) + ### Component Interaction Object ###### Sample Component Interaction diff --git a/docs/interactions/Receiving_and_Responding.md b/docs/interactions/Receiving_and_Responding.md index fb62ff665b..eb6b08f61e 100644 --- a/docs/interactions/Receiving_and_Responding.md +++ b/docs/interactions/Receiving_and_Responding.md @@ -209,22 +209,22 @@ There are a number of ways you can respond to an interaction: ###### Interaction Callback Type -| Name | Value | Description | -|-----------------------------------------|-------|---------------------------------------------------------------------------------------------------------------| -| PONG | 1 | ACK a `Ping` | -| CHANNEL_MESSAGE_WITH_SOURCE | 4 | respond to an interaction with a message | -| DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE | 5 | ACK an interaction and edit a response later, the user sees a loading state | -| DEFERRED_UPDATE_MESSAGE\* | 6 | for components, ACK an interaction and edit the original message later; the user does not see a loading state | -| UPDATE_MESSAGE\* | 7 | for components, edit the message the component was attached to | -| APPLICATION_COMMAND_AUTOCOMPLETE_RESULT | 8 | respond to an autocomplete interaction with suggested choices | -| MODAL\*\* | 9 | respond to an interaction with a popup modal | -| PREMIUM_REQUIRED\*\*\* | 10 | respond to an interaction with an upgrade button, only available for apps with monetization enabled | +| Name | Value | Description | +|-----------------------------------------|-------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| PONG | 1 | ACK a `Ping` | +| CHANNEL_MESSAGE_WITH_SOURCE | 4 | respond to an interaction with a message | +| DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE | 5 | ACK an interaction and edit a response later, the user sees a loading state | +| DEFERRED_UPDATE_MESSAGE\* | 6 | for components, ACK an interaction and edit the original message later; the user does not see a loading state | +| UPDATE_MESSAGE\* | 7 | for components, edit the message the component was attached to | +| APPLICATION_COMMAND_AUTOCOMPLETE_RESULT | 8 | respond to an autocomplete interaction with suggested choices | +| MODAL\*\* | 9 | respond to an interaction with a popup modal | +| PREMIUM_REQUIRED\*\*\* | 10 | [**Deprecated**](#DOCS_CHANGE_LOG/premium-apps-new-premium-button-style-deep-linking-url-schemes); respond to an interaction with an upgrade button, only available for apps with monetization enabled | \* Only valid for [component-based](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/) interactions \*\* Not available for `MODAL_SUBMIT` and `PING` interactions. -\*\*\* Not available for `APPLICATION_COMMAND_AUTOCOMPLETE` and `PING` interactions. +\*\*\* This response type is deprecated. Learn more about [migrating to premium buttons](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS/gating-premium-interactions). `PREMIUM_REQUIRED` response type is not available for `APPLICATION_COMMAND_AUTOCOMPLETE` and `PING` interactions. ###### Interaction Callback Data Structure diff --git a/docs/monetization/App_Subscriptions.md b/docs/monetization/App_Subscriptions.md index ff6c126d5e..b56c60dee1 100644 --- a/docs/monetization/App_Subscriptions.md +++ b/docs/monetization/App_Subscriptions.md @@ -36,6 +36,34 @@ When a user subscribes to your app, there are a few things you will need to impl ### Gating Premium Interactions +Each interaction payload includes an `entitlements` field containing an array of full [entitlement objects](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object). You can use this field to determine if the user or guild is subscribed to your app. If the user or guild is not subscribed and you wish to present them with a means to do so you can use a [button](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/buttons) with a [premium style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) and a `sku_id` attached. You may also use these buttons to present users with options to make a [One-Time Purchase](#DOCS_MONETIZATION_ONE-TIME_PURCHASES). + +```javascript +return new JsonResponse({ + type: 4, // InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE + data: { + content: "This command requires Nelly Premium! Upgrade now to get access to these features!", + components: [{ + type: MessageComponentTypes.ACTION_ROW, + components: [ + { + type: MessageComponentTypes.BUTTON, + style: 6, // ButtonStyleTypes.PREMIUM + skuId: '1234965026943668316', + }, + ], + }] + }, +}); +``` + +![A premium button](premium-button.png) + +#### Type 10 Interaction Response + +> warn +> `PREMIUM_REQUIRED` type 10 interaction response is deprecated. Please use `ButtonStyle.PREMIUM` to handle purchases. + Interactions like [commands](#DOCS_INTERACTIONS_APPLICATION_COMMANDS) commonly respond to users with a message or modal response. If you'd like to make a command only available to users with a subscription, you can reply with a `PREMIUM_REQUIRED` interaction response `type: 10`. Users without a subscription will be prompted to upgrade when they attempt to use these commands. ```javascript @@ -94,4 +122,4 @@ After checkout, you will have a live subscription that includes a `starts_at` an Once an app has made its first $100 it will become eligible for payout. A review will be conducted and if everything looks good, your team will begin to receive payouts. -For more information, read the [Premium Apps Payouts](https://support-dev.discord.com/hc/articles/17299902720919) Help Center article. \ No newline at end of file +For more information, read the [Premium Apps Payouts](https://support-dev.discord.com/hc/articles/17299902720919) Help Center article. diff --git a/docs/monetization/Managing_Your_Store.md b/docs/monetization/Managing_Your_Store.md index 0e92412bf2..012196d790 100644 --- a/docs/monetization/Managing_Your_Store.md +++ b/docs/monetization/Managing_Your_Store.md @@ -50,3 +50,14 @@ Currently, you can only have one active App Subscription SKU for your app. If yo As you build out your One-Time Purchase SKUs, you can add as many durable and consumable items to your Store as needed by your app. ![Items in your Store View](premium-items.png) + +## Linking To Your Store + +You can link directly to your Store using our Application Directory Store URL scheme: + +`https://discord.com/application-directory/:appID/store` + +- When used in chat, it will render as a rich embed that allows users to launch a modal to your Store +- When used as a direct URL in a browser, it will take the user to your store in the Application Directory on web + +![Embed for direct link to Store](store_embed.png) \ No newline at end of file diff --git a/docs/monetization/SKUs.md b/docs/monetization/SKUs.md index 0f8dca490e..1ea0013117 100644 --- a/docs/monetization/SKUs.md +++ b/docs/monetization/SKUs.md @@ -112,6 +112,17 @@ From then on, we'll send you daily dashboard emails containing information about Congratulations on going live! 🥳 +## Linking to your SKUs + +You can link directly to a specific SKU using our Application Directory Store URL scheme: + +`https://discord.com/application-directory/:appID/store/:skuID` + +- When used in chat, it will render as a rich embed that allows users to launch a modal to view either the SKU details or checkout flow +- When used as a direct URL in a browser, it will take the user to your product in the Application Directory on web + +![Embed for direct link to SKU](sku_embed.png) + ## List SKUs % GET /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/skus Returns all SKUs for a given application. diff --git a/images/button-styles.png b/images/button-styles.png index 7480e1da90..f89e6e82ab 100644 Binary files a/images/button-styles.png and b/images/button-styles.png differ diff --git a/images/multiple-buttons-example-1.png b/images/multiple-buttons-example-1.png new file mode 100644 index 0000000000..fe8acdd25f Binary files /dev/null and b/images/multiple-buttons-example-1.png differ diff --git a/images/multiple-buttons-example-2.png b/images/multiple-buttons-example-2.png new file mode 100644 index 0000000000..f646978dc0 Binary files /dev/null and b/images/multiple-buttons-example-2.png differ diff --git a/images/premium-button.png b/images/premium-button.png new file mode 100644 index 0000000000..8f566c20b2 Binary files /dev/null and b/images/premium-button.png differ diff --git a/images/sku_embed.png b/images/sku_embed.png new file mode 100644 index 0000000000..1e9c198bc0 Binary files /dev/null and b/images/sku_embed.png differ diff --git a/images/store_embed.png b/images/store_embed.png new file mode 100644 index 0000000000..315d14511a Binary files /dev/null and b/images/store_embed.png differ