Interactive /mybots menu for @BotFather
Button-driven bot management: paginated picker, per-bot API token / revoke, Edit Bot (name/description/about/commands/botpic), Bot Settings toggles (inline/groups/privacy), and delete. Navigation edits the menu message in place via a new editServiceBotMessage helper. Edit Botpic accepts a photo the user sends to @BotFather and sets it as the bot's profile photo (new files.SetAvatarFromExistingPhoto, wired through bots.SetBotUserpic / WithBotAvatarStore); photos.uploadProfilePhoto does not accept a bot target so this is the only route.
This commit is contained in:
parent
196f90f9b1
commit
f474a360d7
10 changed files with 1467 additions and 26 deletions
|
|
@ -869,12 +869,13 @@ func TestVerifyBotCallbackForForeignBotIsNotClaimed(t *testing.T) {
|
|||
}); handled || err != nil {
|
||||
t.Fatalf("foreign bot callback handled=%v err=%v, want (false, nil)", handled, err)
|
||||
}
|
||||
// A built-in bot with no keyboards is claimed but answered empty, so the click
|
||||
// cannot hang for the whole callback timeout.
|
||||
// @BotFather owns the /mybots menu now: a click with no active dialog is
|
||||
// claimed and answered with the expired-button alert, so it cannot hang for
|
||||
// the whole callback timeout.
|
||||
answer, handled, err := svc.OnCallbackQuery(context.Background(), domain.BotCallbackQuery{
|
||||
BotUserID: domain.BotFatherUserID, UserID: 900, Data: []byte("x"),
|
||||
BotUserID: domain.BotFatherUserID, UserID: 900, Data: []byte("bf:x"),
|
||||
})
|
||||
if !handled || err != nil || answer.Message != "" {
|
||||
if !handled || err != nil || !answer.Alert || answer.Message == "" {
|
||||
t.Fatalf("BotFather callback = (%+v, %v, %v)", answer, handled, err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue