From e2b658b794961e01c8644e170e6e3c3a530957b8 Mon Sep 17 00:00:00 2001
From: skulidropek <66840575+skulidropek@users.noreply.github.com>
Date: Wed, 25 Mar 2026 20:35:14 +0000
Subject: [PATCH 1/2] fix(bot): remove TMA URL from bot messages
---
src/__tests__/bot-commands.test.ts | 23 +++++++++++++++++------
src/bot/i18n.ts | 8 --------
src/bot/polling.ts | 5 ++---
src/bot/preview-notify.ts | 2 +-
4 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/src/__tests__/bot-commands.test.ts b/src/__tests__/bot-commands.test.ts
index e9ed3a1..26e77ee 100644
--- a/src/__tests__/bot-commands.test.ts
+++ b/src/__tests__/bot-commands.test.ts
@@ -1,6 +1,7 @@
// src/__tests__/bot-commands.test.ts
import { describe, it, expect } from "vitest";
import { createdMessage, launchMessage, normalizeTelegramCommandText, parseCommand } from "../bot/commands.js";
+import { previewReadyMessage } from "../bot/i18n.js";
describe("parseCommand", () => {
it("parses /start", () => {
@@ -56,7 +57,6 @@ describe("bot messages", () => {
"npx @spawn-dock/create --token pair_demo",
"https://spawn-dock.example/preview/demo-app",
"https://t.me/TMASpawnerBot/tma?startapp=demo-app",
- "https://spawn-dock.example/tma?tgWebAppStartParam=demo-app",
);
expect(message).toContain("Проект demo-app создан.");
@@ -67,7 +67,7 @@ describe("bot messages", () => {
expect(message).toContain("pnpm run dev");
expect(message).toContain("Preview URL:");
expect(message).toContain("Telegram Link:");
- expect(message).toContain("TMA URL:");
+ expect(message).not.toContain("TMA URL:");
});
it("createdMessage (en) uses English bootstrap copy", () => {
@@ -77,7 +77,6 @@ describe("bot messages", () => {
"npx @spawn-dock/create --token pair_demo",
"https://spawn-dock.example/preview/demo-app",
"https://t.me/TMASpawnerBot/tma?startapp=demo-app",
- "https://spawn-dock.example/tma?tgWebAppStartParam=demo-app",
);
expect(message).toContain("Project demo-app created.");
@@ -87,20 +86,32 @@ describe("bot messages", () => {
expect(message).toContain("pnpm run dev");
});
- it("includes TMA and preview links in launchMessage", () => {
+ it("includes preview and telegram links in launchMessage without TMA URL", () => {
const message = launchMessage(
"en",
"demo-app",
"connected",
- "https://example.com/tma?tgWebAppStartParam=demo-app",
"https://example.com/preview/demo-app",
"https://t.me/rustgpt_bot/tma?startapp=demo-app",
);
- expect(message).toContain("TMA URL:");
+ expect(message).not.toContain("TMA URL:");
expect(message).toContain("Telegram Link:");
expect(message).toContain("Preview URL:");
expect(message).toContain("Tunnel status:");
expect(message).toContain("npm run agent");
});
+
+ it("previewReadyMessage omits TMA URL", () => {
+ const message = previewReadyMessage(
+ "ru",
+ "demo-app",
+ "https://example.com/preview/demo-app",
+ "https://t.me/rustgpt_bot/tma?startapp=demo-app",
+ );
+
+ expect(message).toContain("Preview URL:");
+ expect(message).toContain("Telegram Link:");
+ expect(message).not.toContain("TMA URL:");
+ });
});
diff --git a/src/bot/i18n.ts b/src/bot/i18n.ts
index 96739ac..83908e0 100644
--- a/src/bot/i18n.ts
+++ b/src/bot/i18n.ts
@@ -102,7 +102,6 @@ export function createdMessage(
bootstrapCmd: string,
previewUrl: string,
telegramMiniAppUrl: string,
- tmaUrl: string,
): string {
if (locale === "ru") {
return [
@@ -119,7 +118,6 @@ export function createdMessage(
"Ссылки:",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
- `TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}
return [
@@ -136,7 +134,6 @@ export function createdMessage(
"Links:",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
- `TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}
@@ -144,7 +141,6 @@ export function launchMessage(
locale: BotLocale,
slug: string,
status: "connected" | "offline",
- tmaUrl: string,
previewUrl: string,
telegramMiniAppUrl: string,
): string {
@@ -157,7 +153,6 @@ export function launchMessage(
locale === "ru" ? `Проект ${esc(slug)}.` : `Project ${esc(slug)}.`,
"",
`${statusLabel}: ${esc(status)}`,
- `TMA URL: ${renderLink(tmaUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
`Preview URL: ${renderLink(previewUrl)}`,
"",
@@ -235,7 +230,6 @@ export function previewReadyMessage(
slug: string,
previewUrl: string,
telegramMiniAppUrl: string,
- tmaUrl: string,
): string {
if (locale === "ru") {
return [
@@ -243,7 +237,6 @@ export function previewReadyMessage(
"",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
- `TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}
return [
@@ -251,6 +244,5 @@ export function previewReadyMessage(
"",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
- `TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}
diff --git a/src/bot/polling.ts b/src/bot/polling.ts
index 00ba26c..20c7f14 100644
--- a/src/bot/polling.ts
+++ b/src/bot/polling.ts
@@ -160,12 +160,11 @@ async function processUpdate(cfg: ReturnType, update: Tele
const token = data.pairingToken.token;
const bootstrapCmd = `npx @spawn-dock/create --token ${token}`;
const previewUrl = data.launchUrl;
- const tmaUrl = buildGatewayMiniAppUrl(previewUrl, slug);
const telegramMiniAppUrl = buildTelegramMiniAppUrl(cfg.telegramBotUsername, cfg.telegramMiniAppShortName, slug);
await sendMessage(
cfg.telegramBotToken,
msg.chat.id,
- createdMessage(locale, slug, bootstrapCmd, previewUrl, telegramMiniAppUrl, tmaUrl),
+ createdMessage(locale, slug, bootstrapCmd, previewUrl, telegramMiniAppUrl),
);
return;
}
@@ -197,7 +196,7 @@ async function processUpdate(cfg: ReturnType, update: Tele
await sendMessage(
cfg.telegramBotToken,
msg.chat.id,
- launchMessage(locale, cmd.slug, data.status, tmaUrl, previewUrl, telegramMiniAppUrl),
+ launchMessage(locale, cmd.slug, data.status, previewUrl, telegramMiniAppUrl),
{ tmaUrl, previewUrl, telegramMiniAppUrl, buttonLabels: buttons },
);
return;
diff --git a/src/bot/preview-notify.ts b/src/bot/preview-notify.ts
index 32facbe..5fbb66b 100644
--- a/src/bot/preview-notify.ts
+++ b/src/bot/preview-notify.ts
@@ -28,7 +28,7 @@ export async function notifyOwnerPreviewReady(input: {
const tmaUrl = buildGatewayMiniAppUrl(previewUrl, input.slug);
const telegramMiniAppUrl = buildTelegramMiniAppUrl(botUsername, miniAppShortName, input.slug);
- const html = previewReadyMessage(locale, input.slug, previewUrl, telegramMiniAppUrl, tmaUrl);
+ const html = previewReadyMessage(locale, input.slug, previewUrl, telegramMiniAppUrl);
await sendMessage(token, input.ownerTelegramId, html, {
tmaUrl,
From 337ade440753a03f55c51841bb28aac22cfbfaf7 Mon Sep 17 00:00:00 2001
From: skulidropek <66840575+skulidropek@users.noreply.github.com>
Date: Wed, 25 Mar 2026 20:38:26 +0000
Subject: [PATCH 2/2] fix(bot): keep links only in preview-ready message
---
src/__tests__/bot-commands.test.ts | 22 +++++++++++-----------
src/bot/i18n.ts | 15 +++++----------
src/bot/polling.ts | 6 ++----
src/bot/preview-notify.ts | 2 +-
4 files changed, 19 insertions(+), 26 deletions(-)
diff --git a/src/__tests__/bot-commands.test.ts b/src/__tests__/bot-commands.test.ts
index 26e77ee..e2720eb 100644
--- a/src/__tests__/bot-commands.test.ts
+++ b/src/__tests__/bot-commands.test.ts
@@ -50,13 +50,11 @@ describe("parseCommand", () => {
});
describe("bot messages", () => {
- it("createdMessage (ru) includes bootstrap steps and links", () => {
+ it("createdMessage (ru) includes bootstrap steps without links", () => {
const message = createdMessage(
"ru",
"demo-app",
"npx @spawn-dock/create --token pair_demo",
- "https://spawn-dock.example/preview/demo-app",
- "https://t.me/TMASpawnerBot/tma?startapp=demo-app",
);
expect(message).toContain("Проект demo-app создан.");
@@ -65,9 +63,10 @@ describe("bot messages", () => {
expect(message).toContain("Эту команду можно запускать повторно для этого проекта.");
expect(message).toContain("2. После bootstrap запусти:");
expect(message).toContain("pnpm run dev");
- expect(message).toContain("Preview URL:");
- expect(message).toContain("Telegram Link:");
+ expect(message).not.toContain("Preview URL:");
+ expect(message).not.toContain("Telegram Link:");
expect(message).not.toContain("TMA URL:");
+ expect(message).not.toContain("Ссылки:");
});
it("createdMessage (en) uses English bootstrap copy", () => {
@@ -75,8 +74,6 @@ describe("bot messages", () => {
"en",
"demo-app",
"npx @spawn-dock/create --token pair_demo",
- "https://spawn-dock.example/preview/demo-app",
- "https://t.me/TMASpawnerBot/tma?startapp=demo-app",
);
expect(message).toContain("Project demo-app created.");
@@ -84,34 +81,37 @@ describe("bot messages", () => {
expect(message).toContain("npx @spawn-dock/create --token pair_demo");
expect(message).toContain("2. After bootstrap, run:");
expect(message).toContain("pnpm run dev");
+ expect(message).not.toContain("Links:");
});
- it("includes preview and telegram links in launchMessage without TMA URL", () => {
+ it("includes TMA, preview, and telegram links in launchMessage", () => {
const message = launchMessage(
"en",
"demo-app",
"connected",
+ "https://example.com/tma?tgWebAppStartParam=demo-app",
"https://example.com/preview/demo-app",
"https://t.me/rustgpt_bot/tma?startapp=demo-app",
);
- expect(message).not.toContain("TMA URL:");
+ expect(message).toContain("TMA URL:");
expect(message).toContain("Telegram Link:");
expect(message).toContain("Preview URL:");
expect(message).toContain("Tunnel status:");
expect(message).toContain("npm run agent");
});
- it("previewReadyMessage omits TMA URL", () => {
+ it("previewReadyMessage keeps all links", () => {
const message = previewReadyMessage(
"ru",
"demo-app",
"https://example.com/preview/demo-app",
"https://t.me/rustgpt_bot/tma?startapp=demo-app",
+ "https://example.com/tma?tgWebAppStartParam=demo-app",
);
expect(message).toContain("Preview URL:");
expect(message).toContain("Telegram Link:");
- expect(message).not.toContain("TMA URL:");
+ expect(message).toContain("TMA URL:");
});
});
diff --git a/src/bot/i18n.ts b/src/bot/i18n.ts
index 83908e0..ca2a870 100644
--- a/src/bot/i18n.ts
+++ b/src/bot/i18n.ts
@@ -100,8 +100,6 @@ export function createdMessage(
locale: BotLocale,
slug: string,
bootstrapCmd: string,
- previewUrl: string,
- telegramMiniAppUrl: string,
): string {
if (locale === "ru") {
return [
@@ -114,10 +112,6 @@ export function createdMessage(
"",
"2. После bootstrap запусти:",
"pnpm run dev",
- "",
- "Ссылки:",
- `Preview URL: ${renderLink(previewUrl)}`,
- `Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
].join("\n");
}
return [
@@ -130,10 +124,6 @@ export function createdMessage(
"",
"2. After bootstrap, run:",
"pnpm run dev",
- "",
- "Links:",
- `Preview URL: ${renderLink(previewUrl)}`,
- `Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
].join("\n");
}
@@ -141,6 +131,7 @@ export function launchMessage(
locale: BotLocale,
slug: string,
status: "connected" | "offline",
+ tmaUrl: string,
previewUrl: string,
telegramMiniAppUrl: string,
): string {
@@ -153,6 +144,7 @@ export function launchMessage(
locale === "ru" ? `Проект ${esc(slug)}.` : `Project ${esc(slug)}.`,
"",
`${statusLabel}: ${esc(status)}`,
+ `TMA URL: ${renderLink(tmaUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
`Preview URL: ${renderLink(previewUrl)}`,
"",
@@ -230,6 +222,7 @@ export function previewReadyMessage(
slug: string,
previewUrl: string,
telegramMiniAppUrl: string,
+ tmaUrl: string,
): string {
if (locale === "ru") {
return [
@@ -237,6 +230,7 @@ export function previewReadyMessage(
"",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
+ `TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}
return [
@@ -244,5 +238,6 @@ export function previewReadyMessage(
"",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
+ `TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}
diff --git a/src/bot/polling.ts b/src/bot/polling.ts
index 20c7f14..7756251 100644
--- a/src/bot/polling.ts
+++ b/src/bot/polling.ts
@@ -159,12 +159,10 @@ async function processUpdate(cfg: ReturnType, update: Tele
const slug = data.project.slug;
const token = data.pairingToken.token;
const bootstrapCmd = `npx @spawn-dock/create --token ${token}`;
- const previewUrl = data.launchUrl;
- const telegramMiniAppUrl = buildTelegramMiniAppUrl(cfg.telegramBotUsername, cfg.telegramMiniAppShortName, slug);
await sendMessage(
cfg.telegramBotToken,
msg.chat.id,
- createdMessage(locale, slug, bootstrapCmd, previewUrl, telegramMiniAppUrl),
+ createdMessage(locale, slug, bootstrapCmd),
);
return;
}
@@ -196,7 +194,7 @@ async function processUpdate(cfg: ReturnType, update: Tele
await sendMessage(
cfg.telegramBotToken,
msg.chat.id,
- launchMessage(locale, cmd.slug, data.status, previewUrl, telegramMiniAppUrl),
+ launchMessage(locale, cmd.slug, data.status, tmaUrl, previewUrl, telegramMiniAppUrl),
{ tmaUrl, previewUrl, telegramMiniAppUrl, buttonLabels: buttons },
);
return;
diff --git a/src/bot/preview-notify.ts b/src/bot/preview-notify.ts
index 5fbb66b..32facbe 100644
--- a/src/bot/preview-notify.ts
+++ b/src/bot/preview-notify.ts
@@ -28,7 +28,7 @@ export async function notifyOwnerPreviewReady(input: {
const tmaUrl = buildGatewayMiniAppUrl(previewUrl, input.slug);
const telegramMiniAppUrl = buildTelegramMiniAppUrl(botUsername, miniAppShortName, input.slug);
- const html = previewReadyMessage(locale, input.slug, previewUrl, telegramMiniAppUrl);
+ const html = previewReadyMessage(locale, input.slug, previewUrl, telegramMiniAppUrl, tmaUrl);
await sendMessage(token, input.ownerTelegramId, html, {
tmaUrl,