Skip to content

Commit

Permalink
Merge pull request #222 from Telegram-Mini-Apps/feature/launch-params…
Browse files Browse the repository at this point in the history
…-from-url

Feature/launch params from url
  • Loading branch information
heyqbnk authored Feb 5, 2024
2 parents a18fdf8 + c2de1d4 commit effa93e
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/yellow-trainers-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tma.js/sdk": minor
---

Implement retrieveFromUrl launch params function.
19 changes: 19 additions & 0 deletions apps/docs/platform/launch-parameters/common-information.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

:::
19 changes: 19 additions & 0 deletions packages/sdk/src/launch-params/__tests__/retrieveFromUrl.ts
Original file line number Diff line number Diff line change
@@ -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',
});
});
1 change: 1 addition & 0 deletions packages/sdk/src/launch-params/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk/src/launch-params/launchParamsParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export function launchParamsParser() {
type: boolean().optional(),
from: 'tgWebAppShowSettings',
},
startParam: {
type: string().optional(),
from: 'tgWebAppStartParam',
},
themeParams: {
type: themeParamsParser(),
from: 'tgWebAppThemeParams',
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/src/launch-params/retrieveFromLocation.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { parseLaunchParams } from './parseLaunchParams.js';
import { retrieveFromUrl } from './retrieveFromUrl.js';
import type { LaunchParams } from './types.js';

/**
* Attempts to extract launch parameters from the current window location hash.
* @throws {Error} window.location.hash contains invalid data.
*/
export function retrieveFromLocation(): LaunchParams {
return parseLaunchParams(window.location.hash.slice(1));
return retrieveFromUrl(window.location.href);
}
9 changes: 2 additions & 7 deletions packages/sdk/src/launch-params/retrieveFromPerformance.ts
Original file line number Diff line number Diff line change
@@ -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';

/**
Expand All @@ -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);
}
19 changes: 19 additions & 0 deletions packages/sdk/src/launch-params/retrieveFromUrl.ts
Original file line number Diff line number Diff line change
@@ -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);
}
21 changes: 13 additions & 8 deletions packages/sdk/src/launch-params/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down

0 comments on commit effa93e

Please sign in to comment.