From 43b85c0b1c83be63d2bfdcaf1ae7f2f90d4d5061 Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Mon, 13 Jan 2025 15:55:25 -0500 Subject: [PATCH 1/7] [guides] add Prompting Users to Share Incentivized Links Guide --- docs/activities/Development_Guides.mdx | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/activities/Development_Guides.mdx b/docs/activities/Development_Guides.mdx index dadec5c8a6..fe4516c3b7 100644 --- a/docs/activities/Development_Guides.mdx +++ b/docs/activities/Development_Guides.mdx @@ -96,6 +96,13 @@ These guides include suggested development practices, SDK commands, and user flo +## Links + + + Have your users share links to your activity, with tracking and incentives. + + + ## Assets & Metadata @@ -879,6 +886,35 @@ This example is being done entirely on the client, however, a more common patter --- +### Prompting Users to Share Incentivized Links +Virality is a valuable way to grow your userbase and your application. In order to leverage network effects, we suggest using our SDK's `shareLink` command to prompt users to share so-called "incentivized links" and receive rewards for sharing. + +An example reward would be something like free coins (or any other in-game resource) for users who click the link and for those who shared the link. + +To share the link, use `shareLink`. +```javascript +// custom ID creation, persistence, and resolution is up to you as a developer +const customId = await createPromotionalCustomId(); + +const { success } = await DiscordRPC.commands.shareLink({ + message: 'Click this link to redeem 5 free coins!', + custom_id: customId, +}); +success ? console.log('User shared link!') : console.log('User did not share link!'); +``` +Calling `shareLink` will prompt the user with a modal to share the link. The `success` returned indicates if the link was shared or copied. Note that we did not add a `referrer_id` in this example, as the user ID will automatically be appended as a referrer if left empty. + +So now that the initial user has shared a link, what happens when their friend receives the message and clicks the link? +Clicking the link (or Play from the Embed) will launch the activity and pass the `customId` and `referredId` to the SDK. From there you can resolve the IDs and grant the rewards as promised. + +```javascript +// for illustrative purposes -- this must be implemented by you as a developer +await resolvePromotion({ + customId: DiscordRPC.customId, // your promotional ID, which corresponds to granting reward (coins) + refererId: DiscordRPC.referredId, // the user ID of the initial user who shared the link +}); +``` + ### Preventing unwanted activity sessions Activities are surfaced through iframes in the Discord app. The activity website itself is publicly reachable at `.discordsays.com`. Activities will expect to be able to communicate with Discord's web or mobile client via the Discord SDK's RPC protocol. If a user loads the activity's website in a normal browser, the Discord RPC server will not be present, and the activity will likely fail in some way. From 12a2c02f72402c0462699a83cd009d88ef58f90d Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Mon, 13 Jan 2025 15:57:34 -0500 Subject: [PATCH 2/7] slight clarification on auto referredId --- docs/activities/Development_Guides.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/activities/Development_Guides.mdx b/docs/activities/Development_Guides.mdx index fe4516c3b7..2e9c691e37 100644 --- a/docs/activities/Development_Guides.mdx +++ b/docs/activities/Development_Guides.mdx @@ -902,7 +902,7 @@ const { success } = await DiscordRPC.commands.shareLink({ }); success ? console.log('User shared link!') : console.log('User did not share link!'); ``` -Calling `shareLink` will prompt the user with a modal to share the link. The `success` returned indicates if the link was shared or copied. Note that we did not add a `referrer_id` in this example, as the user ID will automatically be appended as a referrer if left empty. +Calling `shareLink` will prompt the user with a modal to share the link. The `success` returned indicates if the link was shared or copied. Note that we did not add a `referrer_id` in this example, as the user ID of the user sharing the link will automatically be appended as a referrer if left empty. So now that the initial user has shared a link, what happens when their friend receives the message and clicks the link? Clicking the link (or Play from the Embed) will launch the activity and pass the `customId` and `referredId` to the SDK. From there you can resolve the IDs and grant the rewards as promised. From 43381bfa405959d35b52e67e892cbfa305fe87b7 Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Mon, 13 Jan 2025 15:59:03 -0500 Subject: [PATCH 3/7] another copy tweak --- docs/activities/Development_Guides.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/activities/Development_Guides.mdx b/docs/activities/Development_Guides.mdx index 2e9c691e37..20504d7b2e 100644 --- a/docs/activities/Development_Guides.mdx +++ b/docs/activities/Development_Guides.mdx @@ -905,7 +905,7 @@ success ? console.log('User shared link!') : console.log('User did not share lin Calling `shareLink` will prompt the user with a modal to share the link. The `success` returned indicates if the link was shared or copied. Note that we did not add a `referrer_id` in this example, as the user ID of the user sharing the link will automatically be appended as a referrer if left empty. So now that the initial user has shared a link, what happens when their friend receives the message and clicks the link? -Clicking the link (or Play from the Embed) will launch the activity and pass the `customId` and `referredId` to the SDK. From there you can resolve the IDs and grant the rewards as promised. +Clicking the link (or Play from the Embed) will launch the activity and pass the `customId` and `referredId` to the SDK. Once launched, the SDK will expose the `customId` and `refererId` and you can resolve the IDs and grant the rewards as promised. ```javascript // for illustrative purposes -- this must be implemented by you as a developer From c0f07ad5a1ef8792a27974333f2829c6b1994239 Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Mon, 13 Jan 2025 17:13:57 -0500 Subject: [PATCH 4/7] rework for clarity, add sections --- docs/activities/Development_Guides.mdx | 87 +++++++++++++++++++++----- 1 file changed, 70 insertions(+), 17 deletions(-) diff --git a/docs/activities/Development_Guides.mdx b/docs/activities/Development_Guides.mdx index 20504d7b2e..c1eff935f9 100644 --- a/docs/activities/Development_Guides.mdx +++ b/docs/activities/Development_Guides.mdx @@ -887,34 +887,87 @@ This example is being done entirely on the client, however, a more common patter --- ### Prompting Users to Share Incentivized Links -Virality is a valuable way to grow your userbase and your application. In order to leverage network effects, we suggest using our SDK's `shareLink` command to prompt users to share so-called "incentivized links" and receive rewards for sharing. -An example reward would be something like free coins (or any other in-game resource) for users who click the link and for those who shared the link. +Incentivized sharing can help grow your application through network effects. This guide covers implementing a reward system for users who share links and those who click them. + +#### Implementation Overview +1. Create and track promotional campaigns +2. Prompt users to share links +3. Handle incoming referrals +4. Distribute rewards safely + +#### Sharing Links + +When implementing sharing, you'll need to: +1. Generate a unique ID for tracking the promotion +2. Call the `shareLink` command +3. Track the share attempt -To share the link, use `shareLink`. ```javascript -// custom ID creation, persistence, and resolution is up to you as a developer +// Generate a unique ID for this promotion +// This could be per-campaign, per-user, or per-share depending on your needs const customId = await createPromotionalCustomId(); -const { success } = await DiscordRPC.commands.shareLink({ - message: 'Click this link to redeem 5 free coins!', - custom_id: customId, -}); -success ? console.log('User shared link!') : console.log('User did not share link!'); +try { + const { success } = await DiscordRPC.commands.shareLink({ + message: 'Click this link to redeem 5 free coins!', + custom_id: customId, + // referrer_id is optional - if omitted, the current user's ID is used + }); + + if (success) { + // Track successful share for analytics/limiting + await trackSuccessfulShare(customId); + } +} catch (error) { + // Handle share failures appropriately + console.error('Failed to share link:', error); +} ``` -Calling `shareLink` will prompt the user with a modal to share the link. The `success` returned indicates if the link was shared or copied. Note that we did not add a `referrer_id` in this example, as the user ID of the user sharing the link will automatically be appended as a referrer if left empty. -So now that the initial user has shared a link, what happens when their friend receives the message and clicks the link? -Clicking the link (or Play from the Embed) will launch the activity and pass the `customId` and `referredId` to the SDK. Once launched, the SDK will expose the `customId` and `refererId` and you can resolve the IDs and grant the rewards as promised. +#### Handling Incoming Referrals +When a user clicks a shared link, your activity will launch with referral data available through the SDK: ```javascript -// for illustrative purposes -- this must be implemented by you as a developer -await resolvePromotion({ - customId: DiscordRPC.customId, // your promotional ID, which corresponds to granting reward (coins) - refererId: DiscordRPC.referredId, // the user ID of the initial user who shared the link -}); +// Early in your activity's initialization +async function handleReferral() { + // Validate the referral data + if (!DiscordRPC.customId || !DiscordRPC.refererId) { + return; + } + + try { + // Verify this is a valid promotion and hasn't expired + const promotion = await validatePromotion(DiscordRPC.customId); + if (!promotion) { + console.log('Invalid or expired promotion'); + return; + } + + // Prevent self-referrals + if (DiscordRPC.refererId === currentUserId) { + console.log('Self-referrals not allowed'); + return; + } + + // Grant rewards to both users + await grantRewards({ + promotionId: DiscordRPC.customId, + refererId: DiscordRPC.refererId, + newUserId: currentUserId + }); + } catch (error) { + console.error('Failed to process referral:', error); + } +} ``` +#### Link Sharing Best Practices +- Generate unique, non-guessable `customId`s +- Track and validate referrals to prevent abuse +- Handle edge cases like expired promotions gracefully +- Consider implementing cool-down periods between shares + ### Preventing unwanted activity sessions Activities are surfaced through iframes in the Discord app. The activity website itself is publicly reachable at `.discordsays.com`. Activities will expect to be able to communicate with Discord's web or mobile client via the Discord SDK's RPC protocol. If a user loads the activity's website in a normal browser, the Discord RPC server will not be present, and the activity will likely fail in some way. From 2083713ff8f732043c66476245deef9f2ba3c46c Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Wed, 15 Jan 2025 15:47:11 -0500 Subject: [PATCH 5/7] implement some feedback --- docs/activities/Development_Guides.mdx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/activities/Development_Guides.mdx b/docs/activities/Development_Guides.mdx index c1eff935f9..31b557709f 100644 --- a/docs/activities/Development_Guides.mdx +++ b/docs/activities/Development_Guides.mdx @@ -96,10 +96,10 @@ These guides include suggested development practices, SDK commands, and user flo -## Links +## Growth and Referrals - Have your users share links to your activity, with tracking and incentives. + Encourage your users to share links to your activity by adding tracking and offering rewards for engagement. @@ -888,13 +888,11 @@ This example is being done entirely on the client, however, a more common patter ### Prompting Users to Share Incentivized Links -Incentivized sharing can help grow your application through network effects. This guide covers implementing a reward system for users who share links and those who click them. +Incentivized sharing can help grow your Activity through network effects. This guide covers implementing a reward system for users who share links and those who click them. #### Implementation Overview -1. Create and track promotional campaigns -2. Prompt users to share links -3. Handle incoming referrals -4. Distribute rewards safely +1. Create and track an incentivized link for a promotional campaign, then prompt users to share the link +3. Handle incoming referrals and grant valid rewards #### Sharing Links From 5855f1b378e052c978289092cec1e57b53c4f765 Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Wed, 15 Jan 2025 16:42:41 -0500 Subject: [PATCH 6/7] Update docs/activities/Development_Guides.mdx Co-authored-by: advaith --- docs/activities/Development_Guides.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/activities/Development_Guides.mdx b/docs/activities/Development_Guides.mdx index 31b557709f..c9a99fe9b6 100644 --- a/docs/activities/Development_Guides.mdx +++ b/docs/activities/Development_Guides.mdx @@ -892,7 +892,7 @@ Incentivized sharing can help grow your Activity through network effects. This g #### Implementation Overview 1. Create and track an incentivized link for a promotional campaign, then prompt users to share the link -3. Handle incoming referrals and grant valid rewards +2. Handle incoming referrals and grant valid rewards #### Sharing Links From b564bc75c212bca33a4398a7d2593feac37190f6 Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Thu, 23 Jan 2025 12:09:43 -0500 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: Colin Loretz --- docs/activities/Development_Guides.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/activities/Development_Guides.mdx b/docs/activities/Development_Guides.mdx index c9a99fe9b6..27774d3792 100644 --- a/docs/activities/Development_Guides.mdx +++ b/docs/activities/Development_Guides.mdx @@ -898,7 +898,7 @@ Incentivized sharing can help grow your Activity through network effects. This g When implementing sharing, you'll need to: 1. Generate a unique ID for tracking the promotion -2. Call the `shareLink` command +2. Call the [`shareLink`](#DOCS_DEVELOPER_TOOLS_EMBEDDED_APP_SDK/sharelink) command 3. Track the share attempt ```javascript @@ -966,6 +966,8 @@ async function handleReferral() { - Handle edge cases like expired promotions gracefully - Consider implementing cool-down periods between shares +--- + ### Preventing unwanted activity sessions Activities are surfaced through iframes in the Discord app. The activity website itself is publicly reachable at `.discordsays.com`. Activities will expect to be able to communicate with Discord's web or mobile client via the Discord SDK's RPC protocol. If a user loads the activity's website in a normal browser, the Discord RPC server will not be present, and the activity will likely fail in some way.