rpc: add android startup and messaging compat
(cherry picked from commit d718593156cc7310105007f37645948c17637e0a)
This commit is contained in:
parent
fc01346160
commit
b4e47c894f
11 changed files with 184 additions and 2 deletions
|
|
@ -4,12 +4,15 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/gotd/td/bin"
|
||||
"github.com/gotd/td/tg"
|
||||
|
||||
"telesrv/internal/compat/tdesktop"
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
const legacyAccountRegisterDeviceTypeID uint32 = 0x637ea878
|
||||
|
||||
// registerAccount 注册 account.* RPC handler。
|
||||
func (r *Router) registerAccount(d *tg.ServerDispatcher) {
|
||||
d.OnAccountRegisterDevice(func(ctx context.Context, req *tg.AccountRegisterDeviceRequest) (bool, error) {
|
||||
|
|
@ -136,6 +139,12 @@ func (r *Router) registerAccount(d *tg.ServerDispatcher) {
|
|||
}
|
||||
return &tg.AccountSavedMusicIDs{IDs: []int64{}}, nil
|
||||
})
|
||||
d.OnAccountGetSavedRingtones(func(ctx context.Context, hash int64) (tg.AccountSavedRingtonesClass, error) {
|
||||
if _, _, err := r.currentUserID(ctx); err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
return &tg.AccountSavedRingtones{Hash: 0, Ringtones: []tg.DocumentClass{}}, nil
|
||||
})
|
||||
d.OnAccountGetAccountTTL(r.onAccountGetAccountTTL)
|
||||
d.OnAccountSetAccountTTL(func(ctx context.Context, ttl tg.AccountDaysTTL) (bool, error) {
|
||||
return true, nil
|
||||
|
|
@ -204,6 +213,23 @@ func (r *Router) onAccountGetPasswordSettings(ctx context.Context, password tg.I
|
|||
return tgPasswordSettings(settings), nil
|
||||
}
|
||||
|
||||
func (r *Router) handleLegacyAccountRegisterDevice(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||
if err := b.ConsumeID(legacyAccountRegisterDeviceTypeID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := b.Int(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := b.String(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &tg.BoolTrue{}, nil
|
||||
}
|
||||
|
||||
func (r *Router) onAccountUpdatePasswordSettings(ctx context.Context, req *tg.AccountUpdatePasswordSettingsRequest) (bool, error) {
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ func (r *Router) dispatchCompat(ctx context.Context, b *bin.Buffer, id uint32) (
|
|||
)
|
||||
|
||||
switch id {
|
||||
case legacyAccountRegisterDeviceTypeID:
|
||||
name = "account.registerDevice#637ea878"
|
||||
enc, err = r.handleLegacyAccountRegisterDevice(ctx, b)
|
||||
case legacyUpdatesGetDifferenceTypeID:
|
||||
name = "updates.getDifference#25939651"
|
||||
enc, err = r.handleLegacyUpdatesGetDifference(ctx, b)
|
||||
case legacyLangpackGetLangPackTypeID:
|
||||
name = "langpack.getLangPack#9ab5c58e"
|
||||
enc, err = r.handleLegacyLangpackGetLangPack(ctx, b)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"unicode/utf8"
|
||||
|
||||
"github.com/gotd/td/tg"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"telesrv/internal/app/contacts"
|
||||
"telesrv/internal/compat/tdesktop"
|
||||
|
|
@ -42,6 +43,12 @@ func (r *Router) registerContacts(d *tg.ServerDispatcher) {
|
|||
return tdesktop.TopPeers(), nil
|
||||
})
|
||||
d.OnContactsGetBlocked(r.onContactsGetBlocked)
|
||||
d.OnContactsGetBirthdays(func(ctx context.Context) (*tg.ContactsContactBirthdays, error) {
|
||||
if _, _, err := r.currentUserID(ctx); err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
return &tg.ContactsContactBirthdays{Contacts: []tg.ContactBirthday{}, Users: []tg.UserClass{}}, nil
|
||||
})
|
||||
d.OnContactsGetSponsoredPeers(func(ctx context.Context, q string) (tg.ContactsSponsoredPeersClass, error) {
|
||||
if utf8.RuneCountInString(q) > maxContactSearchQLen {
|
||||
return nil, limitInvalidErr()
|
||||
|
|
@ -250,6 +257,7 @@ func (r *Router) onContactsImportContacts(ctx context.Context, input []tg.InputP
|
|||
}
|
||||
res, err := r.deps.Contacts.ImportContacts(ctx, userID, items)
|
||||
if err != nil {
|
||||
r.log.Warn("contacts.importContacts service failed", append(r.contextLogFields(ctx), zap.Error(err), zap.Int("contacts", len(items)))...)
|
||||
return nil, internalErr()
|
||||
}
|
||||
out := &tg.ContactsImportedContacts{
|
||||
|
|
@ -267,18 +275,22 @@ func (r *Router) onContactsImportContacts(ctx context.Context, input []tg.InputP
|
|||
peer := domain.Peer{Type: domain.PeerTypeUser, ID: contact.User.ID}
|
||||
settings, err := r.deps.Contacts.GetPeerSettings(ctx, userID, peer)
|
||||
if err != nil {
|
||||
r.log.Warn("contacts.importContacts peer settings failed", append(r.contextLogFields(ctx), zap.Error(err), zap.Int64("peer_user_id", contact.User.ID))...)
|
||||
return nil, internalErr()
|
||||
}
|
||||
if err := r.recordPeerSettings(ctx, userID, peer, settings); err != nil {
|
||||
r.log.Warn("contacts.importContacts record peer settings failed", append(r.contextLogFields(ctx), zap.Error(err), zap.Int64("peer_user_id", contact.User.ID))...)
|
||||
return nil, internalErr()
|
||||
}
|
||||
if contact.Mutual {
|
||||
if err := r.recordAcceptedContactTargetUpdates(ctx, userID, contact.User.ID); err != nil {
|
||||
r.log.Warn("contacts.importContacts record accepted target failed", append(r.contextLogFields(ctx), zap.Error(err), zap.Int64("peer_user_id", contact.User.ID))...)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := r.recordContactsReset(ctx, userID); err != nil {
|
||||
r.log.Warn("contacts.importContacts record contacts reset failed", append(r.contextLogFields(ctx), zap.Error(err), zap.Int("contacts", len(items)))...)
|
||||
return nil, internalErr()
|
||||
}
|
||||
r.pushContactsReset(ctx, userID)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ func (r *Router) registerHelp(d *tg.ServerDispatcher) {
|
|||
d.OnHelpGetNearestDC(func(ctx context.Context) (*tg.NearestDC, error) {
|
||||
return tdesktop.NearestDC(r.cfg.DC), nil
|
||||
})
|
||||
d.OnHelpGetInviteText(func(ctx context.Context) (*tg.HelpInviteText, error) {
|
||||
return &tg.HelpInviteText{Message: "Join me on Telegram."}, nil
|
||||
})
|
||||
d.OnHelpGetAppConfig(func(ctx context.Context, hash int) (tg.HelpAppConfigClass, error) {
|
||||
if r.deps.Help == nil {
|
||||
return tdesktop.AppConfig(hash), nil
|
||||
|
|
|
|||
|
|
@ -79,6 +79,60 @@ func TestLegacyLangpackGetStrings(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLegacyUpdatesGetDifference(t *testing.T) {
|
||||
r := New(Config{DC: 2, IP: "127.0.0.1", Port: 2398}, Deps{}, zaptest.NewLogger(t), clock.System)
|
||||
|
||||
var flags bin.Fields
|
||||
flags.Set(0)
|
||||
var in bin.Buffer
|
||||
in.PutID(legacyUpdatesGetDifferenceTypeID)
|
||||
if err := flags.Encode(&in); err != nil {
|
||||
t.Fatalf("encode flags: %v", err)
|
||||
}
|
||||
in.PutInt(10)
|
||||
in.PutInt(100)
|
||||
in.PutInt(123456)
|
||||
in.PutInt(0)
|
||||
|
||||
enc, err := r.Dispatch(WithUserID(androidClientContext(), 1000000001), [8]byte{}, 0, &in)
|
||||
if err != nil {
|
||||
t.Fatalf("dispatch legacy updates.getDifference: %v", err)
|
||||
}
|
||||
var out bin.Buffer
|
||||
if err := enc.Encode(&out); err != nil {
|
||||
t.Fatalf("encode response: %v", err)
|
||||
}
|
||||
var diff tg.UpdatesDifferenceEmpty
|
||||
if err := diff.Decode(&out); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLegacyAccountRegisterDevice(t *testing.T) {
|
||||
r := New(Config{DC: 2, IP: "127.0.0.1", Port: 2398}, Deps{}, zaptest.NewLogger(t), clock.System)
|
||||
|
||||
var in bin.Buffer
|
||||
in.PutID(legacyAccountRegisterDeviceTypeID)
|
||||
in.PutInt(2)
|
||||
in.PutString("android-fcm-token")
|
||||
|
||||
enc, err := r.Dispatch(WithUserID(androidClientContext(), 1000000001), [8]byte{}, 0, &in)
|
||||
if err != nil {
|
||||
t.Fatalf("dispatch legacy account.registerDevice: %v", err)
|
||||
}
|
||||
var out bin.Buffer
|
||||
if err := enc.Encode(&out); err != nil {
|
||||
t.Fatalf("encode response: %v", err)
|
||||
}
|
||||
ok, err := tg.DecodeBool(&out)
|
||||
if err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
if _, ok := ok.(*tg.BoolTrue); !ok {
|
||||
t.Fatalf("legacy account.registerDevice = false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func assertLangpackLanguages(t *testing.T, r *Router, ctx context.Context, in *bin.Buffer) {
|
||||
t.Helper()
|
||||
enc, err := r.Dispatch(ctx, [8]byte{}, 0, in)
|
||||
|
|
|
|||
|
|
@ -183,6 +183,12 @@ func (r *Router) registerMessages(d *tg.ServerDispatcher) {
|
|||
d.OnMessagesGetStickers(func(ctx context.Context, req *tg.MessagesGetStickersRequest) (tg.MessagesStickersClass, error) {
|
||||
return tdesktop.Stickers(), nil
|
||||
})
|
||||
d.OnMessagesGetArchivedStickers(func(ctx context.Context, req *tg.MessagesGetArchivedStickersRequest) (*tg.MessagesArchivedStickers, error) {
|
||||
return &tg.MessagesArchivedStickers{
|
||||
Count: 0,
|
||||
Sets: []tg.StickerSetCoveredClass{},
|
||||
}, nil
|
||||
})
|
||||
d.OnMessagesGetStickerSet(r.onMessagesGetStickerSet)
|
||||
d.OnMessagesGetEmojiGroups(func(ctx context.Context, hash int) (tg.MessagesEmojiGroupsClass, error) {
|
||||
return tdesktop.EmojiGroups(), nil
|
||||
|
|
|
|||
|
|
@ -10,6 +10,17 @@ import (
|
|||
|
||||
// registerPayments 注册第一阶段 TDesktop 启动所需 payments.* RPC 兼容响应。
|
||||
func (r *Router) registerPayments(d *tg.ServerDispatcher) {
|
||||
d.OnPaymentsGetStarsStatus(func(ctx context.Context, req *tg.PaymentsGetStarsStatusRequest) (*tg.PaymentsStarsStatus, error) {
|
||||
balance := tg.StarsAmountClass(&tg.StarsAmount{})
|
||||
if req.GetTon() {
|
||||
balance = &tg.StarsTonAmount{}
|
||||
}
|
||||
return &tg.PaymentsStarsStatus{
|
||||
Balance: balance,
|
||||
Chats: []tg.ChatClass{},
|
||||
Users: []tg.UserClass{},
|
||||
}, nil
|
||||
})
|
||||
d.OnPaymentsGetStarGiftActiveAuctions(func(ctx context.Context, hash int64) (tg.PaymentsStarGiftActiveAuctionsClass, error) {
|
||||
return tdesktop.StarGiftActiveAuctions(), nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -401,6 +401,7 @@ func TestTDesktopStartupRPCsEncode(t *testing.T) {
|
|||
{name: "help.getPromoData", req: &tg.HelpGetPromoDataRequest{}},
|
||||
{name: "help.getTermsOfServiceUpdate", req: &tg.HelpGetTermsOfServiceUpdateRequest{}},
|
||||
{name: "help.getPremiumPromo", req: &tg.HelpGetPremiumPromoRequest{}},
|
||||
{name: "help.getInviteText", req: &tg.HelpGetInviteTextRequest{}},
|
||||
{name: "auth.initPasskeyLogin", req: &tg.AuthInitPasskeyLoginRequest{APIID: 4, APIHash: "test"}},
|
||||
{name: "account.getPassword", req: &tg.AccountGetPasswordRequest{}},
|
||||
{name: "account.getNotifySettings", req: &tg.AccountGetNotifySettingsRequest{Peer: &tg.InputNotifyUsers{}}},
|
||||
|
|
@ -426,8 +427,10 @@ func TestTDesktopStartupRPCsEncode(t *testing.T) {
|
|||
{name: "account.getPasskeys", req: &tg.AccountGetPasskeysRequest{}},
|
||||
{name: "account.getAutoDownloadSettings", req: &tg.AccountGetAutoDownloadSettingsRequest{}},
|
||||
{name: "account.getSavedMusicIds", req: &tg.AccountGetSavedMusicIDsRequest{}},
|
||||
{name: "account.getSavedRingtones", req: &tg.AccountGetSavedRingtonesRequest{}},
|
||||
{name: "account.resetPassword", req: &tg.AccountResetPasswordRequest{}},
|
||||
{name: "account.updateStatus", req: &tg.AccountUpdateStatusRequest{Offline: true}},
|
||||
{name: "payments.getStarsStatus", req: &tg.PaymentsGetStarsStatusRequest{Peer: &tg.InputPeerSelf{}}},
|
||||
{name: "updates.getDifference", req: &tg.UpdatesGetDifferenceRequest{}},
|
||||
{name: "users.getFullUser", req: &tg.UsersGetFullUserRequest{ID: &tg.InputUserSelf{}}},
|
||||
{name: "users.getSavedMusic", req: &tg.UsersGetSavedMusicRequest{ID: &tg.InputUserSelf{}, Limit: 20}},
|
||||
|
|
@ -439,6 +442,7 @@ func TestTDesktopStartupRPCsEncode(t *testing.T) {
|
|||
{name: "messages.getAvailableReactions", req: &tg.MessagesGetAvailableReactionsRequest{}},
|
||||
{name: "messages.getAvailableEffects", req: &tg.MessagesGetAvailableEffectsRequest{}},
|
||||
{name: "messages.getStickers", req: &tg.MessagesGetStickersRequest{}},
|
||||
{name: "messages.getArchivedStickers", req: &tg.MessagesGetArchivedStickersRequest{Limit: 20}},
|
||||
{name: "messages.getStickerSet", req: &tg.MessagesGetStickerSetRequest{Stickerset: &tg.InputStickerSetEmpty{}}},
|
||||
{name: "messages.getEmojiGroups", req: &tg.MessagesGetEmojiGroupsRequest{}},
|
||||
{name: "messages.getEmojiStickerGroups", req: &tg.MessagesGetEmojiStickerGroupsRequest{}},
|
||||
|
|
@ -459,12 +463,15 @@ func TestTDesktopStartupRPCsEncode(t *testing.T) {
|
|||
{name: "contacts.getContacts", req: &tg.ContactsGetContactsRequest{}},
|
||||
{name: "contacts.search", req: &tg.ContactsSearchRequest{Q: "Test", Limit: 20}},
|
||||
{name: "contacts.getBlocked", req: &tg.ContactsGetBlockedRequest{Limit: 20}},
|
||||
{name: "contacts.getBirthdays", req: &tg.ContactsGetBirthdaysRequest{}},
|
||||
{name: "contacts.getTopPeers", req: &tg.ContactsGetTopPeersRequest{Correspondents: true, Limit: 10}},
|
||||
{name: "contacts.getSponsoredPeers", req: &tg.ContactsGetSponsoredPeersRequest{Q: "Test"}},
|
||||
{name: "stories.getAllStories", req: &tg.StoriesGetAllStoriesRequest{}},
|
||||
{name: "stories.getStoriesArchive", req: &tg.StoriesGetStoriesArchiveRequest{Peer: &tg.InputPeerSelf{}, Limit: 20}},
|
||||
{name: "stories.getPinnedStories", req: &tg.StoriesGetPinnedStoriesRequest{Peer: &tg.InputPeerSelf{}, Limit: 20}},
|
||||
{name: "stories.getAlbums", req: &tg.StoriesGetAlbumsRequest{Peer: &tg.InputPeerSelf{}}},
|
||||
{name: "stories.getAllReadPeerStories", req: &tg.StoriesGetAllReadPeerStoriesRequest{}},
|
||||
{name: "stories.getPeerMaxIDs", req: &tg.StoriesGetPeerMaxIDsRequest{ID: []tg.InputPeerClass{&tg.InputPeerSelf{}}}},
|
||||
{name: "payments.getStarGiftActiveAuctions", req: &tg.PaymentsGetStarGiftActiveAuctionsRequest{}},
|
||||
{name: "payments.getSavedStarGifts", req: &tg.PaymentsGetSavedStarGiftsRequest{Peer: &tg.InputPeerSelf{}, Limit: 20}},
|
||||
{name: "payments.getSavedStarGift", req: &tg.PaymentsGetSavedStarGiftRequest{Stargift: []tg.InputSavedStarGiftClass{}}},
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@ func (r *Router) registerStories(d *tg.ServerDispatcher) {
|
|||
d.OnStoriesGetAlbums(func(ctx context.Context, req *tg.StoriesGetAlbumsRequest) (tg.StoriesAlbumsClass, error) {
|
||||
return tdesktop.StoryAlbums(), nil
|
||||
})
|
||||
d.OnStoriesGetAllReadPeerStories(func(ctx context.Context) (tg.UpdatesClass, error) {
|
||||
return tgEmptyUpdates(int(r.clock.Now().Unix())), nil
|
||||
})
|
||||
d.OnStoriesGetPeerMaxIDs(func(ctx context.Context, id []tg.InputPeerClass) ([]tg.RecentStory, error) {
|
||||
out := make([]tg.RecentStory, len(id))
|
||||
return out, nil
|
||||
})
|
||||
d.OnStoriesSendReaction(r.onStoriesSendReaction)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/gotd/td/bin"
|
||||
"github.com/gotd/td/tg"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
const updatesTooLongNudgeDelay = 300 * time.Millisecond
|
||||
const legacyUpdatesGetDifferenceTypeID uint32 = 0x25939651
|
||||
|
||||
// registerUpdates 注册 updates.* RPC handler。
|
||||
func (r *Router) registerUpdates(d *tg.ServerDispatcher) {
|
||||
|
|
@ -71,6 +73,42 @@ func (r *Router) onUpdatesGetDifference(ctx context.Context, req *tg.UpdatesGetD
|
|||
return tgUpdatesDifference(st), nil
|
||||
}
|
||||
|
||||
func (r *Router) handleLegacyUpdatesGetDifference(ctx context.Context, b *bin.Buffer) (bin.Encoder, error) {
|
||||
if err := b.ConsumeID(legacyUpdatesGetDifferenceTypeID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var flags bin.Fields
|
||||
if err := flags.Decode(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pts, err := b.Int()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ptsTotalLimit int
|
||||
if flags.Has(0) {
|
||||
ptsTotalLimit, err = b.Int()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
date, err := b.Int()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qts, err := b.Int()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.onUpdatesGetDifference(ctx, &tg.UpdatesGetDifferenceRequest{
|
||||
Flags: flags,
|
||||
Pts: pts,
|
||||
PtsTotalLimit: ptsTotalLimit,
|
||||
Date: date,
|
||||
Qts: qts,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Router) accountChannelDifferenceNudges(ctx context.Context, userID int64, sinceDate int) []domain.ChannelDifferenceNudge {
|
||||
if r.deps.Channels == nil || userID == 0 || sinceDate <= 0 {
|
||||
return nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue