Repository navigation
MaxMessenger.Bot v0.7.0-alpha
Pre-release
Pre-release
Ревью всей библиотеки на соответствие MAX Bot API (схемы официального Go SDK max-bot-api-client-go) и исправление открытых issue.
Breaking Changes
- Webhook endpoint is opt-in (#35):
WebhookControllerсталabstract, поэтому подключение пакета больше не добавляетPOST /api/max/webhook(и запись в Swagger) в каждое ASP.NET Core приложение. Подключайте эндпоинт явно черезapp.MapMaxWebhook()или унаследуйтесь отWebhookControllerс[Route(...)]. - Webhook secret header:
MaxWebhookOptions.SignatureHeaderNameпо умолчанию теперьX-Max-Bot-Api-Secret— именно этот заголовок присылает MAX. Раньше при заданномSecretTokenвсе реальные webhook-запросы отклонялись с 401. - Callback answer body:
NewMessageBody.AttachmentsтеперьAttachmentRequest[], аNewMessageBody.Link—NewMessageLink(формат запросаPOST /answers). - AttachmentRequest:
Payloadстал nullable (уlocationнет payload), добавленыLatitude/Longitude; сPayloadснят атрибут[Required](Typeпо-прежнему обязателен). - Typed updates:
MessageRemovedUpdate.MessageиMessageChatCreatedUpdate.Messageстали nullable — MAX присылает для этих событий идентификаторы, а не сообщение. - WebhookController action:
PostAsync(CancellationToken)больше не принимает[FromBody] Update— контроллер сам читает тело после проверки размера и секрета, поэтому неавторизованные запросы не парсятся. - Webhook secret format:
MaxWebhookOptions.Validate()иConfigureWebhookAsyncотклоняют секрет, не соответствующий формату MAX (5-256 символовA-Z,a-z,0-9,_,-). - Upload result:
photosиfile_idразбираются в типизированныеFileUploadResult.Photos/FileIdи больше не попадают вAdditionalProperties. - New interface members:
IMessagesApi.GetMessagesAsync(chatId, count, from, to),IMessagesApi.GetMessagesByIdsAsync,IChatsApi.GetChatListAsync,IChatsApi.GetChatMembersPageAsync,IFilesApi.UploadAsync— собственные реализации этих интерфейсов нужно дополнить. - AddChatAdminRequest.UserId помечен
[Obsolete]: MAX требует список прав, используйтеAdminsсChatAdmin.Permissions.
Added
- Upload helper (#38):
IFilesApi.UploadAsync(type, stream, fileName)делаетPOST /uploads+ загрузку и возвращает готовый токен (дляimage— изphotos, дляvideo/audio— токен изPOST /uploads). - Attachment factories (#15):
AttachmentRequest.ImageFromUrl,Image,Video,Audio,File,FromUpload,Sticker,Contact,Location,Share,Keyboardи типизированные payload-классы. - MapMaxWebhook (#35): minimal-API эндпоинт
app.MapMaxWebhook(pattern)с проверкой секрета и лимита размера тела. - MaxAttachmentNotReadyException (#22): отдельное исключение для ошибки
attachment.not.ready. - Messages pagination (#18):
GetMessagesAsync(chatId, count, from, to)иGetMessagesByIdsAsync(messageIds). - Chats pagination (#23):
GetChatListAsync(count, marker)возвращаетChatListResponseсmarkerследующей страницы;GetChatMembersPageAsync(chatId, marker, count)возвращает участников вместе сmarker. - Inline buttons:
ButtonType.Clipboard, кнопкаopen_app(ButtonType.OpenApp+InlineKeyboardButton.WebApp/ContactId) иQuickдляrequest_geo_location.OpenAppбезWebAppпо-прежнему отправляется какlink. - Chat info in updates (#37):
Update.ChatId,Update.Chat(частично: id и тип) иUpdate.ChatTypeзаполняются изmessage.recipientдляmessage_created,message_editedиmessage_callback; дляbot_added/bot_removed/user_added/user_removedChatTypeвычисляется изis_channel. - Update fields:
message_id,user_id,admin_id,title,is_channel,muted_until,start_payloadи соответствующие свойства в типизированных обёртках (MessageRemovedUpdate,UserRemovedUpdate,ChatTitleChangedUpdate,BotAddedUpdateи др.). - Attachments:
StickerAttachment,ShareAttachment;Tokenу фото/видео/аудио/файлов,VideoAttachment.Thumbnail,AudioAttachment.Transcription. - Models:
MessageBody.Markup,MessageStat.Views,Chat.MessagesCount,ChatStatus.Suspended,Subscription.Time/Version,ChatAdminдля назначения администраторов.
Fixed
- Callback answers (#34):
AnswerCallbackQueryAsyncпередаётcallback_idвместо устаревшегоcallback_query_id. - Image upload token (#38):
FileUploadResultснова содержит типизированныеPhotosиFileId, аTokenзаполняется изphotos; XML-ответ CDN (<retval>1</retval>) больше не считается токеном. - API error parsing (#22): ошибки формата
{"code": "...", "message": "..."}разбираются вMaxApiException.ErrorCode/Messageвместо сырого JSON в тексте исключения. - Attachment retry: повтор отправки/редактирования выполняется только для
attachment.not.ready(раньше повторялся любой400 Bad Request); повтор добавлен дляSendMessageAsync(SendMessageRequest)с вложениями и дляEditMessageAsync. - Get chats (#23):
GetChatsAsyncкорректно разбирает ответ{"chats": [...], "marker": ...}вместо исключенияThe JSON value could not be converted to Max.Bot.Types.Chat[]. - Pinned message:
GetPinnedMessageAsyncразбирает ответ{"message": ...}и возвращаетnull, если ничего не закреплено. - Add chat admins:
AddChatAdminRequestсериализуется как{"admins": [{"user_id", "permissions", "alias"}]}. - Incoming attachments (#20, #21, #25): поля из
payloadи корня вложения объединяются — у файлов теперь заполняютсяFileName/FileSize(filename/size), у видео — размеры, длительность и превью. - Long polling marker: следующий запрос
GET /updatesиспользуетmarkerиз ответа. Раньше подставлялсяupdate_id, которого нет в MAX API (всегда0). - Webhook configuration (#36):
ConfigureWebhookAsync()иDeleteWebhookAsync()берут URL изMaxWebhookOptions.Endpoint, а секрет — изMaxWebhookOptions.SecretToken, если они не переданы явно. - Upload retries: при повторе
UploadFileDataAsyncпоток перематывается в начало, а не поддерживающие seek потоки один раз буферизуются, чтобы не отправлять пустой файл. Токен, вычисленный изphotos, не сериализуется обратно (в image payloadtokenиphotosвзаимоисключающие).UploadFileResumableAsyncбольше не делает лишний GET после загрузки видео/аудио. - Culture-invariant ids: id чатов/пользователей и числовые query-параметры форматируются через
InvariantCulture— в культурах с минусом U+2212 (sv-SE, nb-NO, fi-FI) запросы к групповым чатам (отрицательные id) ломались. - Poison updates: апдейт, который не удалось разобрать, пропускается с логированием — раньше он ронял всю пачку, маркер не сдвигался и long polling зацикливался. Вложения с неожиданными типами полей превращаются в «пустое» вложение нужного типа вместо исключения.
- Polling: маркер сдвигается только после обработки всей пачки (остановка посреди пачки не теряет апдейты);
StopAsyncдожидается параллельных обработчиков; фильтрAllowedUsernamesдляmessage_callbackпроверяет нажавшего кнопку, а не автора сообщения-бота. - Webhook hardening:
MapMaxWebhookне подставляет пустыеIOptions<MaxBotOptions>(это отключало проверку секрета) и берёт опции изMaxClient;MaxWebhookOptions.HandlerTimeoutтеперь применяется;ConfigureWebhookAsyncобновляетEndpoint/SecretTokenтолько приsuccess: trueи всегда сохраняет переданный секрет. - Retry-After: дата в прошлом или отрицательное значение больше не приводят к
ArgumentOutOfRangeExceptionв цикле повторов. - message_chat_created:
Update.ChatIdиMessageChatCreatedUpdate.ChatIdзаполняются из объектаchat. - Unknown enum values: неизвестные статусы чата и права администраторов больше не ломают десериализацию ответа.
- User-Agent: заголовок содержит фактическую версию пакета вместо зашитой
0.5.1-alpha. - Build:
Microsoft.SourceLink.GitHubобновлён до10.0.401— версия8.0.0тянула уязвимыйMicrosoft.Build.Tasks.Git(GHSA-23fw-v26w-5fgq), из-за чегоdotnet restoreпадал сNU1902приTreatWarningsAsErrors. - Samples: исправлена испорченная кодировка текстов в примерах;
FileBotSampleиспользуетUploadAsync.