From e39adad3994972c1209a50cf5df6be47a8ed5bae Mon Sep 17 00:00:00 2001 From: Vladislav Kibenko Date: Tue, 6 Feb 2024 00:21:09 +0300 Subject: [PATCH 1/4] feat(launch-params): implement and reuse the retrieveFromUrl function --- .../__tests__/retrieveFromUrl.ts | 19 +++++++++++++++++ .../src/launch-params/launchParamsParser.ts | 4 ++++ .../src/launch-params/retrieveFromLocation.ts | 4 ++-- .../launch-params/retrieveFromPerformance.ts | 9 ++------ .../sdk/src/launch-params/retrieveFromUrl.ts | 19 +++++++++++++++++ packages/sdk/src/launch-params/types.ts | 21 ++++++++++++------- 6 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 packages/sdk/src/launch-params/__tests__/retrieveFromUrl.ts create mode 100644 packages/sdk/src/launch-params/retrieveFromUrl.ts diff --git a/packages/sdk/src/launch-params/__tests__/retrieveFromUrl.ts b/packages/sdk/src/launch-params/__tests__/retrieveFromUrl.ts new file mode 100644 index 000000000..fa1bdebe7 --- /dev/null +++ b/packages/sdk/src/launch-params/__tests__/retrieveFromUrl.ts @@ -0,0 +1,19 @@ +import { expect, it } from 'vitest'; +import { retrieveFromUrl } from '../retrieveFromUrl'; + +it('should return launch parameters based on hash only in case, URL does not contain the query part', () => { + expect(retrieveFromUrl('#tgWebAppPlatform=tdesktop&tgWebAppVersion=7.0&tgWebAppThemeParams=%7B%7D')).toEqual({ + platform: 'tdesktop', + version: '7.0', + themeParams: {}, + }); +}); + +it('should return launch parameters based on query params and hash in case, URL contains both parts', () => { + expect(retrieveFromUrl('?tgWebAppStartParam=900#tgWebAppPlatform=tdesktop&tgWebAppVersion=7.0&tgWebAppThemeParams=%7B%7D')).toEqual({ + platform: 'tdesktop', + version: '7.0', + themeParams: {}, + startParam: '900', + }); +}); diff --git a/packages/sdk/src/launch-params/launchParamsParser.ts b/packages/sdk/src/launch-params/launchParamsParser.ts index 008a7ab4e..2fcd7015b 100644 --- a/packages/sdk/src/launch-params/launchParamsParser.ts +++ b/packages/sdk/src/launch-params/launchParamsParser.ts @@ -29,6 +29,10 @@ export function launchParamsParser() { type: boolean().optional(), from: 'tgWebAppShowSettings', }, + startParam: { + type: string().optional(), + from: 'tgWebAppStartParam', + }, themeParams: { type: themeParamsParser(), from: 'tgWebAppThemeParams', diff --git a/packages/sdk/src/launch-params/retrieveFromLocation.ts b/packages/sdk/src/launch-params/retrieveFromLocation.ts index 643944b55..228487d4b 100644 --- a/packages/sdk/src/launch-params/retrieveFromLocation.ts +++ b/packages/sdk/src/launch-params/retrieveFromLocation.ts @@ -1,4 +1,4 @@ -import { parseLaunchParams } from './parseLaunchParams.js'; +import { retrieveFromUrl } from './retrieveFromUrl.js'; import type { LaunchParams } from './types.js'; /** @@ -6,5 +6,5 @@ import type { LaunchParams } from './types.js'; * @throws {Error} window.location.hash contains invalid data. */ export function retrieveFromLocation(): LaunchParams { - return parseLaunchParams(window.location.hash.slice(1)); + return retrieveFromUrl(window.location.href); } diff --git a/packages/sdk/src/launch-params/retrieveFromPerformance.ts b/packages/sdk/src/launch-params/retrieveFromPerformance.ts index 36c822dfa..15c8a338a 100644 --- a/packages/sdk/src/launch-params/retrieveFromPerformance.ts +++ b/packages/sdk/src/launch-params/retrieveFromPerformance.ts @@ -1,5 +1,5 @@ import { getFirstNavigationEntry } from './getFirstNavigationEntry.js'; -import { parseLaunchParams } from './parseLaunchParams.js'; +import { retrieveFromUrl } from './retrieveFromUrl.js'; import type { LaunchParams } from './types.js'; /** @@ -14,10 +14,5 @@ export function retrieveFromPerformance(): LaunchParams { throw new Error('Unable to get first navigation entry.'); } - const hashMatch = navigationEntry.name.match(/#(.*)/); - if (!hashMatch) { - throw new Error('First navigation entry does not contain hash part.'); - } - - return parseLaunchParams(hashMatch[1]); + return retrieveFromUrl(navigationEntry.name); } diff --git a/packages/sdk/src/launch-params/retrieveFromUrl.ts b/packages/sdk/src/launch-params/retrieveFromUrl.ts new file mode 100644 index 000000000..1504276ad --- /dev/null +++ b/packages/sdk/src/launch-params/retrieveFromUrl.ts @@ -0,0 +1,19 @@ +import { parseLaunchParams } from '~/launch-params/parseLaunchParams.js'; +import type { LaunchParams } from '~/launch-params/types.js'; + +/** + * Retrieves launch parameters from the specified URL. + * @param url - URL to extract launch parameters from. + */ +export function retrieveFromUrl(url: string): LaunchParams { + const queryParams = url.includes('?') + // If URL includes "?", we expect it to possibly contain "#". The reason is TMA allows passing + // start parameter via tgWebAppStartParam **query** parameter. Replacing "#" with "&" we + // expect merging query parameters with hash parameters and creating complete launch + // parameters information. + ? url.replace('#', '&').slice(url.indexOf('?') + 1) + // Otherwise, we expect specifying launch parameters only in the hash part. + : url.slice(url.indexOf('#') + 1); + + return parseLaunchParams(queryParams); +} diff --git a/packages/sdk/src/launch-params/types.ts b/packages/sdk/src/launch-params/types.ts index 228c42bc9..29f51e9e7 100644 --- a/packages/sdk/src/launch-params/types.ts +++ b/packages/sdk/src/launch-params/types.ts @@ -8,9 +8,9 @@ import type { Platform } from '~/types/index.js'; */ export interface LaunchParams { /** - * Current Mini Apps version. + * True if Mini App is currently launched in inline mode. */ - version: string; + botInline?: boolean; /** * Current launch init data. Can be missing in case, application was launched via @@ -29,19 +29,24 @@ export interface LaunchParams { platform: Platform; /** - * Mini App palette settings. + * True if application is required to show the Settings Button. */ - themeParams: ThemeParamsParsed; + showSettings?: boolean; /** - * True if Mini App is currently launched in inline mode. + * Start parameter passed in the application link. */ - botInline?: boolean; + startParam?: string; /** - * True if application is required to show the Settings Button. + * Mini App palette settings. */ - showSettings?: boolean; + themeParams: ThemeParamsParsed; + + /** + * Current Mini Apps version. + */ + version: string; } export interface LaunchData { From 1d639bfc982cae6257853f73507fd7935bd75095 Mon Sep 17 00:00:00 2001 From: Vladislav Kibenko Date: Tue, 6 Feb 2024 00:21:20 +0300 Subject: [PATCH 2/4] docs(launch-params): add tgWebAppStartParam docs --- .../launch-parameters/common-information.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/apps/docs/platform/launch-parameters/common-information.md b/apps/docs/platform/launch-parameters/common-information.md index 160a1e452..e01e7d6b5 100644 --- a/apps/docs/platform/launch-parameters/common-information.md +++ b/apps/docs/platform/launch-parameters/common-information.md @@ -103,3 +103,22 @@ no other meaning to external developers. This parameter is being added in case the current application is launched in inline mode. This allows calling such Telegram Mini Apps method as [web_app_switch_inline_query](../apps-communication/methods.md#web-app-switch-inline-query). + +### `tgWebAppStartParam` + +This parameter is being included in case, bot link contains such query parameter as `startattach`, +or Direct Link contains the `startapp` query parameter. + +Here are the examples: + +- `https://t.me/botusername?startattach=PARAM` +- `https://t.me/botusername/appname?startapp=PARAM` + +In both of these cases, `tgWebAppStartParam` will be set to `"PARAM"`. + +::: info + +This launch parameter is not included in the location hash. Instead, it can be found in a +URL query parameters. + +::: \ No newline at end of file From b9effab9ad81de44543f5ab984e61c3acb33f308 Mon Sep 17 00:00:00 2001 From: Vladislav Kibenko Date: Tue, 6 Feb 2024 00:23:02 +0300 Subject: [PATCH 3/4] chore(launch-params): export retrieveFromUrl func --- packages/sdk/src/launch-params/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/sdk/src/launch-params/index.ts b/packages/sdk/src/launch-params/index.ts index 6bde52dff..479c6665b 100644 --- a/packages/sdk/src/launch-params/index.ts +++ b/packages/sdk/src/launch-params/index.ts @@ -6,6 +6,7 @@ export * from './parseLaunchParams.js'; export * from './retrieveCurrent.js'; export * from './retrieveFromLocation.js'; export * from './retrieveFromPerformance.js'; +export * from './retrieveFromUrl.js'; export * from './retrieveLaunchData.js'; export * from './serializeLaunchParams.js'; export * from './storage.js'; From c2de1d428a3f4434aa1588edb74db66c4f6874e4 Mon Sep 17 00:00:00 2001 From: Vladislav Kibenko Date: Tue, 6 Feb 2024 00:23:26 +0300 Subject: [PATCH 4/4] docs(changeset): Implement retrieveFromUrl launch params function. --- .changeset/yellow-trainers-run.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/yellow-trainers-run.md diff --git a/.changeset/yellow-trainers-run.md b/.changeset/yellow-trainers-run.md new file mode 100644 index 000000000..201d09837 --- /dev/null +++ b/.changeset/yellow-trainers-run.md @@ -0,0 +1,5 @@ +--- +"@tma.js/sdk": minor +--- + +Implement retrieveFromUrl launch params function.