From effd59b378cd969ba82551d95b35e6ac12532ad1 Mon Sep 17 00:00:00 2001 From: Andrew Giel Date: Thu, 9 Jan 2025 12:46:41 -0500 Subject: [PATCH] feat: add shareLink command (#297) * chore: update schema * feat: add shareLink command * chore: add mock * fix: shareLink jsdoc * fix: share link command response * feat: add response to schema --- src/commands/index.ts | 2 ++ src/commands/shareLink.ts | 12 +++++++ src/generated/schema.json | 66 +++++++++++++++++++++++++++++++++++++++ src/generated/schemas.ts | 50 +++++++++++++++++++++++++++++ src/mock.ts | 1 + src/schema/common.ts | 1 + src/schema/responses.ts | 1 + 7 files changed, 133 insertions(+) create mode 100644 src/commands/shareLink.ts diff --git a/src/commands/index.ts b/src/commands/index.ts index 28c629ad..a6f280e4 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -15,6 +15,7 @@ import {openShareMomentDialog} from './openShareMomentDialog'; import {setActivity, SetActivity} from './setActivity'; import {setConfig} from './setConfig'; import {setOrientationLockState} from './setOrientationLockState'; +import {shareLink} from './shareLink'; import {startPurchase} from './startPurchase'; import {userSettingsGetLocale} from './userSettingsGetLocale'; import {initiateImageUpload} from './initiateImageUpload'; @@ -40,6 +41,7 @@ function commands(sendCommand: TSendCommand) { setActivity: setActivity(sendCommand), setConfig: setConfig(sendCommand), setOrientationLockState: setOrientationLockState(sendCommand), + shareLink: shareLink(sendCommand), startPurchase: startPurchase(sendCommand), userSettingsGetLocale: userSettingsGetLocale(sendCommand), initiateImageUpload: initiateImageUpload(sendCommand), diff --git a/src/commands/shareLink.ts b/src/commands/shareLink.ts new file mode 100644 index 00000000..1d842fa1 --- /dev/null +++ b/src/commands/shareLink.ts @@ -0,0 +1,12 @@ +import {Command} from '../generated/schemas'; +import {schemaCommandFactory} from '../utils/commandFactory'; + +/** + * Opens a modal in the user's client to share the Activity link. + * + * @param {string} referrer_id + * @param {string} custom_id + * @param {string} message - message sent alongside link when shared. + * @returns {Promise<{success: boolean>} whether or not the user shared the link to someone + */ +export const shareLink = schemaCommandFactory(Command.SHARE_LINK); diff --git a/src/generated/schema.json b/src/generated/schema.json index 48a3c25c..1ab2ed38 100644 --- a/src/generated/schema.json +++ b/src/generated/schema.json @@ -148,5 +148,71 @@ "required": ["participants"], "additionalProperties": false } + }, + "SHARE_INTERACTION": { + "request": { + "type": "object", + "properties": { + "command": {"type": "string"}, + "content": {"type": "string", "maxLength": 2000}, + "preview_image": { + "type": "object", + "properties": {"height": {"type": "number"}, "url": {"type": "string"}, "width": {"type": "number"}}, + "required": ["height", "url", "width"], + "additionalProperties": false + }, + "components": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": {"const": 1}, + "components": { + "type": "array", + "maxItems": 5, + "items": { + "type": "object", + "properties": { + "type": {"const": 2}, + "style": {"type": "number", "minimum": 1, "maximum": 5}, + "label": {"type": "string", "description": "Text that appears on the button", "maxLength": 80}, + "custom_id": { + "type": "string", + "description": "Developer-defined identifier for the button; max 100 characters", + "maxLength": 100 + } + }, + "required": ["type", "style"], + "additionalProperties": false + } + } + }, + "required": ["type"], + "additionalProperties": false + } + } + }, + "required": ["command"], + "additionalProperties": false + }, + "response": null + }, + "SHARE_LINK": { + "request": { + "type": "object", + "properties": { + "referrer_id": {"type": "string", "maxLength": 64}, + "custom_id": {"type": "string", "maxLength": 64}, + "message": {"type": "string", "maxLength": 1000} + }, + "required": ["message"], + "additionalProperties": false + }, + "response": { + "type": "object", + "properties": {"success": {"type": "boolean"}}, + "required": ["success"], + "additionalProperties": false + } } } diff --git a/src/generated/schemas.ts b/src/generated/schemas.ts index 4c561a9a..2d4f843a 100644 --- a/src/generated/schemas.ts +++ b/src/generated/schemas.ts @@ -113,6 +113,46 @@ export type GetActivityInstanceConnectedParticipantsResponse = zInfer< typeof GetActivityInstanceConnectedParticipantsResponseSchema >; +// SHARE_INTERACTION +export const ShareInteractionRequestSchema = z.object({ + command: z.string(), + content: z.string().max(2000).optional(), + preview_image: z.object({height: z.number(), url: z.string(), width: z.number()}).optional(), + components: z + .array( + z.object({ + type: z.literal(1), + components: z + .array( + z.object({ + type: z.literal(2), + style: z.number().gte(1).lte(5), + label: z.string().max(80).optional(), + custom_id: z + .string() + .max(100) + .describe('Developer-defined identifier for the button; max 100 characters') + .optional(), + }), + ) + .max(5) + .optional(), + }), + ) + .optional(), +}); +export type ShareInteractionRequest = zInfer; + +// SHARE_LINK +export const ShareLinkRequestSchema = z.object({ + referrer_id: z.string().max(64).optional(), + custom_id: z.string().max(64).optional(), + message: z.string().max(1000), +}); +export type ShareLinkRequest = zInfer; +export const ShareLinkResponseSchema = z.object({success: z.boolean()}); +export type ShareLinkResponse = zInfer; + /** * RPC Commands which support schemas. */ @@ -121,6 +161,8 @@ export enum Command { OPEN_SHARE_MOMENT_DIALOG = 'OPEN_SHARE_MOMENT_DIALOG', AUTHENTICATE = 'AUTHENTICATE', GET_ACTIVITY_INSTANCE_CONNECTED_PARTICIPANTS = 'GET_ACTIVITY_INSTANCE_CONNECTED_PARTICIPANTS', + SHARE_INTERACTION = 'SHARE_INTERACTION', + SHARE_LINK = 'SHARE_LINK', } const emptyResponseSchema = z.object({}).optional().nullable(); @@ -146,4 +188,12 @@ export const Schemas = { request: emptyRequestSchema, response: GetActivityInstanceConnectedParticipantsResponseSchema, }, + [Command.SHARE_INTERACTION]: { + request: ShareInteractionRequestSchema, + response: emptyResponseSchema, + }, + [Command.SHARE_LINK]: { + request: ShareLinkRequestSchema, + response: ShareLinkResponseSchema, + }, } as const; diff --git a/src/mock.ts b/src/mock.ts index 8a589f38..ca932076 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -134,6 +134,7 @@ export const commandsMockDefault: IDiscordSDK['commands'] = { }), getChannelPermissions: () => Promise.resolve({permissions: bigInt(1234567890) as unknown as bigint}), openShareMomentDialog: () => Promise.resolve(null), + shareLink: () => Promise.resolve({success: false}), initiateImageUpload: () => Promise.resolve({ image_url: diff --git a/src/schema/common.ts b/src/schema/common.ts index 8ea7710b..fedc5e4b 100644 --- a/src/schema/common.ts +++ b/src/schema/common.ts @@ -36,6 +36,7 @@ export enum Commands { OPEN_SHARE_MOMENT_DIALOG = 'OPEN_SHARE_MOMENT_DIALOG', INITIATE_IMAGE_UPLOAD = 'INITIATE_IMAGE_UPLOAD', GET_ACTIVITY_INSTANCE_CONNECTED_PARTICIPANTS = 'GET_ACTIVITY_INSTANCE_CONNECTED_PARTICIPANTS', + SHARE_LINK = 'SHARE_LINK', } export const ReceiveFramePayload = zod diff --git a/src/schema/responses.ts b/src/schema/responses.ts index 922b289f..e34fd842 100644 --- a/src/schema/responses.ts +++ b/src/schema/responses.ts @@ -182,6 +182,7 @@ function parseResponseData({cmd, data}: zod.infer) { case Commands.INITIATE_IMAGE_UPLOAD: case Commands.OPEN_SHARE_MOMENT_DIALOG: case Commands.GET_ACTIVITY_INSTANCE_CONNECTED_PARTICIPANTS: + case Commands.SHARE_LINK: const {response} = Schemas[cmd]; return response.parse(data); default: