botfather: /start <bot> opens that bot's menu

The "Manage Bot" button on a bot's profile deep-links to @BotFather with
start=<bot username>. parseBotCommand dropped the argument, so /start <bot>
just replied with the generic greeting instead of the per-bot menu.

Route "/start <arg>" to the bot's "What do you want to do?" screen (same as
/mybots then tapping the bot) when <arg> names one of the sender's own bots by
username or id; empty or unknown args keep the greeting.
This commit is contained in:
Astra 2026-09-09 15:03:53 +01:00
parent 236e9ed25a
commit 86f9b61336
2 changed files with 89 additions and 0 deletions

View file

@ -202,6 +202,40 @@ func TestMyBotsBotMenuAndBack(t *testing.T) {
}
}
func TestBotFatherStartWithBotOpensItsMenu(t *testing.T) {
svc, users, _, messages := newTestService(t)
owner := newOwner(t, users, "+2011")
makeBots(t, svc, owner.ID, 2)
// "/start <bot>" is the "Manage Bot" deep link: it lands on the per-bot menu.
body := sendToBotFather(t, svc, messages, owner, "/start mb0_bot")
if !strings.Contains(body, "@mb0_bot") || !strings.Contains(body, "What do you want to do?") {
t.Fatalf("/start mb0_bot reply = %q", body)
}
menu := botFatherUserReply(t, messages, owner.ID)
for _, want := range []string{"API Token", "Edit Bot", "Bot Settings", "Delete Bot", "Back to bots"} {
if !mybotsHasButton(menu, want) {
t.Fatalf("start menu missing %q: %+v", want, menu.ReplyMarkup)
}
}
// The buttons are live (state was saved), so Edit Bot works from here.
_, edit := pressBotFather(t, svc, messages, owner.ID, "Edit Bot")
if !strings.Contains(edit.Body, "@mb0_bot") {
t.Fatalf("edit menu after /start = %q", edit.Body)
}
// A leading @ and an unknown/foreign bot fall back to the greeting.
if body := sendToBotFather(t, svc, messages, owner, "/start @mb1_bot"); !strings.Contains(body, "@mb1_bot") {
t.Fatalf("/start @mb1_bot reply = %q", body)
}
if body := sendToBotFather(t, svc, messages, owner, "/start not_a_real_bot"); !strings.Contains(body, "create a new bot") {
t.Fatalf("/start unknown reply = %q, want greeting", body)
}
if body := sendToBotFather(t, svc, messages, owner, "/start"); !strings.Contains(body, "create a new bot") {
t.Fatalf("bare /start reply = %q, want greeting", body)
}
}
func TestMyBotsTokenAndRevoke(t *testing.T) {
svc, users, bots, messages := newTestService(t)
owner := newOwner(t, users, "+2003")