add QuestStore (#632)

This commit is contained in:
prism 2026-01-08 16:59:04 +01:00 • committed by GitHub
parent 0f507cccb5
commit bc230dde7b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 1125 additions and 0 deletions

View file

@ -5,6 +5,7 @@ export * from "./commands";
export * from "./guild";
export * from "./messages";
export * from "./misc";
export * from "./quests";
export * from "./settings";
export * from "./user";
export * from "./voice";

View file

@ -0,0 +1,129 @@
export const enum QuestRewardType {
REWARD_CODE = 1,
IN_GAME = 2,
COLLECTIBLE = 3,
VIRTUAL_CURRENCY = 4,
FRACTIONAL_PREMIUM = 5,
}
export const enum QuestPlatform {
CROSS_PLATFORM = 0,
XBOX = 1,
PLAYSTATION = 2,
SWITCH = 3,
PC = 4,
}
export const enum QuestTargetedContent {
GIFT_INVENTORY_SETTINGS_BADGE = 0,
QUEST_BAR = 1,
QUEST_INVENTORY_CARD = 2,
QUESTS_EMBED = 3,
ACTIVITY_PANEL = 4,
QUEST_LIVE_STREAM = 5,
MEMBERS_LIST = 6,
QUEST_BADGE = 7,
GIFT_INVENTORY_FOR_YOU = 8,
GIFT_INVENTORY_OTHER = 9,
QUEST_BAR_V2 = 10,
QUEST_HOME_DESKTOP = 11,
QUEST_HOME_MOBILE = 12,
QUEST_BAR_MOBILE = 13,
THIRD_PARTY_APP = 14,
QUEST_BOTTOM_SHEET = 15,
QUEST_EMBED_MOBILE = 16,
QUEST_HOME_MOVE_CALLOUT = 17,
DISCOVERY_SIDEBAR = 18,
QUEST_SHARE_LINK = 19,
CONNECTIONS_MODAL = 20,
DISCOVERY_COMPASS = 21,
TROPHY_CASE_CARD = 22,
VIDEO_MODAL = 23,
VIDEO_MODAL_END_CARD = 24,
REWARD_MODAL = 25,
EXCLUDED_QUEST_EMBED = 26,
VIDEO_MODAL_MOBILE = 27,
ORBS_ANNOUNCEMENT_MODAL = 28,
ORBS_BALANCE_MENU = 29,
QUEST_ENROLLMENT_BLOCKED_BOTTOM_SHEET = 30,
ORBS_SHOP_HERO_CTA = 31,
QUEST_ENROLLMENT_BLOCKED_MODAL = 32,
INTERNAL_PREVIEW_TOOL = 33,
ORBS_REHEAT_COACHMARK_CTA = 34,
INVALID_QUEST_EMBED = 35,
NOT_SHAREABLE_QUEST_EMBED = 36,
QUEST_HOME_MOVE_CALLOUT_DISCOVER = 37,
SPONSORED_QUEST_SHEET = 38,
MOBILE_ORBS_ONBOARDING_DC = 39,
RUNNING_ACTIVITY = 40,
VIDEO_MODAL_PRIMARY_CTA = 41,
QUEST_HOME_TAKEOVER = 42,
USER_PROFILE_ACTIVITY = 43,
}
export const enum QuestPlacement {
INVALID_PLACEMENT = 0,
DESKTOP_ACCOUNT_PANEL_AREA = 1,
MOBILE_HOME_DOCK_AREA = 2,
}
export const enum QuestRewardAssignmentMethod {
ALL = 1,
TIERED = 2,
}
export const enum QuestRewardExpirationMode {
NORMAL = 1,
PREMIUM_EXTENSION = 2,
PREMIUM_PERMANENT = 3,
}
export const enum QuestFeature {
POST_ENROLLMENT_CTA = 1,
QUEST_BAR_V2 = 3,
EXCLUDE_RUSSIA = 5,
IN_HOUSE_CONSOLE_QUEST = 6,
MOBILE_CONSOLE_QUEST = 7,
START_QUEST_CTA = 8,
REWARD_HIGHLIGHTING = 9,
FRACTIONS_QUEST = 10,
ADDITIONAL_REDEMPTION_INSTRUCTIONS = 11,
PACING_V2 = 12,
DISMISSAL_SURVEY = 13,
MOBILE_QUEST_DOCK = 14,
QUESTS_CDN = 15,
PACING_CONTROLLER = 16,
QUEST_HOME_FORCE_STATIC_IMAGE = 17,
VIDEO_QUEST_FORCE_HLS_VIDEO = 18,
VIDEO_QUEST_FORCE_END_CARD_CTA_SWAP = 19,
EXPERIMENTAL_TARGETING_TRAITS = 20,
DO_NOT_DISPLAY = 21,
EXTERNAL_DIALOG = 22,
MOBILE_ONLY_QUEST_PUSH_TO_MOBILE = 23,
MANUAL_HEARTBEAT_INITIALIZATION = 24,
CLOUD_GAMING_ACTIVITY = 25,
NON_GAMING_PLAY_QUEST = 26,
ACTIVITY_QUEST_AUTO_ENROLLMENT = 27,
PACKAGE_ACTION_ADVENTURE = 28,
PACKAGE_RPG_MMO = 29,
PACKAGE_RACING_SPORTS = 30,
PACKAGE_SANDBOX_CREATIVE = 31,
PACKAGE_FAMILY_FRIENDLY = 32,
PACKAGE_HOLIDAY_SEASON = 33,
PACKAGE_NEW_YEARS = 34,
}
export const enum QuestDismissibleContentFlags {
GIFT_INVENTORY_SETTINGS_BADGE = 1,
QUEST_BAR = 2,
ACTIVITY_PANEL = 4,
QUEST_LIVE_STREAM = 8,
}
export const enum QuestUserQuestStatus {
UNACCEPTED = 0,
ACCEPTED = 1,
IN_PROGRESS = 2,
COMPLETED = 3,
CLAIMED = 4,
}

View file

@ -0,0 +1,992 @@
import {
QuestDismissibleContentFlags,
QuestFeature,
QuestPlatform,
QuestPlacement,
QuestRewardAssignmentMethod,
QuestRewardExpirationMode,
QuestRewardType,
QuestTargetedContent,
} from "../../enums";
import { FluxStore } from "./FluxStore";
/** Task types for quest completion requirements. */
export const enum QuestTaskType {
STREAM_ON_DESKTOP = "STREAM_ON_DESKTOP",
PLAY_ON_DESKTOP = "PLAY_ON_DESKTOP",
PLAY_ON_XBOX = "PLAY_ON_XBOX",
PLAY_ON_PLAYSTATION = "PLAY_ON_PLAYSTATION",
PLAY_ON_DESKTOP_V2 = "PLAY_ON_DESKTOP_V2",
WATCH_VIDEO = "WATCH_VIDEO",
WATCH_VIDEO_ON_MOBILE = "WATCH_VIDEO_ON_MOBILE",
PLAY_ACTIVITY = "PLAY_ACTIVITY",
ACHIEVEMENT_IN_GAME = "ACHIEVEMENT_IN_GAME",
ACHIEVEMENT_IN_ACTIVITY = "ACHIEVEMENT_IN_ACTIVITY",
}
/** Operator for combining multiple quest tasks. */
export const enum QuestTaskJoinOperator {
/** All tasks must be completed. */
AND = "and",
/** Any one task must be completed. */
OR = "or",
}
/** Error types returned from quest API operations. */
export const enum QuestErrorType {
GENERIC = "generic",
RATE_LIMITED = "rate_limited",
}
/** Platform mode for quest task selection. */
export const enum QuestPlatformMode {
DESKTOP = "desktop",
CONSOLE = "console",
/** User must select a platform. */
SELECT = "select",
}
/** Reasons for pausing quest video playback. */
export const enum QuestVideoPauseReason {
PAUSE_BUTTON = "PAUSE_BUTTON",
LOST_FOCUS = "LOST_FOCUS",
MODAL_CLOSED = "MODAL_CLOSED",
}
/** Placement types for quest home takeover. */
export const enum QuestHomePlacement {
QUEST_HOME_BANNER = "quest_home_banner",
}
/** Client platforms for quest targeting. */
export const enum QuestClientPlatform {
IOS = "ios",
ANDROID = "android",
DESKTOP = "desktop",
WEB = "web",
WEB_MOBILE = "web_mobile",
WEB_TABLET = "web_tablet",
}
/** Quest sharing policy. */
export const enum QuestSharePolicy {
SHAREABLE_EVERYWHERE = "shareable_everywhere",
NOT_SHAREABLE = "not_shareable",
}
/** Quest bar UI states. */
export const enum QuestBarState {
COLLAPSED = "collapsed",
EXPANDED = "expanded",
CLOSED = "closed",
SOFT_DISMISSED = "soft-dismissed",
RESET_TO_PREVIOUS = "reset-to-previous",
}
/** Reasons for quest embed fallback display. */
export const enum QuestEmbedFallbackReason {
EXCLUDED_QUEST = "excluded_quest",
UNKNOWN_QUEST = "unknown_quest",
NOT_SHAREABLE_QUEST = "not_shareable_quest",
}
/** Console platform selection for quest tasks. */
export const enum QuestConsolePlatformSelection {
CONSOLE = "CONSOLE",
DESKTOP = "DESKTOP",
}
/** Call-to-action types for quest UI interactions. */
export const enum QuestContentCTA {
LEARN_MORE = "LEARN_MORE",
SHOW_REWARD = "SHOW_REWARD",
CLAIM_REWARD = "CLAIM_REWARD",
GET_REWARD_CODE = "GET_REWARD_CODE",
COPY_REWARD_CODE = "COPY_REWARD_CODE",
ACCEPT_QUEST = "ACCEPT_QUEST",
COPY_QUEST_URL = "COPY_QUEST_URL",
MOBILE_SHARESHEET = "MOBILE_SHARESHEET",
TRACK_PROGRESS = "TRACK_PROGRESS",
CONNECT_CONSOLE = "CONNECT_CONSOLE",
CONNECT_CONSOLE_LINK = "CONNECT_CONSOLE_LINK",
VIEW_CONSOLE_CONNECTIONS = "VIEW_CONSOLE_CONNECTION",
VIEW_CONSOLE_CONNECTIONS_LINK = "VIEW_CONSOLE_CONNECTIONS_LINK",
VIEW_REQUIREMENTS = "VIEW_REQUIREMENTS",
SELECT_CONSOLE_PLATFORM = "SELECT_CONSOLE_PLATFORM",
SELECT_DESKTOP_PLATFORM = "SELECT_DESKTOP_PLATFORM",
DESELECT_PLATFORM = "DESELECT_PLATFORM",
DEFIBRILLATOR = "DEFIBRILLATOR",
DEFIBRILLATOR_RECONNECT_CONSOLE = "DEFIBRILLATOR_RECONNECT_CONSOLE",
OPEN_DISCLOSURE = "OPEN_DISCLOSURE",
WATCH_STREAM = "WATCH_STREAM",
WATCH_STREAM_CONFIRM = "WATCH_STREAM_CONFIRM",
REWARD_LEARN_MORE = "REWARD_LEARN_MORE",
OPEN_GAME_LINK = "OPEN_GAME_LINK",
OPEN_CONTEXT_MENU = "OPEN_CONTEXT_MENU",
OPEN_QUEST_HOME = "OPEN_QUEST_HOME",
QUEST_BAR_COPY_LINK = "QUEST_BAR.COPY_LINK",
CONTEXT_MENU_COPY_LINK = "CONTEXT_MENU.COPY_LINK",
REWARD_MODAL_COPY_LINK = "REWARD_MODAL.COPY_LINK",
CONTEXT_MENU_HIDE_CONTENT = "CONTEXT_MENU.HIDE_CONTENT",
CONTEXT_MENU_OPEN_GAME_LINK = "CONTEXT_MENU.OPEN_GAME_LINK",
CONTEXT_MENU_OPEN_DISCLOSURE = "CONTEXT_MENU.OPEN_DISCLOSURE",
CONTEXT_MENU_LEARN_MORE = "CONTEXT_MENU.LEARN_MORE",
HOW_TO_HELP_ARTICLE_XBOX = "HOW_TO_HELP_ARTICLE_XBOX",
HOW_TO_HELP_ARTICLE_PLAYSTATION = "HOW_TO_HELP_ARTICLE_PLAYSTATION",
VIEW_QUESTS = "VIEW_QUESTS",
EXPAND = "EXPAND",
COLLAPSE = "COLLAPSE",
START_QUEST = "START_QUEST",
TRANSCRIPT_ENABLE = "TRANSCRIPT_ENABLE",
TRANSCRIPT_DISABLE = "TRANSCRIPT_DISABLE",
CLOSED_CAPTIONING_ENABLE = "CLOSED_CAPTIONING_ENABLE",
CLOSED_CAPTIONING_DISABLE = "CLOSED_CAPTIONING_DISABLE",
SEEK_BACKWARD = "SEEK_BACKWARD",
SEEK_FORWARD = "SEEK_FORWARD",
WATCH_VIDEO = "WATCH_VIDEO",
QUEST_BAR_VIDEO_QUEST_PREVIEW = "QUEST_BAR_VIDEO_QUEST_PREVIEW",
QUEST_HOME_TILE_HEADER_WATCH_VIDEO = "QUEST_HOME_TILE_HEADER_WATCH_VIDEO",
REDEEM_REWARD = "REDEEM_REWARD",
VISIT_REDEMPTION_LINK = "VISIT_REDEMPTION_LINK",
SPONSORED_QUEST_SHEET = "SPONSORED_QUEST_SHEET",
GAME_PROFILE_OPEN = "GAME_PROFILE_OPEN",
GAME_STORE_OPEN_GAME_LINK = "GAME_STORE_OPEN_GAME_LINK",
MOBILE_ORBS_ONBOARDING_DC = "MOBILE_ORBS_ONBOARDING_DC",
}
/** Sort methods for quest list display. */
export const enum QuestSortMethod {
/** Default sorting by relevance. */
SUGGESTED = "suggested",
MOST_RECENT = "most_recent",
EXPIRING_SOON = "expiring_soon",
RECENTLY_ENROLLED = "recently_enrolled",
}
/** Filter types for quest tasks. */
export const enum QuestTaskFilter {
VIDEO = "task_video",
PLAY = "task_play",
}
/** Filter types for quest rewards. */
export const enum QuestRewardFilter {
VIRTUAL_CURRENCY = "reward_virtual_currency",
COLLECTIBLE = "reward_collectible",
IN_GAME = "reward_in_game",
}
/** Video playback progress states. */
export const enum QuestVideoProgressState {
UNKNOWN = "UNKNOWN",
NOT_STARTED = "NOT_STARTED",
IN_PROGRESS = "IN_PROGRESS",
COMPLETED = "COMPLETED",
}
/** Transcript fetch operation states. */
export const enum QuestTranscriptFetchStatus {
NONE = "NONE",
FETCHING = "FETCHING",
SUCCESS = "SUCCESS",
FAILURE = "FAILURE",
}
/** Result types from quest enrollment attempts. */
export const enum QuestEnrollmentResult {
SUCCESS = "success",
CAPTCHA_FAILED = "captcha_failed",
UNKNOWN_ERROR = "unknown_error",
/** Enrollment already in progress. */
PREVIOUS_IN_FLIGHT_REQUEST = "previous_in_flight_request",
}
/** Reasons why a quest embed was not found. */
export const enum QuestEmbedNotFoundReason {
NOT_FOUND = "not_found",
MOBILE_ONLY = "mobile_only",
}
/** Tab filter types for quest list. */
export const enum QuestFilterTab {
ALL = "all",
CLAIMED = "claimed",
/** Internal preview tool only. */
PREVIEW_TOOL = "preview_tool",
}
/** URL parameter types for quest filtering. */
export const enum QuestFilterParamType {
TAB = "tab",
QUEST_ID = "quest_id",
SORT = "sort",
FILTER = "filter",
}
/** Location identifiers for quest-related UI and tracking. */
export const enum QuestLocation {
ACTIVITY_PANEL = "quests_bar_activity_panel",
QUESTS_MANAGER = "quests_manager",
QUESTS_CONSOLE_OPTIMISTIC_UPDATES_MANAGER = "quests_console_optimistic_updates_manager",
USER_SETTINGS_GIFT_INVENTORY = "user_settings_gift_inventory",
USER_SETTINGS_SEARCH_GIFT_INVENTORY = "user_settings_search_gift_inventory",
USE_QUESTS = "use_quests",
STREAM_SOURCE_SELECT = "stream_source_select",
MEMBERS_LIST = "members_list",
QUESTS_BAR = "quests_bar",
QUESTS_BAR_MOBILE = "quests_bar_mobile",
REWARD_CODE_MODAL = "reward_code_modal",
INGAME_REWARD_MODAL = "ingame_reward_modal",
COLLECTIBLE_REWARD_MODAL = "collectible_reward_modal",
ORBS_REWARD_MODAL = "orbs_reward_modal",
QUEST_PREVIEW_TOOL = "quest_preview_tool",
QUEST_PREVIEW_TOOL_2 = "quest_preview_tool_2",
QUESTS_MINOR_REWARD_CAPPING_CONFIG = "QUESTS_MINOR_REWARD_CAPPING_CONFIG",
QUESTS_CARD = "quests_card",
QUESTS_STORE = "quests_store",
QUEST_CHANNEL_CALL_HEADER = "quests_channel_call_header",
QUEST_HOME_DESKTOP = "quest_home_desktop",
QUEST_HOME_MOBILE = "quest_home_mobile",
QUEST_PROGRESS_BAR = "quest_progress_bar",
EMBED_MOBILE = "embed_mobile",
EMBED_DESKTOP = "embed_desktop",
QUEST_CONTEXT_MENU = "context_menu",
CODED_LINK = "coded_link",
QUEST_DISCLOSURE_MODAL = "quest_disclosure_modal",
DISCOVERY_SIDEBAR = "discovery_sidebar",
DISCOVERY_COMPASS = "discovery_compass",
BADGE = "badge",
COLLECTIBLES_SHOP_HEADER_BAR = "collectibles_shop_header_bar",
ORBS_ANNOUNCEMENT_MODAL = "orbs_announcement_modal",
CONFLICT_CHECKS = "conflict_checks",
VIDEO_MODAL = "video_modal",
VIDEO_MODAL_MOBILE = "video_modal_mobile",
GAME_WIDGETS_POPOVER = "game_widgets_popover",
PRIVATE_CHANNELS_LIST = "private_channels_list",
INTERNAL_TOOLING = "internal_tooling",
QUEST_HOME_MOVED_CALLOUT = "quest_home_moved_callout",
IN_APP_NAVIGATION = "in_app_navigation",
NAVIGATE_TO_QUEST_HOME_UTIL = "navigate_to_quest_home_util",
QUEST_DEEP_LINK_UTIL = "quest_deep_link_util",
YOU_TAB_PROFILE_HEADER = "you_tab_profile_header",
}
/** Video asset for quest tasks. */
export interface QuestVideoAsset {
/** Video URL path relative to CDN. */
url: string;
/** Width in pixels. */
width: number;
/** Height in pixels. */
height: number;
/** Thumbnail image URL. */
thumbnail: string;
/** VTT caption file URL. */
caption?: string;
/** Transcript file URL. */
transcript?: string;
}
/** Video assets for video-based quest tasks. */
export interface QuestTaskVideoAssets {
/** Full resolution video (1080p). */
video: QuestVideoAsset;
/** Low resolution video (720p). */
videoLowRes?: QuestVideoAsset;
/** HLS streaming video (.m3u8). */
videoHls?: QuestVideoAsset;
}
/** Display messages for video-based quest tasks. */
export interface QuestTaskVideoMessages {
videoTitle: string;
}
/** Display messages for achievement-based quest tasks. */
export interface QuestTaskAchievementMessages {
taskTitle: string;
taskDescription: string;
}
/** Application reference in quest tasks. */
export interface QuestTaskApplication {
/** Discord application ID. */
id: string;
}
/** Base properties shared by all quest task types. */
interface QuestTaskBase {
/** Target value to complete (seconds for play tasks, seconds for video tasks). */
target: number;
}
/** Play on desktop quest task. */
export interface QuestTaskPlayOnDesktop extends QuestTaskBase {
type: QuestTaskType.PLAY_ON_DESKTOP;
/** Applications that qualify for completion. */
applications: QuestTaskApplication[];
}
/** Play on desktop v2 quest task with enhanced tracking. */
export interface QuestTaskPlayOnDesktopV2 extends QuestTaskBase {
type: QuestTaskType.PLAY_ON_DESKTOP_V2;
applications: QuestTaskApplication[];
}
/** Stream on desktop quest task. */
export interface QuestTaskStreamOnDesktop extends QuestTaskBase {
type: QuestTaskType.STREAM_ON_DESKTOP;
applications: QuestTaskApplication[];
}
/** Play Discord activity quest task. */
export interface QuestTaskPlayActivity extends QuestTaskBase {
type: QuestTaskType.PLAY_ACTIVITY;
applications: QuestTaskApplication[];
}
/** Play on Xbox quest task. */
export interface QuestTaskPlayOnXbox extends QuestTaskBase {
type: QuestTaskType.PLAY_ON_XBOX;
/** Xbox title IDs. */
externalIds: string[];
applications: QuestTaskApplication[];
}
/** Play on PlayStation quest task. */
export interface QuestTaskPlayOnPlayStation extends QuestTaskBase {
type: QuestTaskType.PLAY_ON_PLAYSTATION;
/** PlayStation title IDs (e.g., "PPSA09016_00"). */
externalIds: string[];
applications: QuestTaskApplication[];
}
/** Watch video quest task for desktop. */
export interface QuestTaskWatchVideo extends QuestTaskBase {
type: QuestTaskType.WATCH_VIDEO;
assets: QuestTaskVideoAssets;
messages: QuestTaskVideoMessages;
}
/** Watch video quest task for mobile. */
export interface QuestTaskWatchVideoOnMobile extends QuestTaskBase {
type: QuestTaskType.WATCH_VIDEO_ON_MOBILE;
assets: QuestTaskVideoAssets;
messages: QuestTaskVideoMessages;
}
/** Achievement in game quest task. */
export interface QuestTaskAchievementInGame extends QuestTaskBase {
type: QuestTaskType.ACHIEVEMENT_IN_GAME;
/** Event name dispatched when achievement is unlocked. */
eventName: string;
messages: QuestTaskAchievementMessages;
applications: QuestTaskApplication[];
}
/** Achievement in Discord activity quest task. */
export interface QuestTaskAchievementInActivity extends QuestTaskBase {
type: QuestTaskType.ACHIEVEMENT_IN_ACTIVITY;
eventName: string;
messages: QuestTaskAchievementMessages;
applications: QuestTaskApplication[];
}
/** Union of all quest task types. */
export type QuestTask =
| QuestTaskPlayOnDesktop
| QuestTaskPlayOnDesktopV2
| QuestTaskStreamOnDesktop
| QuestTaskPlayActivity
| QuestTaskPlayOnXbox
| QuestTaskPlayOnPlayStation
| QuestTaskWatchVideo
| QuestTaskWatchVideoOnMobile
| QuestTaskAchievementInGame
| QuestTaskAchievementInActivity;
/** Task configuration for a quest. */
export interface QuestTaskConfig {
/** Map of task type to task configuration. */
tasks: Partial<Record<QuestTaskType, QuestTask>>;
/** How tasks are combined. Default is "or" (any task completes the quest). */
joinOperator: QuestTaskJoinOperator;
}
/** Display messages for quest rewards. */
export interface QuestRewardMessages {
/** Redemption instructions keyed by {@link QuestPlatform}. */
redemptionInstructionsByPlatform: Partial<Record<QuestPlatform, string>>;
/** Reward display name (e.g., "700 Orbs"). */
name: string;
/** Name with article (e.g., "700 Orbs"). */
nameWithArticle: string;
}
/** Base properties shared by all quest reward types. */
interface QuestRewardBase {
/** SKU ID for the reward entitlement. */
skuId: string;
messages: QuestRewardMessages;
}
/** Reward code reward type. */
export interface QuestRewardCode extends QuestRewardBase {
type: QuestRewardType.REWARD_CODE;
/** Reward image URL. */
asset?: string;
/** Reward video URL. */
assetVideo?: string | null;
/** Approximate codes remaining, null if unlimited. */
approximateCount?: number | null;
/** External URL to redeem the code. */
redemptionLink?: string | null;
}
/** In-game reward type. */
export interface QuestRewardInGame extends QuestRewardBase {
type: QuestRewardType.IN_GAME;
asset?: string;
assetVideo?: string | null;
}
/** Collectible avatar decoration reward type. */
export interface QuestRewardCollectible extends QuestRewardBase {
type: QuestRewardType.COLLECTIBLE;
asset?: string;
assetVideo?: string | null;
/** ISO timestamp when collectible expires. */
expiresAt?: string;
/** Expiration behavior. */
expirationMode?: QuestRewardExpirationMode;
/** Extended expiration for Nitro users. */
expiresAtPremium?: string | null;
}
/** Virtual currency (Orbs) reward type. */
export interface QuestRewardVirtualCurrency extends QuestRewardBase {
type: QuestRewardType.VIRTUAL_CURRENCY;
/** Number of orbs awarded. */
orbQuantity: number;
}
/** Fractional Nitro premium time reward type. */
export interface QuestRewardFractionalPremium extends QuestRewardBase {
type: QuestRewardType.FRACTIONAL_PREMIUM;
asset?: string;
assetVideo?: string | null;
/** Premium time quantity. */
quantity: number;
}
/** Union of all quest reward types. */
export type QuestReward =
| QuestRewardCode
| QuestRewardInGame
| QuestRewardCollectible
| QuestRewardVirtualCurrency
| QuestRewardFractionalPremium;
/** Rewards configuration for a quest. */
export interface QuestRewardsConfig {
/** How rewards are distributed to users. */
assignmentMethod: QuestRewardAssignmentMethod;
/** Available reward options. */
rewards: QuestReward[];
/** ISO timestamp when rewards can no longer be claimed. */
rewardsExpireAt: string;
/** Platforms where rewards can be claimed. */
platforms: QuestPlatform[];
}
/** Visual assets for quest display. */
export interface QuestAssets {
/** Hero banner image URL. */
hero: string;
/** Hero banner video URL. */
heroVideo: string | null;
/** Quest bar hero image URL. */
questBarHero: string;
/** Quest bar hero video URL. */
questBarHeroVideo: string | null;
/** Game tile image URL. */
gameTile: string;
/** Game logotype image URL. */
logotype: string;
/** Light theme game tile URL. */
gameTileLight: string;
/** Dark theme game tile URL. */
gameTileDark: string;
/** Light theme logotype URL. */
logotypeLight: string;
/** Dark theme logotype URL. */
logotypeDark: string;
}
/** Color scheme for quest UI theming. */
export interface QuestColors {
/** Primary hex color (e.g., "#4752C4"). */
primary: string;
/** Secondary hex color. */
secondary: string;
}
/** Display messages for quest UI. */
export interface QuestMessages {
/** Quest display name. */
questName: string;
/** Game title. */
gameTitle: string;
/** Game publisher name. */
gamePublisher: string;
}
/** Application reference in quest configuration. */
export interface QuestApplication {
/** Discord application ID. */
id: string;
/** Application display name. */
name: string;
}
/** Platform-specific app store configuration. */
export interface QuestCtaPlatformConfig {
/** Android package name. */
androidAppId?: string;
/** iOS App Store ID. */
iosAppId?: string;
}
/** Call-to-action button configuration. */
export interface QuestCtaConfig {
/** CTA destination URL. */
link: string;
/** Button label text. */
buttonLabel: string;
/** Optional subtitle text. */
subtitle?: string;
/** Android-specific configuration. */
android?: QuestCtaPlatformConfig;
/** iOS-specific configuration. */
ios?: QuestCtaPlatformConfig;
}
/** Co-sponsor branding metadata for partnered quests. */
export interface QuestCosponsorMetadata {
/** Co-sponsor company name. */
name: string;
/** Logotype image URL. */
logotype: string;
/** Redemption instructions text. */
redemptionInstructions: string;
/** Light theme logotype URL. */
logotypeLight: string;
/** Dark theme logotype URL. */
logotypeDark: string;
}
/** Complete quest configuration. */
export interface QuestConfig {
/** Quest ID (snowflake). */
id: string;
/** Configuration version number. */
configVersion: number;
/** ISO timestamp when quest becomes available. */
startsAt: string;
/** ISO timestamp when quest expires. */
expiresAt: string;
/** Enabled feature flags for this quest. */
features: QuestFeature[];
/** Associated Discord application. */
application: QuestApplication;
/** Visual assets. */
assets: QuestAssets;
/** Color scheme. */
colors: QuestColors;
/** Display messages. */
messages: QuestMessages;
/** Task requirements configuration. */
taskConfigV2: QuestTaskConfig;
/** Rewards configuration. */
rewardsConfig: QuestRewardsConfig;
/** Optional co-sponsor branding. */
cosponsorMetadata?: QuestCosponsorMetadata;
/** Sharing policy. */
sharePolicy: QuestSharePolicy;
/** Call-to-action configuration. */
ctaConfig: QuestCtaConfig;
}
/** Heartbeat tracking for quest progress. Updated via QUESTS_SEND_HEARTBEAT_SUCCESS. */
export interface QuestProgressHeartbeat {
/** ISO timestamp of last heartbeat. */
lastBeatAt: string;
/** ISO timestamp when heartbeat tracking expires. */
expiresAt: string | null;
}
/** Progress tracking for a single quest task. Updated via QUESTS_USER_STATUS_UPDATE. */
export interface QuestTaskProgress {
/** Task event name matching {@link QuestTaskType}. */
eventName: string;
/** Current progress value (seconds played/watched). */
value: number;
/** ISO timestamp of last progress update. */
updatedAt: string;
/** ISO timestamp when task was completed, null if incomplete. */
completedAt: string | null;
/** Heartbeat tracking for active progress. */
heartbeat: QuestProgressHeartbeat | null;
}
/** User's status for a specific quest. Updated via QUESTS_USER_STATUS_UPDATE. */
export interface QuestUserStatus {
/** User ID (snowflake). */
userId: string;
/** Quest ID (snowflake). */
questId: string;
/** ISO timestamp when user enrolled. */
enrolledAt: string;
/** ISO timestamp when quest was completed, null if incomplete. */
completedAt: string | null;
/** ISO timestamp when reward was claimed, null if unclaimed. */
claimedAt: string | null;
/** Claimed reward tier for tiered rewards, null otherwise. */
claimedTier: number | null;
/** ISO timestamp of last stream heartbeat. */
lastStreamHeartbeatAt: string | null;
/** Total stream progress in seconds. */
streamProgressSeconds: number;
/** Bitmask of dismissed UI content. */
dismissedQuestContent: QuestDismissibleContentFlags;
/** Progress by task event name. */
progress: Record<string, QuestTaskProgress>;
}
/** Quest object with configuration and user status. */
export interface Quest {
/** Quest ID (snowflake). */
id: string;
/** Whether this is a preview/test quest. */
preview: boolean;
/** Quest configuration. */
config: QuestConfig;
/** User's status, null if not enrolled. */
userStatus: QuestUserStatus | null;
/** UI placements where this quest should appear. */
targetedContent: QuestTargetedContent[];
}
/** Reference to an excluded quest. */
export interface ExcludedQuest {
/** Excluded quest ID. */
id: string;
/** Replacement quest ID to show instead. */
replacementId: string;
}
/** Ad tracking identifiers for quest delivery. */
export interface QuestAdIdentifiers {
ad_id?: string;
adset_id?: string;
ad_set_id?: string;
campaign_id?: string;
creative_id?: string;
creative_type?: string;
/** Request ID from ad decision. */
decision_id?: string;
/** Whether quest was served via targeting. */
is_targeted: boolean;
}
/** Quest delivery information for a placement. */
export interface QuestDeliveryInfo {
/** Quest to deliver. */
quest: Quest;
/** Ad tracking data. */
adDecisionData: QuestAdIdentifiers;
/** Ad context for analytics. */
adContext: string | null;
/** Raw metadata for ad attribution. */
metadataRaw: string | null;
/** Sealed metadata for verification. */
metadataSealed: string | null;
}
/** Ad decision cache entry for quest delivery. */
export interface QuestAdDecision {
/** Quest ID or null if no quest to deliver. */
questId: string | null;
/** Unix timestamp when decision was fetched. */
fetchedAt: number;
/** Cache TTL in milliseconds. Default 6 hours. */
ttlMillis: number;
/** Ad tracking data. */
adDecisionData: QuestAdIdentifiers;
adContext: string | null;
metadataRaw: string | null;
metadataSealed: string | null;
}
/** Stream heartbeat failure tracking. Updated via QUESTS_SEND_HEARTBEAT_FAILURE. */
export interface StreamHeartbeatFailure {
/** Quest ID. */
questId: string;
/** Stream identifier. */
streamKey: string;
/** Unix timestamp of first failure. */
firstFailedAt: number;
}
/** Asset for quest home takeover display. */
export interface QuestHomeTakeoverAsset {
/** Accessibility text. */
altText: string;
/** Asset type identifier. */
assetType: string;
/** Asset URL. */
url: string;
}
/** Sponsor CTA for quest home takeover. */
export interface QuestHomeTakeoverCtaSponsor {
ctaType: string;
title: string;
/** Sponsor destination URL. */
url: string;
}
/** Quest CTA for quest home takeover. */
export interface QuestHomeTakeoverCtaQuest {
ctaType: string;
title: string;
/** Quest ID to navigate to. */
questId: string;
}
/** Quest home takeover banner configuration. */
export interface QuestHomeTakeoverConfig {
placementType: QuestHomePlacement;
/** Campaign identifier. */
campaignId: string;
labelTitle: string;
labelSubtitle: string;
/** Hero banner asset. */
assetHeroImage: QuestHomeTakeoverAsset;
/** Sponsor logo asset. */
assetSponsorImage: QuestHomeTakeoverAsset;
/** Sponsor link CTA. */
ctaSponsorUrl: QuestHomeTakeoverCtaSponsor;
/** Quest navigation CTAs. */
ctaQuests: QuestHomeTakeoverCtaQuest[];
/** ISO timestamp when takeover starts. */
startsAt: string;
/** ISO timestamp when takeover expires. */
expiresAt: string;
}
/** Claimed reward code details. Returned by QUESTS_FETCH_REWARD_CODE_SUCCESS. */
export interface QuestClaimedRewardCode {
userId: string;
questId: string;
/** The reward code string. */
code: string;
/** Platform the code is for. */
platform: QuestPlatform;
/** ISO timestamp when claimed. */
claimedAt: string;
/** Reward tier if applicable. */
tier: number | null;
}
/** Entitlement item from reward claim. */
export interface QuestEntitlementItem {
/** SKU ID. */
skuId: string;
/** Metadata containing reward details. */
tenantMetadata: {
questRewards?: {
reward: {
tag: QuestRewardType;
rewardCode?: QuestClaimedRewardCode;
};
};
} | null;
/** Whether entitlement has been consumed. */
consumed: boolean;
}
/** Error from reward claim operation. */
export interface QuestEntitlementError {
code?: string;
message?: string;
}
/** Response from claiming quest rewards. Returned by QUESTS_CLAIM_REWARD_SUCCESS. */
export interface QuestEntitlements {
/** ISO timestamp when claimed. */
claimedAt: string;
/** Entitlement items received. */
items: QuestEntitlementItem[];
/** Errors encountered during claim. */
errors: QuestEntitlementError[];
}
/** Video progress tracking state. */
export interface QuestVideoProgress {
/** Current playback position in seconds. */
timestampSec: number;
/** Total video duration in seconds. */
duration: number;
/** Maximum position reached in seconds. */
maxTimestampSec: number;
}
/** Transcript asset for quest videos. */
export interface QuestTranscriptAsset {
questId: string;
fetchStatus: QuestTranscriptFetchStatus;
/** Transcript text content when loaded. */
text?: string;
/** Transcript file URL. */
url?: string;
}
/** Error hint from console quest operations. */
export interface QuestConsoleErrorHint {
type: QuestErrorType;
/** User-facing error message. */
message: string;
/** Connected account ID that caused the error. */
connected_account_id: string;
/** Account type (e.g., "xbox", "playstation"). */
connected_account_type: string;
}
/** Computed task details for display. */
export interface QuestTaskDetails {
taskType: QuestTaskType;
/** Target completion time in minutes. */
targetMinutes: number;
/** Progress as decimal (0.0 to 1.0). */
percentComplete: number;
/** Applications for this task. */
applications?: QuestTaskApplication[];
}
/** Third-party task details for external quests. */
export interface QuestThirdPartyTaskDetails {
description: string;
/** Current progress value. */
progress: number;
/** Target completion value. */
target: number;
/** Progress as decimal (0.0 to 1.0). */
percentComplete: number;
title?: string;
}
/** Store for Discord Quests data. Manages quest configs, user progress, rewards, and delivery. */
export class QuestStore extends FluxStore {
/** All quests keyed by quest ID. Updated via QUESTS_FETCH_CURRENT_QUESTS_SUCCESS. */
get quests(): Map<string, Quest>;
/** Quests the user is excluded from. Updated via QUESTS_FETCH_CURRENT_QUESTS_SUCCESS. */
get excludedQuests(): Map<string, ExcludedQuest>;
/** Quests with claimed rewards. Updated via QUESTS_FETCH_CLAIMED_QUESTS_SUCCESS. */
get claimedQuests(): Map<string, Quest>;
/** Whether fetching current quests. Set via QUESTS_FETCH_CURRENT_QUESTS_BEGIN. */
get isFetchingCurrentQuests(): boolean;
/** Whether fetching claimed quests. Set via QUESTS_FETCH_CLAIMED_QUESTS_BEGIN. */
get isFetchingClaimedQuests(): boolean;
/** Unix timestamp of last current quests fetch. Default 0. */
get lastFetchedCurrentQuests(): number;
/** Unix timestamp of last quest-to-deliver fetch. Default 0. */
get lastFetchedQuestToDeliver(): number;
/** Whether fetching quest to deliver. Set via QUESTS_FETCH_QUEST_TO_DELIVER_BEGIN. */
get isFetchingQuestToDeliver(): boolean;
/** Override quest for delivery testing. Set via QUESTS_DELIVERY_OVERRIDE. */
get questDeliveryOverride(): Quest | undefined;
/** Quest delivery info keyed by {@link QuestPlacement}. Updated via QUESTS_FETCH_QUEST_TO_DELIVER_SUCCESS. */
get questToDeliverForPlacement(): Map<QuestPlacement, QuestDeliveryInfo>;
/** Date until enrollment is blocked, null if not blocked. Set via QUESTS_ENROLL_FAILURE. */
get questEnrollmentBlockedUntil(): Date | null;
/** Ad decision cache keyed by {@link QuestPlacement}. Updated via QUESTS_FETCH_QUEST_TO_DELIVER_SUCCESS. */
get questAdDecisionByPlacement(): Map<QuestPlacement, QuestAdDecision>;
/** Quest configs keyed by quest ID. */
get questConfigs(): Map<string, QuestConfig>;
/** Whether fetching preview for a quest. */
isFetchingQuestPreview(questId: string): boolean;
/** Whether fetching quest to deliver for a placement. */
isFetchingQuestToDeliverByPlacement(placement: QuestPlacement): boolean;
/** Gets preview fetch error for a quest. */
getFetchQuestPreviewError(questId: string): QuestErrorType | undefined;
/** Whether user is currently enrolling in a quest. Set via QUESTS_ENROLL_BEGIN. */
isEnrolling(questId: string): boolean;
/** Whether user is currently claiming reward for a quest. Set via QUESTS_CLAIM_REWARD_BEGIN. */
isClaimingReward(questId: string): boolean;
/** Whether fetching reward code for a quest. Set via QUESTS_FETCH_REWARD_CODE_BEGIN. */
isFetchingRewardCode(questId: string): boolean;
/** Whether dismissing content for a quest. Set via QUESTS_DISMISS_CONTENT_BEGIN. */
isDismissingContent(questId: string): boolean;
/** Gets claimed reward code for a quest. Updated via QUESTS_FETCH_REWARD_CODE_SUCCESS. */
getRewardCode(questId: string): QuestClaimedRewardCode | undefined;
/** Gets entitlement items for a quest. Updated via QUESTS_CLAIM_REWARD_SUCCESS. */
getRewards(questId: string): QuestEntitlementItem[] | undefined;
/** Gets stream heartbeat failure info. Cleared via STREAM_CLOSE. */
getStreamHeartbeatFailure(streamKey: string): StreamHeartbeatFailure | undefined;
/** Gets a quest by ID. */
getQuest(questId: string): Quest | undefined;
/** Gets quest config by ID. */
getQuestConfig(questId: string): QuestConfig | undefined;
/** Whether quest has active desktop progress. Updated via QUESTS_SEND_HEARTBEAT_SUCCESS. */
isProgressingOnDesktop(questId: string): boolean;
/** Gets selected task platform for a quest. Set via QUESTS_SELECT_TASK_PLATFORM. */
selectedTaskPlatform(questId: string): QuestPlatformMode | null;
/** Gets optimistic progress for a task. Set via QUESTS_UPDATE_OPTIMISTIC_PROGRESS, cleared via QUESTS_RESET_OPTIMISTIC_PROGRESS. */
getOptimisticProgress(questId: string, taskEventName: string): number | undefined;
/** Gets map of quest IDs to expired status. Computed from quest config expiresAt. */
getExpiredQuestsMap(): Map<string, boolean>;
/** Whether a quest has expired. Computed from quest config expiresAt. */
isQuestExpired(questId: string): boolean;
/** Gets quest loaded via preview tool. Updated via QUESTS_FETCH_PREVIEW_SUCCESS. */
getQuestLoadedViaPreview(questId: string): Quest | undefined;
/** Whether fetching quest home takeover config. Set via QUESTS_FETCH_QUEST_HOME_TAKEOVER_BEGIN. */
isFetchingQuestHomeTakeover(): boolean;
/** Gets quest home takeover config. Updated via QUESTS_FETCH_QUEST_HOME_TAKEOVER_SUCCESS. */
getQuestHomeTakeoverConfig(): QuestHomeTakeoverConfig | null;
/** Gets Unix timestamp of last takeover fetch, null if never fetched. */
getLastFetchedQuestHomeTakeover(): number | null;
}

View file

@ -28,6 +28,7 @@ export * from "./OverridePremiumTypeStore";
export * from "./PermissionStore";
export * from "./PopoutWindowStore";
export * from "./PresenceStore";
export * from "./QuestStore";
export * from "./ReadStateStore";
export * from "./RelationshipStore";
export * from "./RTCConnectionStore";

View file

@ -81,6 +81,7 @@ export let SoundboardStore: t.SoundboardStore;
export let PopoutWindowStore: t.PopoutWindowStore;
export let ApplicationCommandIndexStore: t.ApplicationCommandIndexStore;
export let EditMessageStore: t.EditMessageStore;
export let QuestStore: t.QuestStore;
/**
* @see jsdoc of {@link t.useStateFromStores}
@ -134,6 +135,7 @@ waitForStore("SoundboardStore", m => SoundboardStore = m);
waitForStore("PopoutWindowStore", m => PopoutWindowStore = m);
waitForStore("ApplicationCommandIndexStore", m => ApplicationCommandIndexStore = m);
waitForStore("EditMessageStore", m => EditMessageStore = m);
waitForStore("QuestStore", m => QuestStore = m);
waitForStore("ThemeStore", m => {
ThemeStore = m;
// Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies.