Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bot API 7.0 and 7.1 #1335

Merged
merged 91 commits into from Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
c78d843
Update README
karb0f0s Jan 3, 2024
ea17a00
Bump TargetFramework for test projects
karb0f0s Jan 3, 2024
525433d
Bump references
karb0f0s Jan 3, 2024
764f8d2
Reactions
karb0f0s Jan 3, 2024
0f0ac76
Address feedback: replace { } with not null in UpdateType matching.
karb0f0s Jan 3, 2024
a866e73
Replies 2.0: Add ExternalReplyInfo and TextQuote
karb0f0s Jan 3, 2024
5de18c3
Replies 2.0: ReplyParameters
karb0f0s Jan 3, 2024
31b7c65
Replies 2.0: updata CHANGELOG
karb0f0s Jan 3, 2024
a3bcf7f
SendLocation: missing property HorizontalAccuracy
karb0f0s Jan 3, 2024
f40c7b3
Reactions: address feedback
karb0f0s Jan 3, 2024
6d8ed08
Link Preview Customization
karb0f0s Jan 3, 2024
154a333
Reactions: address feedback
karb0f0s Jan 3, 2024
4cbb871
Link Preview Customization: update CHANGELOG
karb0f0s Jan 3, 2024
f0bc8a7
Block Quotation
karb0f0s Jan 3, 2024
e662a4f
Multiple Message Actions
karb0f0s Jan 3, 2024
d214daf
Request for multiple users
karb0f0s Jan 3, 2024
92750c5
Chat Boost
karb0f0s Jan 3, 2024
2e3b0a1
Giveaway
karb0f0s Jan 3, 2024
6865bf6
Giveaway: update CHANGELOG
karb0f0s Jan 3, 2024
3e4b171
Other Changes
karb0f0s Jan 3, 2024
e8fa205
Fix spelling
karb0f0s Jan 3, 2024
ed4c929
Fix MaybeInaccessibleMessage
karb0f0s Jan 4, 2024
e447c0c
Add setters to properties
karb0f0s Jan 4, 2024
9a7bae6
Fix tests
karb0f0s Jan 4, 2024
b74ba09
Reactions: add KnownReactionTypeEmoji
karb0f0s Jan 5, 2024
92972eb
Fix SendVideoMessage tests
karb0f0s Jan 5, 2024
806f2cd
Bump xUnit in test projects
karb0f0s Jan 5, 2024
b12fce6
Fix bug #1336
karb0f0s Jan 5, 2024
6b58640
Fix SetChatPermissionsAsync test
karb0f0s Jan 5, 2024
b15a7df
Fix public class ReplyMarkupSerializationTests warning
karb0f0s Jan 5, 2024
bda138c
Add constructor for button mandatory parameters
karb0f0s Jan 5, 2024
744caa2
Button tests:
karb0f0s Jan 5, 2024
1e3880d
Fix spelling
karb0f0s Jan 5, 2024
ebb477a
Modernize Stickers Tests
karb0f0s Jan 5, 2024
6b5a82c
Multiple Message Actions:
karb0f0s Jan 5, 2024
575697e
Get rid of Polly dependency
karb0f0s Jan 9, 2024
c14bcb5
Remove Cached Content test
karb0f0s Jan 9, 2024
fd39dd4
Fix BotShortDescriptionTests
karb0f0s Jan 9, 2024
34e7106
Modernize test framework classes
karb0f0s Jan 9, 2024
4c04bb9
Modernize Admin Bot tests
karb0f0s Jan 9, 2024
c3c493c
Fix ChatMemberAdministrationTests
karb0f0s Jan 9, 2024
204cef1
Revert "Fix bug #1336"
karb0f0s Jan 10, 2024
a224312
Misplaced doc tag in SendVoiceAsync
karb0f0s Jan 10, 2024
6191c93
Use enum instead of string for MessageOrigin type
tuscen Feb 16, 2024
971c9a7
Pass cancellation token to CopyToAsync on net6.0+ targets
tuscen Feb 16, 2024
cc29dfe
Make sure that CLI language is always in English
tuscen Feb 16, 2024
43212fc
Use C# 12
tuscen Feb 16, 2024
b3b9aa3
Update base container to use .NET 8.0
tuscen Feb 16, 2024
5b2a0c3
Implement Bot API 7.1
tuscen Feb 16, 2024
0dfbaae
Fix MessageOriginConverter
tuscen Feb 16, 2024
52b3d41
Add MessageOrigin serialization tests
tuscen Feb 16, 2024
f13e44c
Update CHANGELOG.md
tuscen Feb 16, 2024
f7d9f56
Add Story serialization tests
tuscen Feb 16, 2024
cc19593
Remove unnecessary commas from JSON
tuscen Feb 16, 2024
9ccba19
Fix tests
tuscen Feb 16, 2024
2c45e70
Add unit tests for Chat and ChatBoostAdded
tuscen Feb 16, 2024
32ab8fb
Rewrite serialization tests to use JObject for asserts
tuscen Feb 16, 2024
cce06b7
Add XML documentation for MessageOriginType
tuscen Feb 16, 2024
bef3a2d
Update CHANGELOG.md
tuscen Feb 16, 2024
54fb473
Refactor some serialization unit tests to use JObject
tuscen Feb 16, 2024
60d18df
Fix XML docs line length
tuscen Feb 16, 2024
473dc95
Make a property public on a public API type
tuscen Feb 16, 2024
27ab6e0
Make reaction type property an enum for consistency
tuscen Feb 16, 2024
30b937a
Update CHANGELOG.md
tuscen Feb 16, 2024
11e0d70
Update README.md
tuscen Feb 16, 2024
306fa3d
Update dependencies
tuscen Feb 16, 2024
94c86d7
Fix devcontainer configuration
tuscen Feb 17, 2024
d61379a
Replace C# extension to C# Dev Kit in devcontainer
tuscen Feb 17, 2024
452987b
Merge pull request #1355 from TelegramBots/tuscen/api7_1
tuscen Feb 19, 2024
d8faafd
Change dev container
tuscen Feb 19, 2024
7a15cf7
Use JObject API in the rest of the serialization unit tests
tuscen Feb 24, 2024
70ee6f8
Use nullable annotation syntax instead of nullability attributes
tuscen Feb 24, 2024
91f3a7c
Remove version suffix
tuscen Feb 24, 2024
945cf78
Add required properties from C# 11
tuscen Feb 25, 2024
0991ea3
Rename UnpinAllGeneralForumTopicMessages to UnpinAllGeneralForumTopic…
tuscen Feb 25, 2024
71c7f96
Add UnpinAllGeneralForumTopicMessagesRequest and made UnpinAllGeneral…
tuscen Feb 25, 2024
68b3d62
Add overloads that accept request classes instead of positional param…
tuscen Feb 25, 2024
dabf077
Mark old API methods with positional parameters as obsolete
tuscen Feb 25, 2024
2b24205
Fix message on obsolete attributes
tuscen Feb 25, 2024
8976b9f
Use factory methods for InputFile
tuscen Feb 26, 2024
1605f68
Add setters to AnswerPreCheckoutQueryRequest for error message
tuscen Feb 26, 2024
e3beb08
Migrate some integration tests to use new APIs with request classes
tuscen Feb 26, 2024
2c24042
Add the word inline for method for the inline mode
tuscen Mar 1, 2024
5873464
Migrate the rest of integration tests to use the new APIs with reques…
tuscen Mar 1, 2024
4371fb3
Fix XML documentation
tuscen Mar 2, 2024
65aebec
Fix XML documentation
tuscen Mar 2, 2024
d97a212
Use target-new for requests
tuscen Mar 2, 2024
47fe66f
use version suffix
tuscen Mar 2, 2024
22a3d47
Updated CHANGELOG.md
tuscen Mar 2, 2024
e5d3d16
Add readme to the resulting nuget package
tuscen Mar 2, 2024
885de13
Use an enum for chat boost source instead of a string
tuscen Mar 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .azure-pipelines/variables.yml
Expand Up @@ -3,7 +3,7 @@ variables:
- name: versionPrefix
value: 20.0.0
- name: versionSuffix
value: 'alpha.2'
value: 'alpha.3'
- name: ciVersionSuffix
value: ci.$(Build.BuildId)+git.commit.$(Build.SourceVersion)
- name: isPreRelease
Expand Down
4 changes: 2 additions & 2 deletions .devcontainer/Dockerfile
@@ -1,5 +1,5 @@
ARG DOTNET_VERSION=6.0
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bullseye-slim
ARG DOTNET_VERSION=8.0
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=${USER_UID}
Expand Down
22 changes: 13 additions & 9 deletions .devcontainer/devcontainer.json
Expand Up @@ -4,14 +4,18 @@
"service": "devhost",
"shutdownAction": "stopCompose",
"workspaceFolder": "/workspace",
"extensions": [
"ms-dotnettools.csharp",
"ms-azuretools.vscode-docker",
"editorconfig.editorconfig",
"eamodio.gitlens",
"tintoy.msbuild-project-tools",
"logerfo.sln-support",
"formulahendry.dotnet-test-explorer"
],
"customizations": {
"vscode": {
"extensions": [
"ms-dotnettools.csdevkit",
"ms-azuretools.vscode-docker",
"editorconfig.editorconfig",
"eamodio.gitlens",
"tintoy.msbuild-project-tools",
"logerfo.sln-support",
"formulahendry.dotnet-test-explorer"
]
}
},
"remoteUser": "vscode"
}
114 changes: 114 additions & 0 deletions CHANGELOG.md
Expand Up @@ -21,6 +21,120 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

<!-- markdownlint-configure-file { "MD024": false } -->

## [Unreleased]

> [Bot API 7.0](https://core.telegram.org/bots/api#december-29-2023) (December 29, 2023)
> [Bot API 7.1](https://core.telegram.org/bots/api#february-16-2024) (February 16, 2024)

### Added

- API methods on `ITelegramBotClient` that accept request classes with parameters
- Class `UnpinAllGeneralForumTopicMessagesRequest`
- The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction.
- Enum `ReactionTypeKind`
- Enum `ChatBoostSourceType`
- The class `KnownReactionTypeEmoji` containing Emojis available for `ReactionTypeEmoji`.
- Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated`
and the property `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it.
- Updates about reaction changes on a message with anonymous reactions, represented by the class `MessageReactionCountUpdated`
and the property `MessageReactionCount` in the class `Update`. The bot must explicitly allow the update to receive it.
- New enum values `MessageReaction`, `MessageReactionCount` for `UpdateType`.
- Type `ReactionCount`.
- Request classes `SetMessageReactionRequest` that allows bots to react to messages.
- New method `ITelegramBotClient.SetMessageReactionAsync` that allows bots to react to messages.
- The property `AvailableReactions` to the class `Chat`.
- The class `ExternalReplyInfo` and the property `ExternalReply` of type `ExternalReplyInfo` to the class `Message`,
containing information about a message that is replied to by the current message, but can be from another chat or forum topic.
- The class `TextQuote` and the property `Quote` of type `TextQuote` to the class `Message`,
which contains the part of the replied message text or caption that is quoted in the current message.
- The class `ReplyParameters`.
- The class `LinkPreviewOptions`.
- The property `LinkPreviewOptions` to the class `Message` with information about the link preview options used to send the message.
- New enum value `Blockquote` for `MessageEntityType`.
- Request classes `DeleteMessagesRequest`, `ForwardMessagesRequest` and `CopyMessagesRequest`.
- New methods `ITelegramBotClient.DeleteMessagesAsync`, `ITelegramBotClient.ForwardMessagesAsync` and `ITelegramBotClient.CopyMessagesAsync`.
- Updates about chat boost changes, represented by the classes `ChatBoostUpdated` and `ChatBoostRemoved` and the properties `ChatBoost` and `RemovedChatBoost`
in the class `Update`. The bot must be an administrator in the chat to receive these updates.
- The classes `ChatBoostSourcePremium`, `ChatBoostSourceGiftCode` and `ChatBoostSourceGiveaway`, representing different sources of a chat boost.
- The method `ITelegramBotClient.GetUserChatBoostsAsync` for obtaining the list of all active boosts a user has contributed to a chat.
- Request class `GetUserChatBoostsRequest` for obtaining the list of all active boosts a user has contributed to a chat.
- The class `Giveaway` and the property `Giveaway` to the class `Message` for messages about scheduled giveaways.
- The class `GiveawayCreated` and the property `GiveawayCreated` to the class `Message` for service messages about the creation of a scheduled giveaway.
- The class `GiveawayWinners` and the property `GiveawayWinners` to the class `Message` for messages about the completion of a giveaway with public winners.
- The class `GiveawayCompleted` and the property `GiveawayCompleted` to the class `Message` for service messages about the completion of a giveaway without public winners.
- New `MessageType` enum members: `Giveaway`, `GiveawayCreated`, `GiveawayWinners` and `GiveawayCompleted`
- The properties `AccentColorId`, `BackgroundCustomEmojiId`, `ProfileAccentColorId`, and `ProfileBackgroundCustomEmojiId` to the class `Chat`.
- The property `HasVisibleHistory` to the class `Chat`.
- Classes `MaybeInaccessibleMessage` and `InaccessibleMessage`.
- The class `ChatBoostAdded`
- Classes `MessageOrigin`, `MessageOriginUser`, `MessageOriginHiddenUser` and `MessageOriginChannel`
- Enum `MessageOriginType`
- Fields `UnrestrictBoostCount` and `CustomEmojiStickerSetName` to type `Chat`
- Enum member `MessageType.BoostAdded`
- Fields `SenderBoostCount`, `ReplyToStory` and `BoostAdded` to type `Message`
- Fields `Chat` and `Id` to type `Story`

### Changed
- All required properties without setters marked as required using `required` keyword
- All non-default ctors are marked as obsolete in favor of the default ctors with object initialization syntax and required properties
- All API methods with positional parameters on `ITelegramBotClient` are marked obsolete
- Class `UnpinAllGeneralForumTopicMessages` marked as obsolete
- Replaced parameters `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the methods
- `ITelegramBotClient.CopyMessageAsync`,
- `ITelegramBotClient.SendMessageAsync`,
- `ITelegramBotClient.SendPhotoAsync`,
- `ITelegramBotClient.SendVideoAsync`,
- `ITelegramBotClient.SendAnimationAsync`,
- `ITelegramBotClient.SendAudioAsync`,
- `ITelegramBotClient.SendDocumentAsync`,
- `ITelegramBotClient.SendStickerAsync`,
- `ITelegramBotClient.SendVideoNoteAsync`,
- `ITelegramBotClient.SendVoiceAsync`,
- `ITelegramBotClient.SendLocationAsync`,
- `ITelegramBotClient.SendVenueAsync`,
- `ITelegramBotClient.SendContactAsync`,
- `ITelegramBotClient.SendPollAsync`,
- `ITelegramBotClient.SendDiceAsync`,
- `ITelegramBotClient.SendInvoiceAsync`,
- `ITelegramBotClient.SendGameAsync`,
- `ITelegramBotClient.SendMediaGroupAsync`
- Replaced properties `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the request classes
- `CopyMessageRequest`,
- `SendMessageRequest`,
- `SendPhotoRequest`,
- `SendVideoRequest`,
- `SendAnimationRequest`,
- `SendAudioRequest`,
- `SendDocumentRequest`,
- `SendStickerRequest`,
- `SendVideoNoteRequest`,
- `SendVoiceRequest`,
- `SendLocationRequest`,
- `SendVenueRequest`,
- `SendContactRequest`,
- `SendPollRequest`,
- `SendDiceRequest`,
- `SendInvoiceRequest`,
- `SendGameRequest`,
- `SendMediaGroupRequest`
- Replaced the parameter `DisableWebPagePreview` with `LinkPreviewOptions` in the methods `SendTextMessageAsync` and `EditMessageTextAsync`.
- Replaced the property `DisableWebPagePreview` with `LinkPreviewOptions` in the request classes `SendMessageRequest`, `EditMessageTextRequest`
and `EditInlineMessageTextRequest`.
- Replaced the property disable_web_page_preview with `DisableWebPagePreview` in the class `InputTextMessageContent`.
- Renamed the class `KeyboardButtonRequestUser` to `KeyboardButtonRequestUsers` and added the property `MaxQuantity` to it.
- Renamed the property `RequestUser` in the class `KeyboardButton` to `RequestUsers`. The old name will still work for backward compatibility.
- Renamed the class `UserShared` to `UsersShared` and changed the property `UserId` to `UserIds`.
- Replaced the property `UserShared` in the class Message with the property `UsersShared`.
- Replaced enum member `MessageType.UserShared` with `MessageType.UsersShared`
- Fields `ForwardFrom`, `ForwardFromChat`, `ForwardFromMessageId`, `ForwardSignature`, `ForwardSenderName`
and `ForwardDate` replaced with the field `ForwardOrigin` of type `MessageOrigin` in the class `Message`.
- Type of the property `Message` of the class `CallbackQuery` to `MaybeInaccessibleMessage`
- Type of the property `PinnedMessage` of the class `Message` to `MaybeInaccessibleMessage`.

### Removed
- Fields `ForwardFrom`, `ForwardFromChat`, `ForwardFromMessageId`, `ForwardSignature`, `ForwardSenderName`
and `ForwardDate` from type `Message`

## [v20.0.0] - Unreleased

> [Bot API 6.9](https://core.telegram.org/bots/api#september-22-2023) (September 22, 2023)
Expand Down
5 changes: 5 additions & 0 deletions Directory.Build.props
@@ -0,0 +1,5 @@
<Project>
<PropertyGroup>
<PreferredUILang>en</PreferredUILang>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion README.md
@@ -1,7 +1,7 @@
# .NET Client for Telegram Bot API

[![package](https://img.shields.io/nuget/vpre/Telegram.Bot.svg?label=Telegram.Bot&style=flat-square)](https://www.nuget.org/packages/Telegram.Bot)
[![Bot API Version](https://img.shields.io/badge/Bot%20API-6.9%20(September%2022,%202023)-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api#september-22-2023)
[![Bot API Version](https://img.shields.io/badge/Bot%20API-7.1%20(February%2016,%202024)-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api#february-16-2024)
[![documentations](https://img.shields.io/badge/Documentations-Book-orange.svg?style=flat-square)](https://telegrambots.github.io/book/)
[![telegram chat](https://img.shields.io/badge/Support_Chat-Telegram-blue.svg?style=flat-square)](https://t.me/joinchat/B35YY0QbLfd034CFnvCtCA)

Expand Down
1 change: 1 addition & 0 deletions Telegram.Bot.sln
Expand Up @@ -25,6 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.gitignore = .gitignore
.gitpod.yml = .gitpod.yml
LICENSE = LICENSE
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".azure-pipelines", ".azure-pipelines", "{71662597-40F2-4192-AC4D-5FB9A1F12642}"
Expand Down
6 changes: 3 additions & 3 deletions src/EnumSerializer.Generator/EnumSerializer.Generator.csproj
Expand Up @@ -14,10 +14,10 @@

<!-- The following libraries include the source generator interfaces and types we need -->
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.85" PrivateAssets="all" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.141" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" PrivateAssets="all" />
<PackageReference Include="Scriban" Version="5.9.0" GeneratePathProperty="true" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" PrivateAssets="all" />
<PackageReference Include="Scriban" Version="5.9.1" GeneratePathProperty="true" PrivateAssets="all" />

<!-- This ensures the library will be packaged as a source generator when we use `dotnet pack` -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
Expand Down
58 changes: 58 additions & 0 deletions src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs
@@ -0,0 +1,58 @@
using System.Reflection;
using Newtonsoft.Json.Linq;
using Telegram.Bot.Types.Enums;

namespace Telegram.Bot.Converters;

internal class ChatBoostSourceConverter : JsonConverter
{
static readonly TypeInfo BaseType = typeof(ChatBoostSource).GetTypeInfo();

public override bool CanWrite => false;
public override bool CanRead => true;
public override bool CanConvert(Type objectType) =>
BaseType.IsAssignableFrom(objectType.GetTypeInfo());

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is null)
{
writer.WriteNull();
}
else
{
var jo = JObject.FromObject(value);
jo.WriteTo(writer);
}
}

public override object? ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
JsonSerializer serializer)
{
var jo = JObject.Load(reader);
var type = jo["source"]?.ToObject<ChatBoostSourceType>();

if (type is null)
{
return null;
}

var actualType = type switch
{
ChatBoostSourceType.Premium => typeof(ChatBoostSourcePremium),
ChatBoostSourceType.GiftCode => typeof(ChatBoostSourceGiftCode),
ChatBoostSourceType.Giveaway => typeof(ChatBoostSourceGiveaway),
_ => throw new JsonSerializationException($"Unknown chat boost source value of '{jo["source"]}'")
};

// Remove status because status property only has getter
jo.Remove("source");
var value = Activator.CreateInstance(actualType)!;
serializer.Populate(jo.CreateReader(), value);

return value;
}
}
4 changes: 2 additions & 2 deletions src/Telegram.Bot/Converters/InputFileConverter.cs
Expand Up @@ -32,7 +32,7 @@ public override void WriteJson(JsonWriter writer, InputFile? value, JsonSerializ
}

return Uri.TryCreate(value, UriKind.Absolute, out var url)
? new InputFileUrl(url)
: new InputFileId(value);
? InputFile.FromUri(url)
: InputFile.FromFileId(value);
}
}
54 changes: 54 additions & 0 deletions src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs
@@ -0,0 +1,54 @@
using System.Reflection;
using Newtonsoft.Json.Linq;

namespace Telegram.Bot.Converters;

internal class MaybeInaccessibleMessageConverter : JsonConverter
{
static readonly TypeInfo BaseType = typeof(MaybeInaccessibleMessage).GetTypeInfo();

public override bool CanWrite => false;
public override bool CanRead => true;
public override bool CanConvert(Type objectType) =>
BaseType.IsAssignableFrom(objectType.GetTypeInfo());

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is null)
{
writer.WriteNull();
}
else
{
var jo = JObject.FromObject(value);
jo.WriteTo(writer);
}
}

public override object? ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
JsonSerializer serializer)
{
var jo = JObject.Load(reader);
var date = jo["date"]?.Value<int>();

if (date is null)
{
return null;
}

var actualType = date switch
{
0 => typeof(InaccessibleMessage),
_ => typeof(Message),
};

// Remove status because status property only has getter
var value = Activator.CreateInstance(actualType)!;
serializer.Populate(jo.CreateReader(), value);

return value;
}
}
59 changes: 59 additions & 0 deletions src/Telegram.Bot/Converters/MessageOriginConverter.cs
@@ -0,0 +1,59 @@
using System.Reflection;
using Newtonsoft.Json.Linq;
using Telegram.Bot.Types.Enums;

namespace Telegram.Bot.Converters;

internal class MessageOriginConverter : JsonConverter
{
static readonly TypeInfo BaseType = typeof(MessageOrigin).GetTypeInfo();

public override bool CanWrite => false;
public override bool CanRead => true;
public override bool CanConvert(Type objectType) =>
BaseType.IsAssignableFrom(objectType.GetTypeInfo());

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is null)
{
writer.WriteNull();
}
else
{
var jo = JObject.FromObject(value);
jo.WriteTo(writer);
}
}

public override object? ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
JsonSerializer serializer)
{
var jo = JObject.Load(reader);
var type = jo["type"]?.ToObject<MessageOriginType>();

if (type is null)
{
return null;
}

var actualType = type switch
{
MessageOriginType.User => typeof(MessageOriginUser),
MessageOriginType.HiddenUser => typeof(MessageOriginHiddenUser),
MessageOriginType.Chat => typeof(MessageOriginChat),
MessageOriginType.Channel => typeof(MessageOriginChannel),
_ => throw new JsonSerializationException($"Unknown message origin type value of '{jo["type"]}'")
};

// Remove status because status property only has getter
jo.Remove("type");
var value = Activator.CreateInstance(actualType)!;
serializer.Populate(jo.CreateReader(), value);

return value;
}
}