Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions src/__tests__/bot-commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,42 @@ describe("parseCommand", () => {
});

describe("bot messages", () => {
it("createdMessage (ru) has spawn link and command", () => {
it("createdMessage (ru) includes bootstrap steps and links", () => {
const message = createdMessage(
"ru",
"demo-app",
"npx -y @spawn-dock/cli spawn --token pair_demo",
"spawndock://spawn?token=pair_demo",
"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).not.toContain("Preview URL:");
expect(message).not.toContain("Telegram Link:");
expect(message).toContain("Нажми на ссылку, чтобы открыть рабочее окружение:");
expect(message).toContain("spawndock://spawn?token=pair_demo");
expect(message).toContain("Или запусти команду локально в терминале:");
expect(message).toContain("npx -y @spawn-dock/cli spawn --token pair_demo");
expect(message).toContain("Проект demo-app создан.");
expect(message).toContain("1. Запусти bootstrap-команду локально:");
expect(message).toContain("npx @spawn-dock/create --token pair_demo");
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).toContain("TMA URL:");
});

it("createdMessage (en) uses English copy", () => {
it("createdMessage (en) uses English bootstrap copy", () => {
const message = createdMessage(
"en",
"demo-app",
"npx -y @spawn-dock/cli spawn --token pair_demo",
"spawndock://spawn?token=pair_demo",
"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");
expect(message).toContain("Click the link to open the workspace:");
expect(message).toContain("spawndock://spawn?token=pair_demo");
expect(message).toContain("Project demo-app created.");
expect(message).toContain("1. Run the bootstrap command locally:");
expect(message).toContain("npx @spawn-dock/create --token pair_demo");
expect(message).toContain("2. After bootstrap, run:");
expect(message).toContain("pnpm run dev");
});

it("includes TMA and preview links in launchMessage", () => {
Expand Down
43 changes: 32 additions & 11 deletions src/bot/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,26 +96,47 @@ export function launchUsageMessage(locale: BotLocale): string {
return "Use /launch <slug> to get the preview URL and current tunnel status.";
}

export function createdMessage(locale: BotLocale, slug: string, spawnCmd: string, spawnLink: string): string {
export function createdMessage(
locale: BotLocale,
slug: string,
bootstrapCmd: string,
previewUrl: string,
telegramMiniAppUrl: string,
tmaUrl: string,
): string {
if (locale === "ru") {
return [
`Проект <b>${esc(slug)}</b> создан.`,
`Проект ${esc(slug)} создан.`,
"",
"1. Запусти bootstrap-команду локально:",
`<code>${esc(bootstrapCmd)}</code>`,
"",
"Эту команду можно запускать повторно для этого проекта.",
"",
"Нажми на ссылку, чтобы открыть рабочее окружение:",
renderLink(spawnLink),
"2. После bootstrap запусти:",
"<code>pnpm run dev</code>",
"",
"Или запусти команду локально в терминале:",
`<code>${esc(spawnCmd)}</code>`
"Ссылки:",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
`TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}
return [
`Project <b>${esc(slug)}</b> created.`,
`Project ${esc(slug)} created.`,
"",
"1. Run the bootstrap command locally:",
`<code>${esc(bootstrapCmd)}</code>`,
"",
"Click the link to open the workspace:",
renderLink(spawnLink),
"You can run this command again for the same project.",
"",
"Or run this command locally in your terminal:",
`<code>${esc(spawnCmd)}</code>`
"2. After bootstrap, run:",
"<code>pnpm run dev</code>",
"",
"Links:",
`Preview URL: ${renderLink(previewUrl)}`,
`Telegram Link: ${renderLink(telegramMiniAppUrl)}`,
`TMA URL: ${renderLink(tmaUrl)}`,
].join("\n");
}

Expand Down
12 changes: 9 additions & 3 deletions src/bot/polling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,15 @@ async function processUpdate(cfg: ReturnType<typeof readBotConfig>, update: Tele
clearTimeout(ackTimeout);
const slug = data.project.slug;
const token = data.pairingToken.token;
const spawnCmd = `npx -y @spawn-dock/cli spawn --token ${token}`;
const spawnLink = `spawndock://spawn?token=${token}`;
await sendMessage(cfg.telegramBotToken, msg.chat.id, createdMessage(locale, slug, spawnCmd, spawnLink));
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),
);
return;
}

Expand Down