Skip to content

Commit e10a824

Browse files
authored
Merge pull request #1457 from TelegramBots/develop
Bot API 8.3 + helpers
2 parents 87463f0 + 9462620 commit e10a824

File tree

320 files changed

+601
-125
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

320 files changed

+601
-125
lines changed

.azure-pipelines/variables.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
variables:
22
- group: Integration Tests Variables
33
- name: versionPrefix
4-
value: 22.3.0
4+
value: 22.4.0
55
- name: versionSuffix
66
value: ''
77
- name: ciVersionSuffix

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2022 Robin Müller, Telegram Bots
3+
Copyright (c) 2016-2025 Telegram Bots
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# .NET Client for Telegram Bot API
22

33
[![Nuget](https://img.shields.io/nuget/vpre/Telegram.Bot.svg?label=Telegram.Bot&style=flat-square&color=d8b541)](https://www.nuget.org/packages/Telegram.Bot)
4-
[![Bot API 8.2](https://img.shields.io/badge/Bot_API-8.2-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api)
4+
[![Bot API 8.3](https://img.shields.io/badge/Bot_API-8.3-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api)
55
[![Documentations](https://img.shields.io/badge/Documentations-Book-orange.svg?style=flat-square)](https://telegrambots.github.io/book/)
66
[![Telegram Chat](https://img.shields.io/badge/Support_Chat-Telegram-blue.svg?style=flat-square)](https://t.me/joinchat/B35YY0QbLfd034CFnvCtCA)
77
[![Master build](https://img.shields.io/azure-devops/build/tgbots/14f9ab3f-313a-4339-8534-e8b96c7763cc/6?style=flat-square&label=master)](https://dev.azure.com/tgbots/Telegram.Bot/_build/latest?definitionId=6&branchName=master)

src/Telegram.Bot/Extend.Types.cs

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,35 @@ public partial class User
6565
public override string ToString() => Username != null ? $"@{Username} ({Id})" : $"{FirstName}{LastName?.Insert(0, " ")} ({Id})";
6666
}
6767

68+
public partial class ChatMember
69+
{
70+
/// <summary>Check if the user is chat admin or owner</summary>
71+
[JsonIgnore]
72+
public bool IsAdmin => Status is ChatMemberStatus.Administrator or ChatMemberStatus.Creator;
73+
/// <summary>Check if the user is in the chat</summary>
74+
[JsonIgnore]
75+
public bool IsInChat => Status switch
76+
{
77+
ChatMemberStatus.Left or ChatMemberStatus.Kicked => false,
78+
ChatMemberStatus.Restricted => ((ChatMemberRestricted)this).IsMember,
79+
_ => true
80+
};
81+
}
82+
83+
public partial class ChatPermissions
84+
{
85+
/// <summary>Initializes a new <see cref="ChatPermissions"/> instance with all fields set to <see langword="false"/>.</summary>
86+
public ChatPermissions() { }
87+
/// <summary>Initializes a new <see cref="ChatPermissions"/> instance with all fields set to the specified value.</summary>
88+
/// <param name="defaultValue"><see langword="true"/> to allow all permissions by default</param>
89+
public ChatPermissions(bool defaultValue)
90+
{
91+
CanSendMessages = CanSendAudios = CanSendDocuments = CanSendPhotos = defaultValue;
92+
CanSendVideos = CanSendVideoNotes = CanSendVoiceNotes = CanSendPolls = CanSendOtherMessages = defaultValue;
93+
CanAddWebPagePreviews = CanChangeInfo = CanInviteUsers = CanPinMessages = CanManageTopics = defaultValue;
94+
}
95+
}
96+
6897
public partial class ReplyParameters
6998
{
7099
/// <summary>Implicit operator when you just want to reply to a message in same chat</summary>
@@ -162,16 +191,34 @@ public ReplyKeyboardMarkup(params KeyboardButton[] keyboardRow) : this(new List<
162191

163192
/// <summary>Generates a reply keyboard markup with one button</summary>
164193
/// <param name="text">Button's text</param>
194+
[return: NotNullIfNotNull(nameof(text))]
165195
public static implicit operator ReplyKeyboardMarkup?(string? text) => text is null ? default : new(text);
166196

167197
/// <summary>Generates a reply keyboard markup with multiple buttons on one row</summary>
168198
/// <param name="texts">Texts of buttons</param>
199+
[return: NotNullIfNotNull(nameof(texts))]
169200
public static implicit operator ReplyKeyboardMarkup?(string[]? texts) => texts is null ? default : new[] { texts };
170201

171202
/// <summary>Generates a reply keyboard markup with multiple buttons</summary>
172-
/// <param name="textsItems">Texts of buttons</param>
173-
public static implicit operator ReplyKeyboardMarkup?(string[][]? textsItems) => textsItems is null ? default
174-
: new ReplyKeyboardMarkup(textsItems.Select(texts => texts.Select(t => new KeyboardButton(t)).ToList()).ToList());
203+
/// <param name="texts">Texts of buttons</param>
204+
[return: NotNullIfNotNull(nameof(texts))]
205+
public static implicit operator ReplyKeyboardMarkup?(string[][]? texts) => texts is null ? default
206+
: new ReplyKeyboardMarkup(texts.Select(texts => texts.Select(t => new KeyboardButton(t)).ToList()).ToList());
207+
208+
/// <summary>Generates a reply keyboard markup with one button</summary>
209+
/// <param name="button">Keyboard button</param>
210+
[return: NotNullIfNotNull(nameof(button))]
211+
public static implicit operator ReplyKeyboardMarkup?(KeyboardButton? button) => button is null ? default : new(button);
212+
213+
/// <summary>Generates a reply keyboard markup with multiple buttons on one row</summary>
214+
/// <param name="buttons">Keyboard buttons</param>
215+
[return: NotNullIfNotNull(nameof(buttons))]
216+
public static implicit operator ReplyKeyboardMarkup?(KeyboardButton[]? buttons) => buttons is null ? default : new([buttons]);
217+
218+
/// <summary>Generates a reply keyboard markup with multiple buttons</summary>
219+
/// <param name="buttons">Keyboard buttons</param>
220+
[return: NotNullIfNotNull(nameof(buttons))]
221+
public static implicit operator ReplyKeyboardMarkup?(IEnumerable<KeyboardButton>[]? buttons) => buttons is null ? default : new(buttons);
175222

176223
/// <summary>Add a button to the last row</summary>
177224
/// <param name="button">The button or text to add</param>
@@ -242,19 +289,17 @@ public InlineKeyboardMarkup(params InlineKeyboardButton[] inlineKeyboardRow) : t
242289
/// <summary>Generate an inline keyboard markup with one button</summary>
243290
/// <param name="buttonText">Text of the button</param>
244291
[return: NotNullIfNotNull(nameof(buttonText))]
245-
public static implicit operator InlineKeyboardMarkup?(string? buttonText) => buttonText is null ? default : new(buttonText!);
246-
247-
/// <summary>Generate an inline keyboard markup from multiple buttons</summary>
248-
/// <param name="inlineKeyboard">Keyboard buttons</param>
249-
[return: NotNullIfNotNull(nameof(inlineKeyboard))]
250-
public static implicit operator InlineKeyboardMarkup?(IEnumerable<InlineKeyboardButton>[]? inlineKeyboard)
251-
=> inlineKeyboard is null ? default : new(inlineKeyboard);
292+
public static implicit operator InlineKeyboardMarkup?(string? buttonText) => buttonText is null ? default : new(buttonText);
252293

253294
/// <summary>Generate an inline keyboard markup from multiple buttons on 1 row</summary>
254-
/// <param name="inlineKeyboard">Keyboard buttons</param>
255-
[return: NotNullIfNotNull(nameof(inlineKeyboard))]
256-
public static implicit operator InlineKeyboardMarkup?(InlineKeyboardButton[]? inlineKeyboard)
257-
=> inlineKeyboard is null ? default : new(inlineKeyboard);
295+
/// <param name="buttons">Keyboard buttons</param>
296+
[return: NotNullIfNotNull(nameof(buttons))]
297+
public static implicit operator InlineKeyboardMarkup?(InlineKeyboardButton[]? buttons) => buttons is null ? default : new(buttons);
298+
299+
/// <summary>Generate an inline keyboard markup from multiple buttons</summary>
300+
/// <param name="buttons">Keyboard buttons</param>
301+
[return: NotNullIfNotNull(nameof(buttons))]
302+
public static implicit operator InlineKeyboardMarkup?(IEnumerable<InlineKeyboardButton>[]? buttons) => buttons is null ? default : new(buttons);
258303

259304
/// <summary>Add a button to the last row</summary>
260305
/// <param name="button">The button to add</param>
@@ -297,6 +342,19 @@ public InlineKeyboardMarkup AddNewRow(params InlineKeyboardButton[] buttons)
297342

298343
public partial class InlineKeyboardButton
299344
{
345+
/// <summary>Creates an inline keyboard button for external URL or for data to be sent in a <see cref="CallbackQuery">callback query</see> to the bot when the button is pressed, 1-64 bytes</summary>
346+
/// <param name="text">Label text on the button</param>
347+
/// <param name="callbackDataOrUrl">URL (starting with http:// or https://) to be opened, or data (1-64 characters) to be sent in a <see cref="CallbackQuery">callback query</see> to the bot, when the button is pressed</param>
348+
[SetsRequiredMembers]
349+
public InlineKeyboardButton(string text, string callbackDataOrUrl)
350+
{
351+
Text = text;
352+
if (callbackDataOrUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || callbackDataOrUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
353+
Url = callbackDataOrUrl;
354+
else
355+
CallbackData = callbackDataOrUrl;
356+
}
357+
300358
/// <summary>Performs an implicit conversion from <see cref="string"/> to <see cref="InlineKeyboardButton"/> with callback data</summary>
301359
/// <param name="textAndCallbackData">Label text and callback data of the button</param>
302360
/// <returns>The result of the conversion.</returns>

src/Telegram.Bot/Extensions/FormatExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public static string ToHtml(string message, MessageEntity[]? entities)
158158
if (tag[0] == 'a')
159159
{
160160
if (nextEntity.Type is MessageEntityType.TextLink)
161-
tag = $"<a href=\"{nextEntity.Url}\">";
161+
tag = $"<a href=\"{Escape(nextEntity.Url)}\">";
162162
else if (nextEntity.Type is MessageEntityType.TextMention)
163163
tag = $"<a href=\"tg://user?id={nextEntity.User?.Id}\">";
164164
}

src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// GENERATED FILE - DO NOT MODIFY MANUALLY
12
namespace Telegram.Bot.Requests;
23

34
/// <summary>Use this method to send answers to callback queries sent from <a href="https://core.telegram.org/bots/features#inline-keyboards">inline keyboards</a>. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert<para>Returns: </para></summary>

src/Telegram.Bot/Requests/Available methods/Commands/DeleteMyCommandsRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// GENERATED FILE - DO NOT MODIFY MANUALLY
12
namespace Telegram.Bot.Requests;
23

34
/// <summary>Use this method to delete the list of the bot's commands for the given scope and user language. After deletion, <a href="https://core.telegram.org/bots/api#determining-list-of-commands">higher level commands</a> will be shown to affected users.<para>Returns: </para></summary>

src/Telegram.Bot/Requests/Available methods/Commands/GetMyCommandsRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// GENERATED FILE - DO NOT MODIFY MANUALLY
12
namespace Telegram.Bot.Requests;
23

34
/// <summary>Use this method to get the current list of the bot's commands for the given scope and user language.<para>Returns: An Array of <see cref="BotCommand"/> objects. If commands aren't set, an empty list is returned.</para></summary>

src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// GENERATED FILE - DO NOT MODIFY MANUALLY
12
namespace Telegram.Bot.Requests;
23

34
/// <summary>Use this method to change the list of the bot's commands. See <a href="https://core.telegram.org/bots/features#commands">this manual</a> for more details about bot commands.<para>Returns: </para></summary>

src/Telegram.Bot/Requests/Available methods/CreateChatSubscriptionInviteLinkRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// GENERATED FILE - DO NOT MODIFY MANUALLY
12
namespace Telegram.Bot.Requests;
23

34
/// <summary>Use this method to create a <a href="https://telegram.org/blog/superchannels-star-reactions-subscriptions#star-subscriptions">subscription invite link</a> for a channel chat. The bot must have the <em>CanInviteUsers</em> administrator rights. The link can be edited using the method <see cref="TelegramBotClientExtensions.EditChatSubscriptionInviteLink">EditChatSubscriptionInviteLink</see> or revoked using the method <see cref="TelegramBotClientExtensions.RevokeChatInviteLink">RevokeChatInviteLink</see>.<para>Returns: The new invite link as a <see cref="ChatInviteLink"/> object.</para></summary>

0 commit comments

Comments
 (0)