E2E chats + fix tests - #1
Conversation
- Add EncryptedChatAggregate with full DDD pattern (Id, State, Aggregate) - Add 4 domain events: EncryptionRequested/Accepted/Discarded, EncryptedMessageSent - Add 4 commands + command handlers for each event - Add EncryptedChatReadModel with MongoDB support - Add EncryptedChatDomainEventHandler for pushing updates to clients - Implement all 9 TL method handlers: requestEncryption, acceptEncryption, discardEncryption, sendEncrypted, sendEncryptedFile, sendEncryptedService, setEncryptedTyping, readEncryptedHistory, uploadEncryptedFile - Uncomment EncryptedChatReadModel in MongoDbReadModels.cs Server acts as opaque relay per Telegram E2E protocol: https://corefork.telegram.org/api/end-to-end
… + tests Implemented Handlers (33 total): Stories (9): - EditStoryHandler: edit story media/caption/privacy via EditStoryCommand - ReadStoriesHandler: mark stories as read, increment view counts - GetStoriesByIDHandler: fetch stories by ID, return TStoryItem/TStoryItemDeleted - GetStoriesViewsHandler: get view counts for multiple stories - GetStoryViewsListHandler: get story viewers list with counts - ExportStoryLinkHandler: generate t.me deep links for stories - SendReactionHandler: send emoji/custom reactions via AddStoryReactionCommand - ActivateStealthModeHandler: activate stealth mode (25min active, 1hr cooldown) - ReportHandler: accept story reports (self-hosted no-op) Bots (11): - GetBotCommandsHandler: query bot commands from BotReadModel - SetBotCommandsHandler: validate and accept bot command updates - ResetBotCommandsHandler: clear bot commands - GetBotInfoHandler: return bot name/about/description from BotReadModel - SetBotInfoHandler: accept bot info updates - GetBotMenuButtonHandler: return menu button config from BotReadModel - SetBotMenuButtonHandler: accept menu button configuration - GetAdminedBotsHandler: list bots owned by user - AllowSendMessageHandler: grant bot messaging permission - SetBotBroadcastDefaultAdminRightsHandler: set channel admin rights - SetBotGroupDefaultAdminRightsHandler: set group admin rights Contacts (2): - GetSavedHandler: return saved contacts list - ExportContactTokenHandler: generate temporary profile link token Help (4): - GetDeepLinkInfoHandler: return deep link info (self-hosted empty) - GetPassportConfigHandler: return passport config (not supported) - GetUserInfoHandler: TSF user info (self-hosted empty) - EditUserInfoHandler: TSF user info edit (self-hosted empty) Messages (7): - GetSplitRangesHandler: return single range (no DC split) - GetEmojiURLHandler: return emoji keywords URL - GetOnlinesHandler: get online member count in chat - ReadMentionsHandler: mark mentions as read - GetUnreadMentionsHandler: return unread mentions - GetDocumentByHashHandler: find document by SHA256 hash - DeletePhoneCallHistoryHandler: delete phone call history New Domain Commands (3): - EditStoryCommand + EditStoryCommandHandler - AddStoryReactionCommand + AddStoryReactionCommandHandler - ToggleStoryPinnedCommand + ToggleStoryPinnedCommandHandler Tests: - StoryAggregateTests (11 tests): create, edit, view, reaction, pin, delete - EditStoryCommandHandlerTests (3 tests): caption, media, privacy rules - AddStoryReactionCommandHandlerTests (2 tests): emoji, custom emoji - ToggleStoryPinnedCommandHandlerTests (2 tests): pin, unpin All handlers follow existing codebase patterns and reference corefork.telegram.org.
…tence Bots: - SetBotCommandsHandler: validate + persist commands to BotReadModel - ResetBotCommandsHandler: clear commands via MongoDB update - SetBotInfoHandler: update name/about/description with char limits - SetBotMenuButtonHandler: persist MiniAppUrl from TBotMenuButton - SetBotBroadcastDefaultAdminRightsHandler: store Flags from TChatAdminRights - SetBotGroupDefaultAdminRightsHandler: store Flags from TChatAdminRights - GetAdminedBotsHandler: use new GetBotsByOwnerUserIdQuery - AllowSendMessageHandler: validate bot, return TUpdatePeerSettings Messages: - ReadMentionsHandler: inject PTS/peer/accessHash helpers - GetOnlinesHandler: load members, check IUserReadModel.IsOnline - DeletePhoneCallHistoryHandler: return real PTS - GetUnreadMentionsHandler: add peer/accessHash validation - GetDocumentByHashHandler: add SHA256 length validation Contacts: - ExportContactTokenHandler: persist token to MongoDB with TTL index Stories: - ReportHandler: log report details for admin review - GetStoryViewsListHandler: clean up stub comment New queries/handlers: - GetBotsByOwnerUserIdQuery + handler - GetChatMemberListQueryHandler (for chat member list) Tests: - GetBotsByOwnerUserIdQueryHandlerTests (2) - GetChatMemberListQueryHandlerTests (2) - Test project references updated
Reconstructed the entire SessionServer architecture from Ghidra decompilation of the original v0.38.222.306 Native AOT binary. This replaces the skeleton implementation with the real architecture: Architecture (54 files, +3561/-638 lines): - Options: MyTelegramSessionServerOptions (DC ID, rate limits, gRPC URLs, temp auth key TTL) - Caching: AuthKeyHelper, OnlineUserHelper, ChatMemberHelper, RequestCacheAppService (all ConcurrentDictionary-based in-memory, matching original binary) - Core Services: SessionService, ServerSaltHelper (Redis), PermissionChecker, TokenBucket, MessageIdGenerator, SessionDataProcessor (Channel<T>), SessionDataDispatcher, MessageSender2, EncryptedMessageProcessor - EncryptedMessageProcessor: Full MTProto 2.0 pipeline - auth key lookup, AES-256-IGE decrypt, TL deserialization, salt/msgId validation, session init, rate limiting, permission checking, request dispatch - 15 Handlers: GetFutureSalts, DestroySession, DestroyAuthKey, InvokeWithLayer, InitConnection, InvokeAfterMsg, InvokeWithoutUpdates, MsgsStateReq, GzipPacked, Auth/BindTempAuthKey, Auth/LogOut, Auth/DropTempAuthKeys, Auth/ResetAuthorizations, Account/GetAuthorizations, Account/ResetAuthorization - EventHandlers: SessionEventHandler with 16 IEventHandler<T> implementations - 6 BackgroundServices: SessionDataProcessor, RemoveExpiredAuthKeys, MongoDbIndexes, ObjectMessageSender, QueuedCommandExecutor, LayeredServiceSubscribe - DI: MyTelegramSessionServerExtensions with full service + event subscription registration - Program.cs: Updated to use AddMyTelegramCoreServices, AddMyTelegramRabbitMqEventBus, AddMyTelegramSessionServer - csproj: Updated to net9.0, proper project references Removed old skeleton: Models/, HostedServices/, SessionManager, RabbitMQService
…p, request routing
- MessageSender2: full MTProto 2.0 encryption pipeline
- Build inner data frames (server_salt + session_id + msg_id + seq_no + data)
- Encrypt via IMtpHelper.Encrypt (AES-256-IGE)
- Publish EncryptedMessageResponse via EventBus → GatewayServer
- PushMessageToPeerAsync: resolve users/chat/channel members, filter by
online status and excluded auth keys
- SendRawDataToClientAsync: for pre-serialized RPC results
- PendingRequestTracker: maps reqMsgId → connection info
- Bridges the gap between open-source DataResultResponseReceivedEvent
(only has ReqMsgId+Data) and the original binary (had ConnectionId etc.)
- 5-minute TTL with periodic cleanup
- EncryptedMessageProcessor: gzip_packed decompression
- Decompress via IGZipHelper, deserialize inner TL object, re-dispatch
- Track pending requests at all 3 dispatch points
- SessionEventHandler: DataResultResponseReceivedEvent routing
- Look up PendingRequestInfo, route response to correct client
- Support both IObject and raw data paths
- Minor fixes: stackalloc out of loop, async→sync where no await
Build: 0 errors, 0 warnings
SummaryMajor implementation pass: 33 Messenger handlers brought to production-ready state + complete SessionServer rewrite reconstructed from the original binary's Ghidra decompilation. 📊 Stats: Messenger Handlers (Commits 1–2)Commit 1: Implement 33 handlers + tests
Commit 2: Make all stub handlers production-ready
SessionServer Rewrite (Commits 3–4)Commit 3: Complete rewrite from decompiled binary54 new C# files reconstructed from Ghidra decompilation of the original closed-source SessionServer:
Commit 4: Implement all remaining TODOs
Build & Test Status
|
• GetBirthdaysHandler: full contact birthday filtering • GetUnreadMentionsHandler: new MongoDB query + message loading • ReadMentionsHandler: real ReadMentionCommand, forum topics support • DeletePhoneCallHistoryHandler: PhoneCall filter + delete pipeline • GetAvailableEffectsHandler: batch document loading • ActivateStealthModeHandler: premium check • Fix TRpcError, ReadOnlyMemory null, ambiguous queries, test mocks
- Fix 34 partial implementations: replace NotImplementedException in else-branches with proper RPC errors (ChannelInvalid, PeerIdInvalid) - Implement 39 new handler stubs across Messages, Channels, Bots, Account, Auth, Premium, Contacts, Users, and Invoke wrappers - Messages: EditChatTitle, EditChatPhoto, DeleteChatUser, GetChats, DeleteSavedHistory, SendScreenshotNotification, GetExportedChatInvite, SaveRecentSticker, StartBot, TogglePeerTranslations, and more - Channels: EditForumTopic, DeleteTopicHistory, GetMessageAuthor - Bots: ToggleUsername, SendCustomRequest, AnswerWebhookJSONQuery, CheckDownloadFileParams, InvokeWebViewCustomMethod - Account: GetTheme, CreateTheme, UpdateTheme, EditBusinessChatLink, ResolveBusinessChatLink - All invoke wrappers: AfterMsgs, WithApnsSecret, WithBusinessConnection, WithGooglePlayIntegrity, WithMessagesRange, WithReCaptcha, InitConnection - Build: 0 errors, 35 warnings (pre-existing)
- Invoke wrappers: delegate inner queries via IHandlerHelper instead of throwing (AfterMsgs, WithApnsSecret, WithBusinessConnection, WithGooglePlayIntegrity, WithMessagesRange, WithReCaptcha) - InitConnection: save device info via NewDeviceCreatedEvent + delegate inner query (matches InvokeWithLayer pattern from corefork) - StartBot: send /start message via IMessageAppService pipeline - SendScreenshotNotification: send messageActionScreenshotTaken service message via IMessageAppService - EditBusinessChatLink: delete + recreate via IBusinessAppService - ResolveBusinessChatLink: add premium/slug validation 14 handlers remain as RPC-error stubs due to missing domain infrastructure: CreateTheme, UpdateTheme, ResendCode, UpdateUserEmojiStatus, SendCustomRequest, AnswerWebhookJSONQuery, InvokeWebViewCustomMethod, EditForumTopic, ImportContactToken, DeleteScheduledMessages, ToggleSuggestedPostApproval, ToggleTodoCompleted, ApplyBoost, ResolveBusinessChatLink
- UpdateUserEmojiStatus (bots): uses UpdateUserEmojiStatusCommand to set/clear emoji status on target user, supports TEmojiStatus, TEmojiStatusCollectible, TEmojiStatusEmpty - ImportContactToken: queries MongoDB ContactTokens collection (written by ExportContactTokenHandler), validates expiry, returns target user - DeleteScheduledMessages: fetches via GetScheduledMessagesQuery, deletes via DeleteMessageCommand, emits TUpdateDeleteScheduledMessages Remaining 11 stubs require new domain aggregates or external infra: - CreateTheme/UpdateTheme: no ThemeAggregate (only ChatThemeAggregate) - EditForumTopic: no ForumTopic commands in domain - ResendCode: no SMS/call provider infrastructure - SendCustomRequest/AnswerWebhookJSONQuery/InvokeWebViewCustomMethod: no webhook/bot external infra - ToggleSuggestedPostApproval/ToggleTodoCompleted: no commands - ApplyBoost: no Boost aggregate - ResolveBusinessChatLink: no reverse slug lookup
|
I merged your changes in my pull request: #2 |
feat: implement production-ready corefork handlersSummaryImplements 68 TL handler completions for the MyTelegram server, bringing partial stubs and missing handlers to production-ready state in accordance with the corefork specification. What was done1. New full implementations (8 handlers)
2. Fix 34 partial implementationsReplaced 3. Implement 39 new handler stubsHandlers across multiple API namespaces:
4. Production-ready refinements (per corefork)
5. Build fixes
Remaining stubs (11 handlers)These handlers return RPC errors because they require new domain aggregates or external infrastructure that doesn't exist yet:
Build status✅ 0 errors, 35 warnings (pre-existing) Files changed~85 files across:
|
…efork spec) Implemented handlers: - account.createTheme — full Theme CQRS domain (aggregate, commands, events, state) - account.updateTheme — theme lookup via GetAllChatThemesQuery, slug/id resolution - account.resolveBusinessChatLink — slug validation, business link reverse lookup - channels.editForumTopic — forum validation, admin rights, close/hide separation checks - bots.sendCustomRequest — bot-only validation, JSON syntax check - bots.answerWebhookJSONQuery — bot-only, query ID validation, JSON validation - bots.invokeWebViewCustomMethod — bot resolution, user verification, JSON validation - messages.toggleSuggestedPostApproval — admin rights, approve/reject with comments - messages.toggleTodoCompleted — checklist task toggle via IChecklistAppService - premium.applyBoost — slot management, premium check, peer validation All handlers follow corefork.telegram.org spec with proper RPC error codes. Domain infrastructure: ThemeAggregate, ThemeState, ThemeId, CreateTheme/UpdateTheme commands, events, and command handlers. Excludes: auth.resendCode (SMS/call — excluded per request)
Complete Bot API implementation with event-driven architecture: Event DTOs (12 new), Serializers (12 new), MTProtoBridge rewrite (~530 lines), BotApiService rewrite (~900 lines), BotApiController rewrite, FileController with MinIO. All methods: sendMessage, forwardMessage, copyMessage, editMessageText, editMessageReplyMarkup, deleteMessage, sendChatAction, answerCallbackQuery, banChatMember, unbanChatMember, restrictChatMember, promoteChatMember, setChatAdministratorCustomTitle, banChatSenderChat, unbanChatSenderChat, setChatPermissions, exportChatInviteLink, createChatInviteLink, editChatInviteLink, revokeChatInviteLink, approveChatJoinRequest, declineChatJoinRequest, setChatPhoto, deleteChatPhoto, setChatTitle, setChatDescription, getChat, getUserProfilePhotos, getFile, sendPhoto, sendAudio, sendDocument, sendVideo, sendAnimation, sendVoice, sendVideoNote, sendSticker, sendMediaGroup, sendLocation, sendVenue, sendContact, sendPoll, sendDice, getAvailableGifts, sendGift, sendInvoice, answerPreCheckoutQuery, setWebhook, deleteWebhook, getWebhookInfo, getMe
Implementation Summary: MTProto Handlers + Bot APIOverviewThis set of changes implements 10 remaining MTProto handler stubs and a complete Bot API rewrite (51 methods), bringing the project from partial stub coverage to full production-ready functionality. Commits:
Total: 49 files changed, +3,841 / −646 Part 1 — MTProto Handler Stubs (10 handlers)All handlers follow the corefork.telegram.org specification with proper RPC error codes, input validation, and permission checks. Account
|
| Event | Purpose |
|---|---|
BotForwardMessageEvent |
Forward message between chats |
BotEditMessageEvent |
Edit message text/markup |
BotDeleteMessageEvent |
Delete messages |
BotChatActionEvent |
Send chat action (typing, etc.) |
BotCallbackQueryAnswerEvent |
Answer inline callback queries |
BotChatMemberEvent |
Ban/unban/restrict/promote members |
BotChatPermissionsEvent |
Set default chat permissions |
BotChatInviteLinkEvent |
Create/edit/revoke invite links |
BotChatJoinRequestEvent |
Approve/decline join requests |
BotChatPhotoEvent |
Set/delete chat photo |
BotChatInfoEvent |
Set chat title/description |
BotSendMediaEvent |
Send photos, documents, audio, video, etc. |
Serializers (12) — MyTelegram.BotApi/Serializers/
MessagePack serializers using ContractlessStandardResolver for each new event type. All registered in Program.cs DI container.
Additional Types — MyTelegram.Domain.Shared/BotApi/BotApiAdditionalTypes.cs
BotApiFile, BotApiUserProfilePhotos, BotApiPhotoSize, BotApiChatInviteLink, BotApiChatPermissions, BotApiLocation, BotApiContact, BotApiVenue, BotApiDice, BotApiPoll, BotApiPollOption, BotApiMessageId
MinioOptions — MyTelegram.BotApi/Options/MinioOptions.cs
Local options class (BotApi doesn't reference MyTelegram.Domain): Endpoint, AccessKey, SecretKey, BucketName.
Rewritten Files
MTProtoBridge.cs (~530 lines)
Bridge between Bot API and MTProto layer. All TODO stubs replaced with:
-
Write operations — publish DTO events via
IEventBusto RabbitMQ:ForwardMessageAsync,EditMessageTextAsync,EditMessageReplyMarkupAsync,DeleteMessageAsyncSendChatActionAsync,AnswerCallbackQueryAsyncManageChatMemberAsync,SetChatPermissionsAsyncManageChatInviteLinkAsync,HandleChatJoinRequestAsyncManageChatPhotoAsync,SetChatInfoAsyncSendMediaAsync
-
Read operations — MongoDB queries:
GetChatAsync— resolves user/chat/channel from appropriate read modelsGetBotApiUserAsync— convertsUserReadModelto Bot APIUserformatGetBotInfoAsync— retrievesBotReadModelby tokenGetMessageFromDbAsync— fetchesMessageReadModelwith Bot API conversion
BotApiService.cs (~900 lines)
All 51 stub methods replaced with production implementations:
| Category | Methods |
|---|---|
| Messages | sendMessage, forwardMessage, copyMessage, editMessageText, editMessageReplyMarkup, deleteMessage, sendChatAction |
| Media | sendPhoto, sendAudio, sendDocument, sendVideo, sendAnimation, sendVoice, sendVideoNote, sendSticker, sendMediaGroup, sendLocation, sendVenue, sendContact, sendPoll, sendDice |
| Callbacks | answerCallbackQuery |
| Members | banChatMember, unbanChatMember, restrictChatMember, promoteChatMember, setChatAdministratorCustomTitle, banChatSenderChat, unbanChatSenderChat |
| Chat Admin | setChatPermissions, exportChatInviteLink, createChatInviteLink, editChatInviteLink, revokeChatInviteLink, approveChatJoinRequest, declineChatJoinRequest |
| Chat Info | setChatPhoto, deleteChatPhoto, setChatTitle, setChatDescription, getChat |
| Users | getUserProfilePhotos, getMe |
| Files | getFile |
| Payments | getAvailableGifts, sendGift, sendInvoice, answerPreCheckoutQuery |
| Webhook | setWebhook, deleteWebhook, getWebhookInfo |
BotApiController.cs (~40 endpoints)
Complete rewrite with:
ExecuteAsync<T>/ExecuteVoidAsynchelper methods to reduce boilerplate- Multipart form endpoints for file uploads (sendPhoto, sendAudio, sendDocument, sendVideo, sendAnimation, sendVoice, sendVideoNote, sendSticker, setChatPhoto)
- Standard Bot API JSON response format:
{ ok: true, result: ... } - Proper error handling with HTTP status codes
FileController.cs
MinIO file download implementation replacing the TODO stub:
- Downloads files from MinIO via HTTP (
http://{endpoint}/{bucket}/{fileId}) - Content-type passthrough
- Error handling for storage unavailability (502) and missing files (404)
IBotApiService.cs
Added GetChatAsync method to the interface.
Program.cs
12 new serializer DI registrations added for all new event types.
MongoDB Read Models Used
| Collection | Key Fields |
|---|---|
UserReadModel |
UserId, FirstName, LastName, UserName, Bot, Premium, ProfilePhoto |
BotReadModel |
UserId, Token, BotName, WebHookUrl, Commands, Description |
ChannelReadModel |
ChannelId, Title, UserName, Broadcast, MegaGroup, About, Pts |
ChannelMemberReadModel |
ChannelId, UserId, IsAdmin, AdminRights, BannedRights |
ChatReadModel |
ChatId, Title, CreatorId, ChatMembers |
ChatInviteReadModel |
InviteId, AdminId, PeerId, Link, Permanent, ExpireDate |
MessageReadModel |
MessageId, OwnerPeerId, Message, Media2, Entities2, Date |
DocumentReadModel |
DocumentId, AccessHash, MimeType, Size, Thumbs, Name |
PhotoReadModel |
PhotoId, AccessHash, Date, Sizes |
Excluded
auth.resendCode— SMS/call delivery, excluded per request
|
дальше мне лень 🥀 |
…ethods to IUpdatesManager
- docker-compose: mongo:4.4 (no AVX), minio old release (no x86-64-v2) - docker-compose: RabbitMQ use env vars instead of hardcoded test/test - docker-compose: gateway SSL disabled for port 30443 - stargift-admin: add frontend Dockerfile and vite proxy config - stargift-admin: replace all hardcoded localhost:3001 with relative paths - stargift-admin: sanitize docker-compose.yml credentials
The WebSocket middleware was missing a reader for UnencryptedMessageResponseQueue, causing MTProto handshake responses (ResPQ, ServerDHParams) to never be sent back to WebSocket clients. This broke the auth key exchange over WebSocket.
requestEncryption, acceptEncryption, discardEncryption,
sendEncrypted, sendEncryptedFile, sendEncryptedService,
setEncryptedTyping, readEncryptedHistory, uploadEncryptedFile
Server acts as opaque relay per Telegram E2E protocol:
https://corefork.telegram.org/api/end-to-end