botapi: implement getChat
Adds the getChat method to the HTTP Bot API gateway. Numeric chat_id only (no
@username). Resolution goes through the shared peer resolvers:
- user: ByID; unknown -> CHAT_NOT_FOUND
- channel/supergroup: ResolveChannel, so a public one resolves even when the bot
is not a member (projected as a preview); a private one the bot cannot access
-> CHAT_NOT_FOUND, a banned bot likewise
The Chat projection returns id (bot-api encoded), type ("channel" for a
broadcast, "supergroup" for a megagroup, "private" for a user), title, username,
first/last name, description, is_forum, and the scam/fake/verified flags.
This commit is contained in:
parent
78267ee0d3
commit
d022521d67
5 changed files with 221 additions and 0 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
|
|
@ -161,6 +162,60 @@ func TestGetMeUsesGateway(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetChatUsesGateway(t *testing.T) {
|
||||
bots := &fakeBotAPIBots{profile: domain.BotProfile{BotUserID: 1001, TokenSecret: "secret"}}
|
||||
gateway := &fakeBotAPIGateway{
|
||||
chat: domain.BotAPIChat{
|
||||
Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 42},
|
||||
Type: "supergroup",
|
||||
Title: "Test",
|
||||
Username: "test1",
|
||||
Description: "a test group",
|
||||
IsForum: true,
|
||||
},
|
||||
}
|
||||
h := (&handler{bots: bots, gateway: gateway}).routes()
|
||||
|
||||
rec := performBotAPIRequest(t, h, bots.profile, "getChat", `{"chat_id":-1000000000042}`)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d body = %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
if gateway.chatChatID != -1000000000042 {
|
||||
t.Fatalf("gateway chat_id = %d, want -1000000000042", gateway.chatChatID)
|
||||
}
|
||||
var resp struct {
|
||||
OK bool `json:"ok"`
|
||||
Result struct {
|
||||
ID int64 `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Username string `json:"username"`
|
||||
Description string `json:"description"`
|
||||
IsForum bool `json:"is_forum"`
|
||||
} `json:"result"`
|
||||
}
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("decode: %v", err)
|
||||
}
|
||||
if !resp.OK || resp.Result.ID != -1000000000042 || resp.Result.Type != "supergroup" ||
|
||||
resp.Result.Username != "test1" || resp.Result.Description != "a test group" || !resp.Result.IsForum {
|
||||
t.Fatalf("response = %s", rec.Body.String())
|
||||
}
|
||||
|
||||
// A private chat the bot cannot see comes back as chat not found.
|
||||
gateway.chatErr = errors.New("CHAT_NOT_FOUND")
|
||||
rec = performBotAPIRequest(t, h, bots.profile, "getChat", `{"chat_id":-1000000000099}`)
|
||||
if rec.Code != http.StatusBadRequest || !strings.Contains(rec.Body.String(), "CHAT_NOT_FOUND") {
|
||||
t.Fatalf("not-found response status=%d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
|
||||
// @username is rejected before it reaches the gateway.
|
||||
rec = performBotAPIRequest(t, h, bots.profile, "getChat", `{"chat_id":"@test1"}`)
|
||||
if rec.Code != http.StatusBadRequest || !strings.Contains(rec.Body.String(), "CHAT_ID_INVALID") {
|
||||
t.Fatalf("username response status=%d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBotCommandsPreserveEphemeralFlag(t *testing.T) {
|
||||
bots := &fakeBotAPIBots{profile: domain.BotProfile{BotUserID: 1001, TokenSecret: "secret"}}
|
||||
h := (&handler{bots: bots}).routes()
|
||||
|
|
@ -1442,6 +1497,10 @@ func (f *fakeWebAppService) SavePreparedInlineMessageFromBotAPI(_ context.Contex
|
|||
type fakeBotAPIGateway struct {
|
||||
self domain.User
|
||||
|
||||
chat domain.BotAPIChat
|
||||
chatErr error
|
||||
chatChatID int64
|
||||
|
||||
updates []domain.UpdateEvent
|
||||
updateBotID int64
|
||||
updateOffset int64
|
||||
|
|
@ -1502,6 +1561,11 @@ func (f *fakeBotAPIGateway) BotAPISelf(context.Context, int64) (domain.User, err
|
|||
return f.self, nil
|
||||
}
|
||||
|
||||
func (f *fakeBotAPIGateway) BotAPIChat(_ context.Context, _ int64, chatID int64) (domain.BotAPIChat, error) {
|
||||
f.chatChatID = chatID
|
||||
return f.chat, f.chatErr
|
||||
}
|
||||
|
||||
func (f *fakeBotAPIGateway) BotAPIUpdates(_ context.Context, botID int64, offset int64) ([]domain.UpdateEvent, error) {
|
||||
f.updateBotID = botID
|
||||
f.updateOffset = offset
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue