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 5 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
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Expand Up @@ -21,6 +21,23 @@ 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)

### Added

- The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction.
- Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated`
and the field `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 field `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 type `SetMessageReactionRequest` that allows bots to react to messages.
- New method `ITelegramBotClient.SetMessageReactionAsync` that allows bots to react to messages.
- The field `AvailableReactions` to the class `Chat`.

## [v20.0.0] - Unreleased

> [Bot API 6.9](https://core.telegram.org/bots/api#september-22-2023) (September 22, 2023)
Expand Down
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.0%20(December%2029,%202023)-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api#december-29-2023)
[![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
4 changes: 2 additions & 2 deletions src/EnumSerializer.Generator/EnumSerializer.Generator.csproj
Expand Up @@ -14,9 +14,9 @@

<!-- 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.133" 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="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" PrivateAssets="all" />
<PackageReference Include="Scriban" Version="5.9.0" GeneratePathProperty="true" PrivateAssets="all" />

<!-- This ensures the library will be packaged as a source generator when we use `dotnet pack` -->
Expand Down
56 changes: 56 additions & 0 deletions src/Telegram.Bot/Converters/ReactionTypeConverter.cs
@@ -0,0 +1,56 @@
using System.Reflection;
using Newtonsoft.Json.Linq;

namespace Telegram.Bot.Converters;

internal class ReactionTypeConverter : JsonConverter
{
static readonly TypeInfo BaseType = typeof(ReactionType).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"]?.Value<string>();

if (type is null)
{
return null;
}

var actualType = type switch
{
"emoji" => typeof(ReactionTypeEmoji),
"custom_emoji" => typeof(ReactionTypeCustomEmoji),
_ => throw new JsonSerializationException($"Unknown reaction 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;
}
}
@@ -0,0 +1,57 @@
// ReSharper disable once CheckNamespace
using Telegram.Bot.Requests.Abstractions;

namespace Telegram.Bot.Requests;

/// <summary>
/// Use this method to change the chosen reactions on a message. Service messages can't be reacted to.
/// Automatically forwarded messages from a channel to its discussion group have the same
/// available reactions as messages in the channel.
/// Returns <see langword="true"/> on success.
/// </summary>
[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
public class SetMessageReactionRequest : RequestBase<bool>,
IChatTargetable
{
/// <inheritdoc />
[JsonProperty(Required = Required.Always)]
public ChatId ChatId { get; }

/// <summary>
/// Identifier of the target message. If the message belongs to a media group, the reaction
/// is set to the first non-deleted message in the group instead.
/// </summary>
[JsonProperty(Required = Required.Always)]
public int MessageId { get; }

/// <summary>
/// New list of reaction types to set on the message. Currently, as non-premium users, bots can
/// set up to one reaction per message. A custom emoji reaction can be used if it is either
/// already present on the message or explicitly allowed by chat administrators.
/// </summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public ReactionType[]? Reaction { get; set; }
karb0f0s marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Pass <see langword="true"/> to set the reaction with a big animation
/// </summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public bool? IsBig { get; set; }

/// <summary>
/// Initializes a new request with chatId and messageId
/// </summary>
/// <param name="chatId">Unique identifier for the target chat or username of the target channel
/// (in the format <c>@channelusername</c>)
/// </param>
/// <param name="messageId">
/// Identifier of the target message. If the message belongs to a media group, the reaction
/// is set to the first non-deleted message in the group instead.
/// </param>
public SetMessageReactionRequest(ChatId chatId, int messageId)
: base("setMessageReaction")
{
ChatId = chatId;
MessageId = messageId;
}
}
11 changes: 5 additions & 6 deletions src/Telegram.Bot/Telegram.Bot.csproj
Expand Up @@ -4,7 +4,6 @@
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
<LangVersion>11</LangVersion>
<Nullable>enable</Nullable>
<WarningLevel>7</WarningLevel>
<EnableNETAnalyzers>True</EnableNETAnalyzers>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<AnalysisLevel>latest-recommended</AnalysisLevel>
Expand Down Expand Up @@ -52,7 +51,7 @@
'HttpClient.GetAsync(Uri, HttpCompletionOption, CancellationToken)' instead
of 'HttpClient.GetAsync(string, HttpCompletionOption, CancellationToken)' -->
<NoWarn>$(NoWarn);CA1031</NoWarn> <!-- Catch a more specific allowed exception type, or rethrow the exception -->
<NoWarn>$(NoWarn);MA0046;MA0048;MA0051</NoWarn>
<NoWarn>$(NoWarn);MA0048;MA0051</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand All @@ -70,7 +69,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
Expand All @@ -79,9 +78,9 @@
</ItemGroup>

<ItemGroup Label="Dev">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.85" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="JetBrains.Annotations" Version="2023.2.0" PrivateAssets="All" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.133" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" />
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all" />
<ProjectReference Include="..\EnumSerializer.Generator\EnumSerializer.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
Expand Down
43 changes: 43 additions & 0 deletions src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs
Expand Up @@ -1804,6 +1804,49 @@ await botClient.ThrowIfNull()
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// Use this method to change the chosen reactions on a message. Service messages can't be reacted to.
/// Automatically forwarded messages from a channel to its discussion group have the same
/// available reactions as messages in the channel.
/// </summary>
/// <param name="botClient">An instance of <see cref="ITelegramBotClient"/></param>
/// <param name="chatId">
/// Unique identifier for the target chat or username of the target channel
/// (in the format <c>@channelusername</c>)
/// </param>
/// <param name="messageId">
/// Identifier of the target message. If the message belongs to a media group, the reaction
/// is set to the first non-deleted message in the group instead.
/// </param>
/// <param name="reaction">
/// New list of reaction types to set on the message. Currently, as non-premium users, bots can
/// set up to one reaction per message. A custom emoji reaction can be used if it is either
/// already present on the message or explicitly allowed by chat administrators.
/// </param>
/// <param name="isBig">
/// Pass <see langword="true"/> to set the reaction with a big animation
/// </param>
/// <param name="cancellationToken">
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation
/// </param>
public static async Task SetMessageReactionAsync(
this ITelegramBotClient botClient,
ChatId chatId,
int messageId,
ReactionType[]? reaction,
karb0f0s marked this conversation as resolved.
Show resolved Hide resolved
bool? isBig,
CancellationToken cancellationToken = default
) =>
await botClient.ThrowIfNull()
.MakeRequestAsync(
new SetMessageReactionRequest(chatId, messageId)
{
Reaction = reaction,
IsBig = isBig,
},
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// Use this method to get a list of profile pictures for a user.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Telegram.Bot/Types/Chat.cs
Expand Up @@ -68,6 +68,13 @@ public class Chat
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string[]? ActiveUsernames { get; set; }

/// <summary>
/// Optional. List of available reactions allowed in the chat. If omitted, then all <see cref="ReactionTypeEmoji.Emoji">emoji reactions</see> are allowed.
/// Returned only in <see cref="Requests.GetChatRequest"/>.
/// </summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public ReactionType[]? AvailableReactions { get; set; }

/// <summary>
/// Optional. Custom emoji identifier of emoji status of the other party in a private chat.
/// Returned only in <see cref="Requests.GetChatRequest"/>.
Expand Down
26 changes: 18 additions & 8 deletions src/Telegram.Bot/Types/Enums/UpdateType.cs
@@ -1,4 +1,4 @@
namespace Telegram.Bot.Types.Enums;
namespace Telegram.Bot.Types.Enums;

/// <summary>
/// The type of an <see cref="Update"/>
Expand Down Expand Up @@ -47,37 +47,47 @@ public enum UpdateType
EditedChannelPost,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="ShippingQuery"/>
/// The <see cref="Update"/> contains an <see cref="Payments.ShippingQuery"/>
/// </summary>
ShippingQuery,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="PreCheckoutQuery"/>
/// The <see cref="Update"/> contains an <see cref="Payments.PreCheckoutQuery"/>
/// </summary>
PreCheckoutQuery,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="Poll"/>
/// The <see cref="Update"/> contains an <see cref="Types.Poll"/>
/// </summary>
Poll,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="PollAnswer"/>
/// The <see cref="Update"/> contains an <see cref="Types.PollAnswer"/>
/// </summary>
PollAnswer,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="MyChatMember"/>
/// The <see cref="Update"/> contains an <see cref="Types.ChatMember"/>
/// </summary>
MyChatMember,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="ChatMember"/>
/// The <see cref="Update"/> contains an <see cref="Types.ChatMember"/>
/// </summary>
ChatMember,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="ChatJoinRequest"/>
/// The <see cref="Update"/> contains an <see cref="Types.ChatJoinRequest"/>
/// </summary>
ChatJoinRequest,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="Types.MessageReactionUpdated"/>
/// </summary>
MessageReaction,

/// <summary>
/// The <see cref="Update"/> contains an <see cref="Types.MessageReactionCountUpdated"/>
/// </summary>
MessageReactionCount,
}
35 changes: 35 additions & 0 deletions src/Telegram.Bot/Types/MessageReactionCountUpdated.cs
@@ -0,0 +1,35 @@
using Newtonsoft.Json.Converters;

namespace Telegram.Bot.Types;

/// <summary>
/// This object represents reaction changes on a message with anonymous reactions.
/// </summary>
[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
public class MessageReactionCountUpdated
{
/// <summary>
/// The chat containing the message
/// </summary>
[JsonProperty(Required = Required.Always)]
public Chat Chat { get; } = default!;

/// <summary>
/// Unique message identifier inside the chat
/// </summary>
[JsonProperty(Required = Required.Always)]
public int MessageId { get; } = default!;

/// <summary>
/// Date of the change
/// </summary>
[JsonProperty(Required = Required.Always)]
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime Date { get; } = default!;

/// <summary>
/// List of reactions that are present on the message
/// </summary>
[JsonProperty(Required = Required.Always)]
public ReactionCount[] Reactions { get; } = default!;
}