From 46953e744f0551b80ce64528bb37431cd80ad932 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Sat, 30 Dec 2023 02:39:08 +0100 Subject: [PATCH 01/12] APIv7.0 version change --- CHANGELOG.md | 4 ++++ README.md | 2 +- pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca768d0..a65b461 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.0 + +- Updated to bot API 7.0 + ## 1.1.0 - Stable release diff --git a/README.md b/README.md index cfe7f94..0971e1b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Dart Telegram Bot is a [Dart](https://dart.dev) wrapper for [Telegram](https://t bot [API](https://core.telegram.org/bots/api). \ It is compatible with Native, Flutter and JS. -[![Bot API Version](https://img.shields.io/badge/Bot%20API-6.9-blue.svg?style=flat-square)](https://core.telegram.org/bots/api) +[![Bot API Version](https://img.shields.io/badge/Bot%20API-7.0-blue.svg?style=flat-square)](https://core.telegram.org/bots/api) [![Dart Version](https://img.shields.io/badge/Dart-2.15.0-blue.svg?style=flat-square)](https://dart.dev) Using Dart Telegram Bot is straightforward, here's an example echo bot: diff --git a/pubspec.yaml b/pubspec.yaml index 63eba4f..4b82f9f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_telegram_bot description: A Telegram Bot API wrapper made to make fast Telegram bots with as less code as possible. -version: 1.1.0 +version: 1.2.0 homepage: https://github.com/KaikyuDev/dart-telegram-bot environment: From 5fd77e35f1192e0b84ebbe152e29ed710294e12f Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Sat, 30 Dec 2023 02:40:08 +0100 Subject: [PATCH 02/12] Added "Link Preview Customization" content --- lib/src/entities/internal/tgapi_methods.dart | 12 ++-- .../telegram/input_text_message_content.dart | 13 +++-- .../telegram/link_preview_options.dart | 58 +++++++++++++++++++ lib/src/entities/telegram/message.dart | 11 ++++ lib/telegram_entities.dart | 1 + test/main_test.dart | 2 +- 6 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 lib/src/entities/telegram/link_preview_options.dart diff --git a/lib/src/entities/internal/tgapi_methods.dart b/lib/src/entities/internal/tgapi_methods.dart index 876abdb..bdde5ec 100644 --- a/lib/src/entities/internal/tgapi_methods.dart +++ b/lib/src/entities/internal/tgapi_methods.dart @@ -48,7 +48,7 @@ mixin TGAPIMethods { int? messageThreadId, ParseMode? parseMode, List? entities, - bool? disableWebPagePreview, + LinkPreviewOptions? linkPreviewOptions, bool? disableNotification, bool? protectContent, int? replyToMessageId, @@ -61,7 +61,7 @@ mixin TGAPIMethods { 'message_thread_id': messageThreadId, 'parse_mode': parseMode, 'entities': entities, - 'disable_web_page_preview': disableWebPagePreview, + 'link_preview_options': linkPreviewOptions, 'disable_notification': disableNotification, 'protect_content': protectContent, 'reply_to_message_id': replyToMessageId, @@ -1631,7 +1631,7 @@ mixin TGAPIMethods { int? messageId, { ParseMode? parseMode, List? entities, - bool? disableWebPagePreview, + LinkPreviewOptions? linkPreviewOptions, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'editMessageText', { @@ -1640,7 +1640,7 @@ mixin TGAPIMethods { 'text': text, 'parse_mode': parseMode, 'entities': entities, - 'disable_web_page_preview': disableWebPagePreview, + 'link_preview_options': linkPreviewOptions, 'reply_markup': replyMarkup, }); } @@ -1653,7 +1653,7 @@ mixin TGAPIMethods { String? inlineMessageId, { ParseMode? parseMode, List? entities, - bool? disableWebPagePreview, + LinkPreviewOptions? linkPreviewOptions, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'editMessageText', { @@ -1661,7 +1661,7 @@ mixin TGAPIMethods { 'text': text, 'parse_mode': parseMode, 'entities': entities, - 'disable_web_page_preview': disableWebPagePreview, + 'link_preview_options': linkPreviewOptions, 'reply_markup': replyMarkup, }); } diff --git a/lib/src/entities/telegram/input_text_message_content.dart b/lib/src/entities/telegram/input_text_message_content.dart index 0e5f2d0..7f767b7 100644 --- a/lib/src/entities/telegram/input_text_message_content.dart +++ b/lib/src/entities/telegram/input_text_message_content.dart @@ -19,15 +19,15 @@ class InputTextMessageContent extends InputMessageContent { List? entities; /// Optional. - /// Disables link previews for links in the sent message - bool? disableWebPagePreview; + /// Link preview generation options for the message + LinkPreviewOptions? linkPreviewOptions; /// Basic constructor InputTextMessageContent( this.messageText, { this.parseMode, this.entities, - this.disableWebPagePreview, + this.linkPreviewOptions, }); /// Creates a object from a json @@ -39,7 +39,10 @@ class InputTextMessageContent extends InputMessageContent { MessageEntity.listFromJsonArray, json['entities'], ), - disableWebPagePreview: json['disable_web_page_preview'], + linkPreviewOptions: callIfNotNull( + LinkPreviewOptions.fromJson, + json['link_preview_options'], + ), ); } @@ -49,7 +52,7 @@ class InputTextMessageContent extends InputMessageContent { 'message_text': messageText, 'parse_mode': parseMode, 'entities': entities, - 'disable_web_page_preview': disableWebPagePreview, + 'link_preview_options': linkPreviewOptions, }..removeWhere((_, v) => v == null); } diff --git a/lib/src/entities/telegram/link_preview_options.dart b/lib/src/entities/telegram/link_preview_options.dart new file mode 100644 index 0000000..2dfbf36 --- /dev/null +++ b/lib/src/entities/telegram/link_preview_options.dart @@ -0,0 +1,58 @@ +/// Describes the options used for link preview generation. +class LinkPreviewOptions { + /// Optional. + /// True, if the link preview is disabled + final bool? isDisabled; + + /// Optional. + /// URL to use for the link preview. + /// If empty, then the first URL found in the message text will be used + final String? url; + + /// Optional. + /// True, if the media in the link preview is suppposed to be shrunk; + /// ignored if the URL isn't explicitly specified or media size change + /// isn't supported for the preview + final bool? preferSmallMedia; + + /// Optional. + /// True, if the media in the link preview is suppposed to be enlarged; + /// ignored if the URL isn't explicitly specified or media size change + /// isn't supported for the preview + final bool? preferLargeMedia; + + /// Optional. + /// True, if the link preview must be shown above the message text; + /// otherwise, the link preview will be shown below the message text + final bool? showAboveText; + + /// Basic constructor + LinkPreviewOptions({ + this.isDisabled, + this.url, + this.preferSmallMedia, + this.preferLargeMedia, + this.showAboveText, + }); + + /// Creates a object from a json + static LinkPreviewOptions fromJson(Map json) { + return LinkPreviewOptions( + isDisabled: json['is_disabled'], + url: json['url'], + preferSmallMedia: json['prefer_small_media'], + preferLargeMedia: json['prefer_large_media'], + showAboveText: json['show_above_text'], + ); + } + + Map toJson() { + return { + 'is_disabled': isDisabled, + 'url': url, + 'prefer_small_media': preferSmallMedia, + 'prefer_large_media': preferLargeMedia, + 'show_above_text': showAboveText, + }..removeWhere((_, v) => v == null); + } +} diff --git a/lib/src/entities/telegram/message.dart b/lib/src/entities/telegram/message.dart index 9e0c896..18e1150 100644 --- a/lib/src/entities/telegram/message.dart +++ b/lib/src/entities/telegram/message.dart @@ -107,6 +107,11 @@ class Message { /// etc. that appear in the text List? entities; + /// Optional. + /// Options used for link preview generation for the message, + /// if it is a text message and link preview options were changed + LinkPreviewOptions? linkPreviewOptions; + /// Optional. /// Message is an animation, information about the animation. /// For backward compatibility, when this field is set, the document fiel @@ -361,6 +366,7 @@ class Message { this.authorSignature, this.text, this.entities, + this.linkPreviewOptions, this.animation, this.audio, this.document, @@ -443,6 +449,10 @@ class Message { MessageEntity.listFromJsonArray, json['entities'], ), + linkPreviewOptions: callIfNotNull( + LinkPreviewOptions.fromJson, + json['link_preview_options'], + ), animation: callIfNotNull(Animation.fromJson, json['animation']), audio: callIfNotNull(Audio.fromJson, json['audio']), document: callIfNotNull(Document.fromJson, json['document']), @@ -585,6 +595,7 @@ class Message { 'author_signature': authorSignature, 'text': text, 'entities': entities, + 'link_preview_options': linkPreviewOptions, 'animation': animation, 'audio': audio, 'document': document, diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index 166cc3f..5c66eff 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -76,6 +76,7 @@ export 'src/entities/telegram/invoice.dart'; export 'src/entities/telegram/keyboard_button.dart'; export 'src/entities/telegram/keyboard_button_poll_type.dart'; export 'src/entities/telegram/labeled_price.dart'; +export 'src/entities/telegram/link_preview_options.dart'; export 'src/entities/telegram/location.dart'; export 'src/entities/telegram/login_url.dart'; export 'src/entities/telegram/mask_position.dart'; diff --git a/test/main_test.dart b/test/main_test.dart index 349ad8c..e613243 100644 --- a/test/main_test.dart +++ b/test/main_test.dart @@ -83,7 +83,7 @@ void main() { '*Test*', replyToMessageId: replyId, disableNotification: true, - disableWebPagePreview: true, + linkPreviewOptions: LinkPreviewOptions(isDisabled: true), parseMode: ParseMode.markdown, ); expect(message.entities!.length, equals(1)); From 3e2c45f2e15523e806293e4f4beeff6481cddd07 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Sat, 30 Dec 2023 03:39:49 +0100 Subject: [PATCH 03/12] Added "Multiple Message Actions" content --- lib/src/entities/internal/tgapi_methods.dart | 77 ++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/lib/src/entities/internal/tgapi_methods.dart b/lib/src/entities/internal/tgapi_methods.dart index bdde5ec..f891406 100644 --- a/lib/src/entities/internal/tgapi_methods.dart +++ b/lib/src/entities/internal/tgapi_methods.dart @@ -92,6 +92,34 @@ mixin TGAPIMethods { }); } + /// Use this method to forward multiple messages of any kind. + /// + /// If some of the specified messages can't be found or forwarded, + /// they are skipped. + /// + /// Service messages and messages with protected content can't be forwarded. + /// + /// Album grouping is kept for forwarded messages. + /// + /// On success, an array of MessageId of the sent messages is returned. + Future> forwardMessages( + ChatID chatId, + ChatID fromChatId, + List messageIds, { + int? messageThreadId, + bool? disableNotification, + bool? protectContent, + }) { + return _client.apiCall(_token, 'forwardMessages', { + 'chat_id': chatId, + 'from_chat_id': fromChatId, + 'message_ids': messageIds, + 'message_thread_id': messageThreadId, + 'disable_notification': disableNotification, + 'protect_content': protectContent, + }); + } + /// Use this method to copy messages of any kind. /// /// Service messages and invoice messages can't be copied. @@ -130,6 +158,43 @@ mixin TGAPIMethods { }); } + /// Use this method to copy messages of any kind. + /// + /// If some of the specified messages can't be found or copied, + /// they are skipped. + /// + /// Service messages, giveaway messages, giveaway winners messages, + /// and invoice messages can't be copied. + /// + /// A quiz poll can be copied only if the value of the field + /// correct_option_id is known to the bot. + /// + /// The method is analogous to the method forwardMessages, + /// but the copied messages don't have a link to the original message. + /// + /// Album grouping is kept for copied messages. + /// + /// On success, an array of MessageId of the sent messages is returned. + Future> copyMessages( + ChatID chatId, + ChatID fromChatId, + List messageIds, { + int? messageThreadId, + bool? disableNotification, + bool? protectContent, + bool? removeCaption, + }) { + return _client.apiCall(_token, 'copyMessages', { + 'chat_id': chatId, + 'from_chat_id': fromChatId, + 'message_ids': messageIds, + 'message_thread_id': messageThreadId, + 'disable_notification': disableNotification, + 'protect_content': protectContent, + 'remove_caption': removeCaption, + }); + } + /// Use this method to send photos. /// /// On success, the sent [Message] is returned. @@ -1820,6 +1885,18 @@ mixin TGAPIMethods { }); } + /// Use this method to delete multiple messages simultaneously. + /// + /// If some of the specified messages can't be found, they are skipped. + /// + /// Returns True on success. + Future deleteMessages(ChatID chatId, List messageIds) { + return _client.apiCall(_token, 'deleteMessages', { + 'chat_id': chatId, + 'message_ids': messageIds, + }); + } + /// Use this method to send static .WEBP, animated .TGS, /// or video .WEBM stickers. /// From ea33dd0396e4ef677e7d394a6f0e6680e4f70566 Mon Sep 17 00:00:00 2001 From: ale183 Date: Fri, 12 Jan 2024 12:07:32 +0100 Subject: [PATCH 04/12] giveaway --- lib/src/entities/telegram/giveaway.dart | 85 +++++++++++++++ .../entities/telegram/giveaway_completed.dart | 45 ++++++++ .../entities/telegram/giveaway_created.dart | 22 ++++ .../entities/telegram/giveaway_winners.dart | 101 ++++++++++++++++++ lib/src/entities/telegram/message.dart | 40 +++++++ lib/telegram_entities.dart | 4 + 6 files changed, 297 insertions(+) create mode 100644 lib/src/entities/telegram/giveaway.dart create mode 100644 lib/src/entities/telegram/giveaway_completed.dart create mode 100644 lib/src/entities/telegram/giveaway_created.dart create mode 100644 lib/src/entities/telegram/giveaway_winners.dart diff --git a/lib/src/entities/telegram/giveaway.dart b/lib/src/entities/telegram/giveaway.dart new file mode 100644 index 0000000..478c1d5 --- /dev/null +++ b/lib/src/entities/telegram/giveaway.dart @@ -0,0 +1,85 @@ +import 'dart:convert'; +import '../../../telegram_entities.dart'; + +/// This object represents a message about a scheduled giveaway. +class Giveaway { + /// The list of chats which the user must join to participate in the giveaway + List chats; + + /// Point in time (Unix timestamp) when winners of the giveaway will + /// be selected + int winnersSelectionDate; + + /// The number of users which are supposed to be selected as winners + /// of the giveaway + int winnerCount; + + /// Optional. + /// True, if only users who join the chats after the giveaway started + /// should be eligible to win + bool? onlyNewMembers; + + /// Optional. + /// True, if the list of giveaway winners will be visible to everyone + bool? hasPublicWinners; + + /// Optional. + /// Description of additional giveaway prize + String? prizeDescription; + + /// Optional. + /// A list of two-letter ISO 3166-1 alpha-2 country codes indicating the + /// countries from which eligible users for the giveaway must come. + /// If empty, then all users can participate in the giveaway. + /// Users with a phone number that was bought on Fragment can always + /// participate in giveaways. + List? countryCodes; + + /// Optional. + /// The number of months the Telegram Premium subscription won from the + /// giveaway will be active for + int? premiumSubscriptionMonthCount; + + /// Basic constructor + Giveaway({ + required this.chats, + required this.winnersSelectionDate, + required this.winnerCount, + this.onlyNewMembers, + this.hasPublicWinners, + this.prizeDescription, + this.countryCodes, + this.premiumSubscriptionMonthCount, + }); + + /// Creates a object from a json + static Giveaway fromJson(Map json) { + return Giveaway( + chats: json['chats'], + winnersSelectionDate: json['winners_selection_date'], + winnerCount: json['winner_count'], + onlyNewMembers: json['only_new_members'], + hasPublicWinners: json['has_public_winners'], + prizeDescription: json['prize_description'], + countryCodes: json['country_codes'], + premiumSubscriptionMonthCount: json['premium_subscription_month_count'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'chats': chats, + 'winners_selection_date': winnersSelectionDate, + 'winner_count': winnerCount, + 'only_new_members': onlyNewMembers, + 'has_public_winners': hasPublicWinners, + 'prize_description': prizeDescription, + 'country_codes': countryCodes, + 'premium_subscription_month_count': premiumSubscriptionMonthCount, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/giveaway_completed.dart b/lib/src/entities/telegram/giveaway_completed.dart new file mode 100644 index 0000000..2a7b0bf --- /dev/null +++ b/lib/src/entities/telegram/giveaway_completed.dart @@ -0,0 +1,45 @@ +import 'dart:convert'; +import '../../../telegram_entities.dart'; + +/// This object represents a service message about the completion of a +/// giveaway without public winners. +class GiveawayCompleted { + /// Number of winners in the giveaway + int winnerCount; + + /// Optional. + /// Number of undistributed prizes + int? unclaimedPrizeCount; + + /// Optional. + /// Message with the giveaway that was completed, if it wasn't deleted + Message? giveawayMessage; + + /// Basic constructor + GiveawayCompleted({ + required this.winnerCount, + this.unclaimedPrizeCount, + this.giveawayMessage, + }); + + /// Creates a object from a json + static GiveawayCompleted fromJson(Map json) { + return GiveawayCompleted( + winnerCount: json['winner_count'], + unclaimedPrizeCount: json['unclaimed_prize_count'], + giveawayMessage: json['giveaway_message'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'winner_count': winnerCount, + 'unclaimed_prize_count': unclaimedPrizeCount, + 'giveaway_message': giveawayMessage, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/giveaway_created.dart b/lib/src/entities/telegram/giveaway_created.dart new file mode 100644 index 0000000..12911f1 --- /dev/null +++ b/lib/src/entities/telegram/giveaway_created.dart @@ -0,0 +1,22 @@ +import 'dart:convert'; + +/// This object represents a service message about the creation of a scheduled +/// giveaway. +/// Currently holds no information. +class GiveawayCreated { + /// Basic constructor + GiveawayCreated(); + + /// Creates a object from json + static GiveawayCreated fromJson(Map json) { + return GiveawayCreated(); + } + + /// Creates a json from the object + Map toJson() { + return {}; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/giveaway_winners.dart b/lib/src/entities/telegram/giveaway_winners.dart new file mode 100644 index 0000000..192e070 --- /dev/null +++ b/lib/src/entities/telegram/giveaway_winners.dart @@ -0,0 +1,101 @@ +import 'dart:convert'; +import '../../../telegram_entities.dart'; + +/// This object represents a message about the completion of a giveaway with +/// public winners. +class GiveawayWinners { + /// The chat that created the giveaway + Chat chat; + + /// Identifier of the messsage with the giveaway in the chat + int giveawayMessageId; + + /// Point in time (Unix timestamp) when winners of the giveaway were + /// selected + int winnersSelectionDate; + + /// Total number of winners in the giveaway + int winnerCount; + + /// List of up to 100 winners of the giveaway + List winners; + + /// Optional. + /// The number of other chats the user had to join in order to be eligible + /// for the giveaway + int? additionalChatCount; + + /// Optional. + /// The number of months the Telegram Premium subscription won from the + /// giveaway will be active for + int? premiumSubscriptionMonthCount; + + /// Optional. + /// Number of undistributed prizes + int? unclaimedPrizeCount; + + /// Optional. + /// True, if only users who had joined the chats after the giveaway started + /// were eligible to win + bool? onlyNewMembers; + + /// Optional. + /// True, if the giveaway was canceled because the payment for it was refunded + bool? wasRefunded; + + /// Optional. + /// Description of additional giveaway prize + String? prizeDescription; + + /// Basic constructor + GiveawayWinners({ + required this.chat, + required this.giveawayMessageId, + required this.winnersSelectionDate, + required this.winnerCount, + required this.winners, + this.additionalChatCount, + this.premiumSubscriptionMonthCount, + this.unclaimedPrizeCount, + this.onlyNewMembers, + this.wasRefunded, + this.prizeDescription, + }); + + /// Creates a object from a json + static GiveawayWinners fromJson(Map json) { + return GiveawayWinners( + chat: Chat.fromJson(json['chat']), + giveawayMessageId: json['giveaway_message_id'], + winnersSelectionDate: json['winners_selection_date'], + winnerCount: json['winner_count'], + winners: User.listFromJsonArray(json['winners']), + additionalChatCount: json['additional_chat_count'], + premiumSubscriptionMonthCount: json['premium_subscription_month_count'], + unclaimedPrizeCount: json['unclaimed_prize_count'], + onlyNewMembers: json['only_new_members'], + wasRefunded: json['was_refunded'], + prizeDescription: json['prize_description'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'chat': chat, + 'giveaway_message_id': giveawayMessageId, + 'winners_selection_date': winnersSelectionDate, + 'winner_count': winnerCount, + 'winners': winners, + 'additional_chat_count': additionalChatCount, + 'premium_subscription_month_count': premiumSubscriptionMonthCount, + 'unclaimed_prize_count': unclaimedPrizeCount, + 'only_new_members': onlyNewMembers, + 'was_refunded': wasRefunded, + 'prize_description': prizeDescription, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/message.dart b/lib/src/entities/telegram/message.dart index 18e1150..30985df 100644 --- a/lib/src/entities/telegram/message.dart +++ b/lib/src/entities/telegram/message.dart @@ -317,6 +317,22 @@ class Message { /// Service message: the 'General' forum topic unhidden GeneralForumTopicUnhidden? generalForumTopicUnhidden; + /// Optional. + /// Service message: a scheduled giveway was created + GiveawayCreated? giveawayCreated; + + /// Optional. + /// The message is a scheduled giveaway message + Giveaway? giveaway; + + /// Optional. + /// A giveaway with public winners was completed + GiveawayWinners? giveawayWinners; + + /// Optional. + /// Service message: a giveaway without public winners was completed + GiveawayCompleted? giveawayCompleted; + /// Optional. /// Service message: video chat scheduled VideoChatScheduled? videoChatScheduled; @@ -407,6 +423,10 @@ class Message { this.forumTopicCreated, this.forumTopicClosed, this.forumTopicReopened, + this.giveawayCreated, + this.giveaway, + this.giveawayWinners, + this.giveawayCompleted, this.videoChatScheduled, this.videoChatStarted, this.videoChatEnded, @@ -535,6 +555,22 @@ class Message { ForumTopicReopened.fromJson, json['forum_topic_reopened'], ), + giveawayCreated: callIfNotNull( + GiveawayCreated.fromJson, + json['giveaway_created'], + ), + giveaway: callIfNotNull( + Giveaway.fromJson, + json['giveaway'], + ), + giveawayWinners: callIfNotNull( + GiveawayWinners.fromJson, + json['giveaway_winners'], + ), + giveawayCompleted: callIfNotNull( + GiveawayCompleted.fromJson, + json['giveaway_ccompleted'], + ), videoChatScheduled: callIfNotNull( VideoChatScheduled.fromJson, json['video_chat_scheduled'], @@ -636,6 +672,10 @@ class Message { 'forum_topic_created': forumTopicCreated, 'forum_topic_closed': forumTopicClosed, 'forum_topic_reopened': forumTopicReopened, + 'giveaway_created': giveawayCreated, + 'giveaway': giveaway, + 'giveaway_winners': giveawayWinners, + 'giveaway_completed': giveawayCompleted, 'video_chat_scheduled': videoChatScheduled, 'video_chat_started': videoChatStarted, 'video_chat_ended': videoChatEnded, diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index 5c66eff..82724f7 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -137,3 +137,7 @@ export 'src/entities/telegram/inline_query_results_button.dart'; export 'src/entities/telegram/switch_inline_query_chosen_chat.dart'; export 'src/entities/telegram/bot_name.dart'; export 'src/entities/telegram/story.dart'; +export 'src/entities/telegram/giveaway_created.dart'; +export 'src/entities/telegram/giveaway.dart'; +export 'src/entities/telegram/giveaway_winners.dart'; +export 'src/entities/telegram/giveaway_completed.dart'; From ba5ef6412a45603ed252ac9fc6548028fa97be19 Mon Sep 17 00:00:00 2001 From: ale183 Date: Fri, 12 Jan 2024 12:09:53 +0100 Subject: [PATCH 05/12] Forum Topic --- lib/src/entities/telegram/message.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/src/entities/telegram/message.dart b/lib/src/entities/telegram/message.dart index 30985df..9879013 100644 --- a/lib/src/entities/telegram/message.dart +++ b/lib/src/entities/telegram/message.dart @@ -423,6 +423,8 @@ class Message { this.forumTopicCreated, this.forumTopicClosed, this.forumTopicReopened, + this.generalForumTopicHidden, + this.generalForumTopicUnhidden, this.giveawayCreated, this.giveaway, this.giveawayWinners, @@ -555,6 +557,14 @@ class Message { ForumTopicReopened.fromJson, json['forum_topic_reopened'], ), + generalForumTopicHidden: callIfNotNull( + GeneralForumTopicHidden.fromJson, + json['general_forum_topic_hidden'], + ), + generalForumTopicUnhidden: callIfNotNull( + GeneralForumTopicUnhidden.fromJson, + json['general_forum_topic_unhidden'], + ), giveawayCreated: callIfNotNull( GiveawayCreated.fromJson, json['giveaway_created'], @@ -672,6 +682,8 @@ class Message { 'forum_topic_created': forumTopicCreated, 'forum_topic_closed': forumTopicClosed, 'forum_topic_reopened': forumTopicReopened, + 'general_forum_topic_hidden': generalForumTopicHidden, + 'general_forum_topic_unhidden': generalForumTopicUnhidden, 'giveaway_created': giveawayCreated, 'giveaway': giveaway, 'giveaway_winners': giveawayWinners, From ebb781e8bb453d1d46b266717e1e013a94457f28 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Sun, 21 Jan 2024 16:48:35 +0100 Subject: [PATCH 06/12] Minor fixes and improvements --- CHANGELOG.md | 1 + example/bot_example.dart | 124 +++++++++--------- lib/src/entities/internal/bot.dart | 28 ++-- .../entities/internal/entities/chat_id.dart | 8 +- .../internal/helpers/bot_command_parser.dart | 2 +- lib/src/entities/internal/tgapi_client.dart | 11 +- lib/src/entities/internal/tgapi_methods.dart | 12 +- lib/src/entities/telegram/animation.dart | 2 +- lib/src/entities/telegram/audio.dart | 2 +- lib/src/entities/telegram/bot_command.dart | 4 +- .../entities/telegram/bot_command_scope.dart | 3 +- .../entities/telegram/bot_description.dart | 2 +- lib/src/entities/telegram/bot_name.dart | 2 +- .../telegram/bot_short_description.dart | 2 +- lib/src/entities/telegram/callback_game.dart | 2 +- lib/src/entities/telegram/callback_query.dart | 2 +- lib/src/entities/telegram/chat.dart | 2 +- .../telegram/chat_administrator_rights.dart | 2 +- .../entities/telegram/chat_invite_link.dart | 2 +- .../entities/telegram/chat_join_request.dart | 2 +- lib/src/entities/telegram/chat_location.dart | 2 +- lib/src/entities/telegram/chat_member.dart | 2 +- .../telegram/chat_member_updated.dart | 2 +- .../entities/telegram/chat_permissions.dart | 8 +- lib/src/entities/telegram/chat_photo.dart | 6 +- lib/src/entities/telegram/chat_shared.dart | 2 +- .../telegram/chosen_inline_result.dart | 2 +- lib/src/entities/telegram/contact.dart | 2 +- lib/src/entities/telegram/dice.dart | 2 +- lib/src/entities/telegram/document.dart | 2 +- .../telegram/encrypted_credentials.dart | 2 +- .../telegram/encrypted_passport_element.dart | 2 +- lib/src/entities/telegram/file.dart | 2 +- lib/src/entities/telegram/force_reply.dart | 2 +- lib/src/entities/telegram/forum_topic.dart | 2 +- .../entities/telegram/forum_topic_closed.dart | 2 +- .../telegram/forum_topic_created.dart | 2 +- .../entities/telegram/forum_topic_edited.dart | 2 +- .../telegram/forum_topic_reopened.dart | 2 +- lib/src/entities/telegram/game.dart | 2 +- .../entities/telegram/game_high_score.dart | 2 +- .../telegram/general_forum_topic_hidden.dart | 2 +- .../general_forum_topic_unhidden.dart | 2 +- lib/src/entities/telegram/giveaway.dart | 2 +- .../entities/telegram/giveaway_completed.dart | 2 +- .../entities/telegram/giveaway_created.dart | 2 +- .../entities/telegram/giveaway_winners.dart | 2 +- .../telegram/inline_keyboard_button.dart | 5 +- .../telegram/inline_keyboard_markup.dart | 2 +- lib/src/entities/telegram/inline_query.dart | 2 +- .../telegram/inline_query_result.dart | 3 +- .../telegram/inline_query_results_button.dart | 2 +- .../input_contact_message_content.dart | 5 +- .../input_location_message_content.dart | 2 +- lib/src/entities/telegram/input_sticker.dart | 6 +- .../telegram/input_text_message_content.dart | 2 +- .../telegram/input_venue_message_content.dart | 2 +- lib/src/entities/telegram/invoice.dart | 2 +- .../entities/telegram/keyboard_button.dart | 5 +- .../telegram/keyboard_button_poll_type.dart | 2 +- .../keyboard_button_request_chat.dart | 2 +- .../keyboard_button_request_user.dart | 2 +- lib/src/entities/telegram/labeled_price.dart | 2 +- .../telegram/link_preview_options.dart | 7 +- lib/src/entities/telegram/location.dart | 2 +- lib/src/entities/telegram/login_url.dart | 2 +- lib/src/entities/telegram/mask_position.dart | 2 +- .../telegram/menu_button_commands.dart | 2 +- .../telegram/menu_button_default.dart | 2 +- .../telegram/menu_button_web_app.dart | 4 +- lib/src/entities/telegram/message.dart | 4 +- .../message_auto_delete_timer_changed.dart | 2 +- lib/src/entities/telegram/message_entity.dart | 2 +- lib/src/entities/telegram/message_id.dart | 2 +- lib/src/entities/telegram/order_info.dart | 2 +- lib/src/entities/telegram/passport_data.dart | 2 +- lib/src/entities/telegram/passport_file.dart | 2 +- lib/src/entities/telegram/photo_size.dart | 2 +- lib/src/entities/telegram/poll.dart | 2 +- lib/src/entities/telegram/poll_answer.dart | 2 +- lib/src/entities/telegram/poll_option.dart | 2 +- .../entities/telegram/pre_checkout_query.dart | 2 +- .../telegram/proximity_alert_triggered.dart | 2 +- .../telegram/reply_keyboard_markup.dart | 2 +- .../telegram/reply_keyboard_remove.dart | 2 +- .../telegram/response_parameters.dart | 2 +- .../telegram/sent_web_app_message.dart | 2 +- .../entities/telegram/shipping_address.dart | 2 +- .../entities/telegram/shipping_option.dart | 2 +- lib/src/entities/telegram/shipping_query.dart | 2 +- lib/src/entities/telegram/sticker.dart | 2 +- lib/src/entities/telegram/sticker_set.dart | 2 +- lib/src/entities/telegram/story.dart | 2 +- .../entities/telegram/successful_payment.dart | 2 +- .../switch_inline_query_chosen_chat.dart | 2 +- lib/src/entities/telegram/update.dart | 2 +- lib/src/entities/telegram/user.dart | 2 +- .../telegram/user_profile_photos.dart | 2 +- lib/src/entities/telegram/user_shared.dart | 2 +- lib/src/entities/telegram/venue.dart | 2 +- lib/src/entities/telegram/video.dart | 2 +- .../entities/telegram/video_chat_ended.dart | 5 +- .../video_chat_participants_invited.dart | 4 +- .../telegram/video_chat_scheduled.dart | 2 +- .../entities/telegram/video_chat_started.dart | 2 +- lib/src/entities/telegram/video_note.dart | 2 +- lib/src/entities/telegram/voice.dart | 2 +- lib/src/entities/telegram/web_app_data.dart | 2 +- lib/src/entities/telegram/web_app_info.dart | 2 +- .../telegram/write_access_allowed.dart | 2 +- lib/telegram_entities.dart | 58 ++++---- test/main_test.dart | 88 +++++++------ 112 files changed, 303 insertions(+), 276 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a65b461..3deb448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 1.2.0 - Updated to bot API 7.0 +- Minor improvements ## 1.1.0 diff --git a/example/bot_example.dart b/example/bot_example.dart index 64f9b9b..6133698 100644 --- a/example/bot_example.dart +++ b/example/bot_example.dart @@ -21,76 +21,70 @@ void main(List arguments) async { var token = Platform.environment['BOT_TOKEN']!; - var bot = Bot( + Bot( token: token, onReady: onReady, onStartFailed: onStartFailed, allowedUpdates: UpdateType.allBut([UpdateType.editedMessage]), - ); - - bot.onUpdate(_onUpdate); - - bot.onCommand('buttons', (bot, update) async { - var buttons = [ - [InlineKeyboardButton.callbackData('Button 1', 'btn1')], - [InlineKeyboardButton.callbackData('Button 2', 'btn2')] - ]; - await bot.sendMessage( - ChatID(update.message!.chat.id), - 'Tap a button...', - replyMarkup: InlineKeyboardMarkup(buttons), - ); - }); - - bot.onCommand('chatid', (bot, update) async { - await bot.sendMessage( - ChatID(update.message!.chat.id), - '*Chat ID*: `${update.message!.chat.id}`', - parseMode: ParseMode.markdown, - ); - }); - - bot.onCommand('msgid', (bot, update) async { - await bot.sendMessage( - ChatID(update.message!.chat.id), - '*Message ID*: `${update.message!.messageId}`', - parseMode: ParseMode.markdown, - ); - }); - - bot.onCommand('uid', (bot, update) async { - await bot.sendMessage( - ChatID(update.message!.chat.id), - '*ID*: `${update.message!.from!.id}`', - parseMode: ParseMode.markdown, - ); - }); - - bot.onCommand('quid', (bot, update) async { - if (update.message!.replyToMessage == null) return; - await bot.sendMessage( - ChatID(update.message!.chat.id), - '*ID*: `${update.message!.replyToMessage!.from!.id}`', - parseMode: ParseMode.markdown, - ); - }); - - bot.onCommand('poll', (bot, update) async { - await bot.sendPoll( - ChatID(update.message!.chat.id), - 'Nani desu ka?', - ['Hai!', 'Ara ara?', '!'], - replyToMessageId: update.message!.messageId, - allowsMultipleAnswers: true, - isAnonymous: true, - type: 'quiz', - correctOptionId: 1, - ); - }); + ) + ..errorHandler = defaultErrorHandler + ..onUpdate(_onUpdate) + ..onCommand('buttons', (bot, update) async { + var buttons = [ + [InlineKeyboardButton.callbackData('Button 1', 'btn1')], + [InlineKeyboardButton.callbackData('Button 2', 'btn2')], + ]; + await bot.sendMessage( + ChatID(update.message!.chat.id), + 'Tap a button...', + replyMarkup: InlineKeyboardMarkup(buttons), + ); + }) + ..onCommand('chatid', (bot, update) async { + await bot.sendMessage( + ChatID(update.message!.chat.id), + '*Chat ID*: `${update.message!.chat.id}`', + parseMode: ParseMode.markdown, + ); + }) + ..onCommand('msgid', (bot, update) async { + await bot.sendMessage( + ChatID(update.message!.chat.id), + '*Message ID*: `${update.message!.messageId}`', + parseMode: ParseMode.markdown, + ); + }) + ..onCommand('uid', (bot, update) async { + await bot.sendMessage( + ChatID(update.message!.chat.id), + '*ID*: `${update.message!.from!.id}`', + parseMode: ParseMode.markdown, + ); + }) + ..onCommand('quid', (bot, update) async { + if (update.message!.replyToMessage == null) return; + await bot.sendMessage( + ChatID(update.message!.chat.id), + '*ID*: `${update.message!.replyToMessage!.from!.id}`', + parseMode: ParseMode.markdown, + ); + }) + ..onCommand('poll', (bot, update) async { + await bot.sendPoll( + ChatID(update.message!.chat.id), + 'Nani desu ka?', + ['Hai!', 'Ara ara?', '!'], + replyToMessageId: update.message!.messageId, + allowsMultipleAnswers: true, + isAnonymous: true, + type: 'quiz', + correctOptionId: 1, + ); + }); } -void defaultErrorHandler(Object e, StackTrace s) { - print('something failed: $e\n$s'); +Future defaultErrorHandler(_, __, Object e, StackTrace s) async { + print('Something failed: $e\n$s'); } void onStartFailed(Bot bot, Object err, StackTrace st) { @@ -132,7 +126,7 @@ Future _onUpdate(Bot bot, Update update) async { '/results?search_query=Zekk+-+TOMOYO)', parseMode: ParseMode.markdown, ), - ) + ), ], cacheTime: 0, ); diff --git a/lib/src/entities/internal/bot.dart b/lib/src/entities/internal/bot.dart index 3f3a340..796c954 100644 --- a/lib/src/entities/internal/bot.dart +++ b/lib/src/entities/internal/bot.dart @@ -30,7 +30,8 @@ class Bot with TGAPIMethods { var _log = Logger('Bot'); - /// List of allowed updates to be received
+ /// List of allowed updates to be received + /// /// Can be changed while the bot is running List? allowedUpdates; @@ -72,7 +73,7 @@ class Bot with TGAPIMethods { _timeout = timeout, _onStartFailedEvent = onStartFailed { this.token = token; - _setup(); + unawaited(_setup()); } /// Override this method when extending this class @@ -104,7 +105,7 @@ class Bot with TGAPIMethods { var user = await getMe(); _id = user.id; _name = user.firstName; - _username = user.username!; + _username = user.username; _log = Logger(_name!); } @@ -114,13 +115,15 @@ class Bot with TGAPIMethods { if (clean) { await _cleanUpdates(); } + await _eventLoop(); // Clean last read update await getUpdates(timeout: 0, offset: _offset); } /// Adds a new update handler - /// which is executed on each update
+ /// which is executed on each update + /// /// If an handler throws an error, [errorHandler] is called /// and the next handler/update is elaborated void onUpdate(Future Function(Bot, Update) callback) { @@ -142,8 +145,9 @@ class Bot with TGAPIMethods { } Future _criticalErrorHandler(Object e, StackTrace st) async { - _log.severe('An exception occurred during an exception handling'); - _log.severe(e, st); + _log + ..severe('An exception occurred during an exception handling') + ..severe(e, st); } Future _onConnectionError(Bot bot, Object error, StackTrace st) async { @@ -170,14 +174,13 @@ class Bot with TGAPIMethods { closeClient(); return; } + await _onReady(); } void _runProtectedSimple(Function foo) { runZonedGuarded( - () { - foo(); - }, + () => foo(), _criticalErrorHandler, ); } @@ -189,7 +192,7 @@ class Bot with TGAPIMethods { }) { runZonedGuarded( foo, - (e, s) => (customErrHandler ?? _onError)(this, update, e, s), + (e, s) async => (customErrHandler ?? _onError)(this, update, e, s), ); } @@ -198,6 +201,7 @@ class Bot with TGAPIMethods { Future _checkCommands(Update update) async { var message = update.message; if (message == null || message.text == null) return false; + var cmdParser = BotCommandParser.fromMessage(message); if (cmdParser == null) return false; @@ -208,6 +212,7 @@ class Bot with TGAPIMethods { username: username, ); if (!isMatching) continue; + anyExecuted = true; _runProtected(() => commandEntry.value.call(this, update), update); } @@ -216,6 +221,7 @@ class Bot with TGAPIMethods { Future _handleUpdate(Update update) async { if (await _checkCommands(update)) return; + for (var callback in _updateCallbacks) { _runProtected(() => callback(this, update), update); } @@ -237,7 +243,7 @@ class Bot with TGAPIMethods { } } on ClientException catch (e, s) { await _onConnectionError(this, e, s); - await Future.delayed(Duration(seconds: 1)); + await Future.delayed(const Duration(seconds: 1)); } on Exception catch (e, s) { _log.severe('Loop body exception', e, s); } on Error catch (e, s) { diff --git a/lib/src/entities/internal/entities/chat_id.dart b/lib/src/entities/internal/entities/chat_id.dart index 33e466d..e70184f 100644 --- a/lib/src/entities/internal/entities/chat_id.dart +++ b/lib/src/entities/internal/entities/chat_id.dart @@ -6,18 +6,16 @@ class ChatID { /// Telegram ChatUsername String? chatUsername; - ChatID._internal({this.chatUsername}); - /// ChatId constructor ChatID(this.chatId); + ChatID._internal({this.chatUsername}); + /// Username constructor factory ChatID.fromUsername(String username) { return ChatID._internal(chatUsername: username); } @override - String toString() { - return (chatId ?? chatUsername)!.toString(); - } + String toString() => (chatId ?? chatUsername)!.toString(); } diff --git a/lib/src/entities/internal/helpers/bot_command_parser.dart b/lib/src/entities/internal/helpers/bot_command_parser.dart index 53cc318..1cfc283 100644 --- a/lib/src/entities/internal/helpers/bot_command_parser.dart +++ b/lib/src/entities/internal/helpers/bot_command_parser.dart @@ -33,6 +33,7 @@ class BotCommandParser { return false; } } + return command.toLowerCase() == this.command.toLowerCase(); } @@ -44,7 +45,6 @@ class BotCommandParser { var command = match.group(1)!; var username = match.group(2); var foundArgs = match.group(3); - if (foundArgs != null) { return BotCommandParser(command, username, args: foundArgs.split(' ')); } diff --git a/lib/src/entities/internal/tgapi_client.dart b/lib/src/entities/internal/tgapi_client.dart index 361c7c5..5f61287 100644 --- a/lib/src/entities/internal/tgapi_client.dart +++ b/lib/src/entities/internal/tgapi_client.dart @@ -81,7 +81,7 @@ class TGAPIClient { ); var response = await _client .send(_getRequest(uri, files)) - .timeout(Duration(seconds: 120)); + .timeout(const Duration(seconds: 120)); var stringResponse = await response.stream.bytesToString(); return json.decode(stringResponse); } @@ -89,8 +89,9 @@ class TGAPIClient { /// Download a file from path Future apiDownload(String? token, String? path) async { var uri = Uri.https(baseUrl, '/file/bot$token/$path'); - var response = - await _client.send(Request('GET', uri)).timeout(Duration(seconds: 120)); + var response = await _client.send(Request('GET', uri)).timeout( + const Duration(seconds: 120), + ); if (response.statusCode != 200) { throw APIException( 'Error while downloading the file with path /$path', @@ -110,9 +111,9 @@ class TGAPIClient { ]) async { var files = {}; if (query != null) { - final updatedQuery = {}; + var updatedQuery = {}; - for (final param in query.entries) { + for (var param in query.entries) { if (param.value == null) continue; switch (param.value.runtimeType) { diff --git a/lib/src/entities/internal/tgapi_methods.dart b/lib/src/entities/internal/tgapi_methods.dart index f891406..0e26c16 100644 --- a/lib/src/entities/internal/tgapi_methods.dart +++ b/lib/src/entities/internal/tgapi_methods.dart @@ -1253,8 +1253,8 @@ mixin TGAPIMethods { /// Use this method to get a list of administrators in a chat. /// - /// On success, returns an Array of [ChatMember] objects that contains information - /// about all chat administrators except other bots. + /// On success, returns an Array of [ChatMember] objects that contains + /// information about all chat administrators except other bots. /// /// If the chat is a group or a supergroup and no administrators were /// appointed, only the creator will be returned. @@ -1457,8 +1457,8 @@ mixin TGAPIMethods { } /// Use this method to hide the 'General' topic in a forum supergroup chat. - /// The bot must be an administrator in the chat for this to work and must have - /// the can_manage_topics administrator rights. + /// The bot must be an administrator in the chat for this to work and must + /// have the can_manage_topics administrator rights. /// The topic will be automatically closed if it was open. /// Returns True on success. Future hideGeneralForumTopic(ChatID chatId) { @@ -1468,8 +1468,8 @@ mixin TGAPIMethods { } /// Use this method to unhide the 'General' topic in a forum supergroup chat. - /// The bot must be an administrator in the chat for this to work and must have - /// the can_manage_topics administrator rights. + /// The bot must be an administrator in the chat for this to work and must + /// have the can_manage_topics administrator rights. /// Returns True on success. Future unhideGeneralForumTopic(ChatID chatId) { return _client.apiCall(_token, 'unhideGeneralForumTopic', { diff --git a/lib/src/entities/telegram/animation.dart b/lib/src/entities/telegram/animation.dart index 02d7e5f..c1ba202 100644 --- a/lib/src/entities/telegram/animation.dart +++ b/lib/src/entities/telegram/animation.dart @@ -56,7 +56,7 @@ class Animation { }); /// Creates a object from a json - static Animation fromJson(Map json) { + factory Animation.fromJson(Map json) { return Animation( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/audio.dart b/lib/src/entities/telegram/audio.dart index a9a4631..76d7f60 100644 --- a/lib/src/entities/telegram/audio.dart +++ b/lib/src/entities/telegram/audio.dart @@ -58,7 +58,7 @@ class Audio { }); /// Creates a object from a json - static Audio fromJson(Map json) { + factory Audio.fromJson(Map json) { return Audio( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/bot_command.dart b/lib/src/entities/telegram/bot_command.dart index 6615a37..45c340f 100644 --- a/lib/src/entities/telegram/bot_command.dart +++ b/lib/src/entities/telegram/bot_command.dart @@ -16,10 +16,10 @@ class BotCommand { }); /// Creates a object from a json - static BotCommand fromJson(Map json) { + factory BotCommand.fromJson(Map json) { return BotCommand( command: json['command']!, - description: json['description']!, + description: json['description'], ); } diff --git a/lib/src/entities/telegram/bot_command_scope.dart b/lib/src/entities/telegram/bot_command_scope.dart index 493e74a..dc4cbc8 100644 --- a/lib/src/entities/telegram/bot_command_scope.dart +++ b/lib/src/entities/telegram/bot_command_scope.dart @@ -1,4 +1,5 @@ -/// This object represents the scope to which bot commands are applied. Currently, the following 7 scopes are supported: +/// This object represents the scope to which bot commands are applied. +/// Currently, the following 7 scopes are supported: /// BotCommandScopeDefault, /// BotCommandScopeAllPrivateChats, /// BotCommandScopeAllGroupChats, diff --git a/lib/src/entities/telegram/bot_description.dart b/lib/src/entities/telegram/bot_description.dart index 4d7cb30..e48f117 100644 --- a/lib/src/entities/telegram/bot_description.dart +++ b/lib/src/entities/telegram/bot_description.dart @@ -11,7 +11,7 @@ class BotDescription { }); /// Creates a object from a json - static BotDescription fromJson(Map json) { + factory BotDescription.fromJson(Map json) { return BotDescription( description: json['description'], ); diff --git a/lib/src/entities/telegram/bot_name.dart b/lib/src/entities/telegram/bot_name.dart index c1f80ce..abef93c 100644 --- a/lib/src/entities/telegram/bot_name.dart +++ b/lib/src/entities/telegram/bot_name.dart @@ -11,7 +11,7 @@ class BotName { }); /// Creates a object from a json - static BotName fromJson(Map json) { + factory BotName.fromJson(Map json) { return BotName( name: json['name'], ); diff --git a/lib/src/entities/telegram/bot_short_description.dart b/lib/src/entities/telegram/bot_short_description.dart index 038e8cb..fd587f4 100644 --- a/lib/src/entities/telegram/bot_short_description.dart +++ b/lib/src/entities/telegram/bot_short_description.dart @@ -11,7 +11,7 @@ class BotShortDescription { }); /// Creates a object from a json - static BotShortDescription fromJson(Map json) { + factory BotShortDescription.fromJson(Map json) { return BotShortDescription( shortDescription: json['short_description'], ); diff --git a/lib/src/entities/telegram/callback_game.dart b/lib/src/entities/telegram/callback_game.dart index d7dd2b4..e4d42a9 100644 --- a/lib/src/entities/telegram/callback_game.dart +++ b/lib/src/entities/telegram/callback_game.dart @@ -5,7 +5,7 @@ class CallbackGame { CallbackGame(); /// Creates a object from a json - static CallbackGame fromJson(Map json) { + factory CallbackGame.fromJson(Map _) { return CallbackGame(); } diff --git a/lib/src/entities/telegram/callback_query.dart b/lib/src/entities/telegram/callback_query.dart index 973746a..f29d418 100644 --- a/lib/src/entities/telegram/callback_query.dart +++ b/lib/src/entities/telegram/callback_query.dart @@ -54,7 +54,7 @@ class CallbackQuery { }); /// Creates a object from a json - static CallbackQuery fromJson(Map json) { + factory CallbackQuery.fromJson(Map json) { return CallbackQuery( id: json['id']!, from: User.fromJson(json['from']!), diff --git a/lib/src/entities/telegram/chat.dart b/lib/src/entities/telegram/chat.dart index 91e7395..650c5d5 100644 --- a/lib/src/entities/telegram/chat.dart +++ b/lib/src/entities/telegram/chat.dart @@ -193,7 +193,7 @@ class Chat { }); /// Creates a object from a json - static Chat fromJson(Map json) { + factory Chat.fromJson(Map json) { return Chat( id: json['id']!, type: json['type']!, diff --git a/lib/src/entities/telegram/chat_administrator_rights.dart b/lib/src/entities/telegram/chat_administrator_rights.dart index 87f155c..0309109 100644 --- a/lib/src/entities/telegram/chat_administrator_rights.dart +++ b/lib/src/entities/telegram/chat_administrator_rights.dart @@ -83,7 +83,7 @@ class ChatAdministratorRights { ); /// Creates a object from a json - static ChatAdministratorRights fromJson(Map json) { + factory ChatAdministratorRights.fromJson(Map json) { return ChatAdministratorRights( json['is_anonymous'], json['can_manage_chat'], diff --git a/lib/src/entities/telegram/chat_invite_link.dart b/lib/src/entities/telegram/chat_invite_link.dart index a197b0b..742acef 100644 --- a/lib/src/entities/telegram/chat_invite_link.dart +++ b/lib/src/entities/telegram/chat_invite_link.dart @@ -54,7 +54,7 @@ class ChatInviteLink { }); /// Creates a object from a json - static ChatInviteLink fromJson(Map json) { + factory ChatInviteLink.fromJson(Map json) { return ChatInviteLink( inviteLink: json['invite_link']!, creator: User.fromJson(json['creator']!), diff --git a/lib/src/entities/telegram/chat_join_request.dart b/lib/src/entities/telegram/chat_join_request.dart index 8564cee..06bf6c7 100644 --- a/lib/src/entities/telegram/chat_join_request.dart +++ b/lib/src/entities/telegram/chat_join_request.dart @@ -43,7 +43,7 @@ class ChatJoinRequest { }); /// Creates a object from a json - static ChatJoinRequest fromJson(Map json) { + factory ChatJoinRequest.fromJson(Map json) { return ChatJoinRequest( chat: Chat.fromJson(json['chat']!), from: User.fromJson(json['from']!), diff --git a/lib/src/entities/telegram/chat_location.dart b/lib/src/entities/telegram/chat_location.dart index e785eec..b449031 100644 --- a/lib/src/entities/telegram/chat_location.dart +++ b/lib/src/entities/telegram/chat_location.dart @@ -18,7 +18,7 @@ class ChatLocation { }); /// Creates a object from a json - static ChatLocation fromJson(Map json) { + factory ChatLocation.fromJson(Map json) { return ChatLocation( location: Location.fromJson(json['location']!), address: json['address']!, diff --git a/lib/src/entities/telegram/chat_member.dart b/lib/src/entities/telegram/chat_member.dart index 790584e..0aef416 100644 --- a/lib/src/entities/telegram/chat_member.dart +++ b/lib/src/entities/telegram/chat_member.dart @@ -160,7 +160,7 @@ class ChatMember { }); /// Creates a object from a json - static ChatMember fromJson(Map json) { + factory ChatMember.fromJson(Map json) { var isAdmin = json['status'] == 'administrator'; var isCreator = json['status'] == 'creator'; var isMember = json['status'] == 'member'; diff --git a/lib/src/entities/telegram/chat_member_updated.dart b/lib/src/entities/telegram/chat_member_updated.dart index d0c0529..3fcfb6c 100644 --- a/lib/src/entities/telegram/chat_member_updated.dart +++ b/lib/src/entities/telegram/chat_member_updated.dart @@ -41,7 +41,7 @@ class ChatMemberUpdated { }); /// Creates a object from a json - static ChatMemberUpdated fromJson(Map json) { + factory ChatMemberUpdated.fromJson(Map json) { return ChatMemberUpdated( chat: Chat.fromJson(json['chat']!), from: User.fromJson(json['from']!), diff --git a/lib/src/entities/telegram/chat_permissions.dart b/lib/src/entities/telegram/chat_permissions.dart index 6f435f3..d119b65 100644 --- a/lib/src/entities/telegram/chat_permissions.dart +++ b/lib/src/entities/telegram/chat_permissions.dart @@ -42,7 +42,8 @@ class ChatPermissions { /// Optional. /// True, if the user is allowed to change the chat title, photo and other - /// settings. Ignored in public supergroups + /// settings. + /// Ignored in public supergroups bool? canChangeInfo; /// Optional. @@ -50,7 +51,8 @@ class ChatPermissions { bool? canInviteUsers; /// Optional. - /// True, if the user is allowed to pin messages. Ignored in public supergroups + /// True, if the user is allowed to pin messages. + /// Ignored in public supergroups bool? canPinMessages; /// Optional. @@ -77,7 +79,7 @@ class ChatPermissions { }); /// Creates a object from a json - static ChatPermissions fromJson(Map json) { + factory ChatPermissions.fromJson(Map json) { return ChatPermissions( canSendMessages: json['can_send_messages'], canSendAudios: json['can_send_audios'], diff --git a/lib/src/entities/telegram/chat_photo.dart b/lib/src/entities/telegram/chat_photo.dart index d3364e5..7001484 100644 --- a/lib/src/entities/telegram/chat_photo.dart +++ b/lib/src/entities/telegram/chat_photo.dart @@ -8,8 +8,8 @@ class ChatPhoto { String smallFileId; /// Unique file identifier of small (160x160) chat photo, which is supposed - /// to be the same over time and for different bots. Can't be used to download - /// or reuse the file. + /// to be the same over time and for different bots. + /// Can't be used to download or reuse the file. String smallFileUniqueId; /// File identifier of big (640x640) chat photo. @@ -31,7 +31,7 @@ class ChatPhoto { }); /// Creates a object from a json - static ChatPhoto fromJson(Map json) { + factory ChatPhoto.fromJson(Map json) { return ChatPhoto( smallFileId: json['small_file_id']!, smallFileUniqueId: json['small_file_unique_id']!, diff --git a/lib/src/entities/telegram/chat_shared.dart b/lib/src/entities/telegram/chat_shared.dart index b477f03..b10aa7e 100644 --- a/lib/src/entities/telegram/chat_shared.dart +++ b/lib/src/entities/telegram/chat_shared.dart @@ -23,7 +23,7 @@ class ChatShared { ); /// Creates a object from a json - static ChatShared fromJson(Map json) { + factory ChatShared.fromJson(Map json) { return ChatShared( json['request_id'], json['user_id'], diff --git a/lib/src/entities/telegram/chosen_inline_result.dart b/lib/src/entities/telegram/chosen_inline_result.dart index aa1e32b..ed09c06 100644 --- a/lib/src/entities/telegram/chosen_inline_result.dart +++ b/lib/src/entities/telegram/chosen_inline_result.dart @@ -36,7 +36,7 @@ class ChosenInlineResult { }); /// Creates a object from a json - static ChosenInlineResult fromJson(Map json) { + factory ChosenInlineResult.fromJson(Map json) { return ChosenInlineResult( resultId: json['result_id']!, from: User.fromJson(json['from']!), diff --git a/lib/src/entities/telegram/contact.dart b/lib/src/entities/telegram/contact.dart index ae4cddf..5535ddd 100644 --- a/lib/src/entities/telegram/contact.dart +++ b/lib/src/entities/telegram/contact.dart @@ -34,7 +34,7 @@ class Contact { }); /// Creates a object from a json - static Contact fromJson(Map json) { + factory Contact.fromJson(Map json) { return Contact( phoneNumber: json['phone_number']!, firstName: json['first_name']!, diff --git a/lib/src/entities/telegram/dice.dart b/lib/src/entities/telegram/dice.dart index 3188d78..a7e9b39 100644 --- a/lib/src/entities/telegram/dice.dart +++ b/lib/src/entities/telegram/dice.dart @@ -18,7 +18,7 @@ class Dice { }); /// Creates a object from a json - static Dice fromJson(Map json) { + factory Dice.fromJson(Map json) { return Dice( emoji: Emoji.forValue(json['emoji']), value: json['value'], diff --git a/lib/src/entities/telegram/document.dart b/lib/src/entities/telegram/document.dart index 2406609..f9879ad 100644 --- a/lib/src/entities/telegram/document.dart +++ b/lib/src/entities/telegram/document.dart @@ -44,7 +44,7 @@ class Document { }); /// Creates a object from a json - static Document fromJson(Map json) { + factory Document.fromJson(Map json) { return Document( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/encrypted_credentials.dart b/lib/src/entities/telegram/encrypted_credentials.dart index d86ed72..d793a78 100644 --- a/lib/src/entities/telegram/encrypted_credentials.dart +++ b/lib/src/entities/telegram/encrypted_credentials.dart @@ -25,7 +25,7 @@ class EncryptedCredentials { }); /// Creates a object from a json - static EncryptedCredentials fromJson(Map json) { + factory EncryptedCredentials.fromJson(Map json) { return EncryptedCredentials( data: json['data']!, hash: json['hash']!, diff --git a/lib/src/entities/telegram/encrypted_passport_element.dart b/lib/src/entities/telegram/encrypted_passport_element.dart index 598d54b..70d8004 100644 --- a/lib/src/entities/telegram/encrypted_passport_element.dart +++ b/lib/src/entities/telegram/encrypted_passport_element.dart @@ -88,7 +88,7 @@ class EncryptedPassportElement { }); /// Creates a object from a json - static EncryptedPassportElement fromJson(Map json) { + factory EncryptedPassportElement.fromJson(Map json) { return EncryptedPassportElement( type: json['type']!, data: json['data'], diff --git a/lib/src/entities/telegram/file.dart b/lib/src/entities/telegram/file.dart index f20336e..3461f6c 100644 --- a/lib/src/entities/telegram/file.dart +++ b/lib/src/entities/telegram/file.dart @@ -35,7 +35,7 @@ class File { }); /// Creates a object from a json - static File fromJson(Map json) { + factory File.fromJson(Map json) { return File( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/force_reply.dart b/lib/src/entities/telegram/force_reply.dart index 77c06ad..24cf3ba 100644 --- a/lib/src/entities/telegram/force_reply.dart +++ b/lib/src/entities/telegram/force_reply.dart @@ -32,7 +32,7 @@ class ForceReply extends ReplyMarkup { }); /// Creates a object from a json - static ForceReply fromJson(Map json) { + factory ForceReply.fromJson(Map json) { return ForceReply( forceReply: json['force_reply'], inputFieldPlaceholder: json['input_field_placeholder'], diff --git a/lib/src/entities/telegram/forum_topic.dart b/lib/src/entities/telegram/forum_topic.dart index 6faede8..1d2f16c 100644 --- a/lib/src/entities/telegram/forum_topic.dart +++ b/lib/src/entities/telegram/forum_topic.dart @@ -23,7 +23,7 @@ class ForumTopic { this.iconCustomEmojiId, ); - static ForumTopic fromJson(Map json) { + factory ForumTopic.fromJson(Map json) { return ForumTopic( json['message_thread_id'], json['name'], diff --git a/lib/src/entities/telegram/forum_topic_closed.dart b/lib/src/entities/telegram/forum_topic_closed.dart index 0d662b4..d1df5b6 100644 --- a/lib/src/entities/telegram/forum_topic_closed.dart +++ b/lib/src/entities/telegram/forum_topic_closed.dart @@ -8,7 +8,7 @@ class ForumTopicClosed { ForumTopicClosed(); /// Creates a object from a json - static ForumTopicClosed fromJson(Map json) { + factory ForumTopicClosed.fromJson(Map _) { return ForumTopicClosed(); } diff --git a/lib/src/entities/telegram/forum_topic_created.dart b/lib/src/entities/telegram/forum_topic_created.dart index e00358e..b1fdb57 100644 --- a/lib/src/entities/telegram/forum_topic_created.dart +++ b/lib/src/entities/telegram/forum_topic_created.dart @@ -21,7 +21,7 @@ class ForumTopicCreated { }); /// Creates a object from a json - static ForumTopicCreated fromJson(Map json) { + factory ForumTopicCreated.fromJson(Map json) { return ForumTopicCreated( name: json['name'], iconColor: json['icon_color'], diff --git a/lib/src/entities/telegram/forum_topic_edited.dart b/lib/src/entities/telegram/forum_topic_edited.dart index c011392..3f64cc0 100644 --- a/lib/src/entities/telegram/forum_topic_edited.dart +++ b/lib/src/entities/telegram/forum_topic_edited.dart @@ -18,7 +18,7 @@ class ForumTopicEdited { }); /// Creates a object from a json - static ForumTopicEdited fromJson(Map json) { + factory ForumTopicEdited.fromJson(Map json) { return ForumTopicEdited( name: json['name'], iconCustomEmojiId: json['icon_custom_emoji_id'], diff --git a/lib/src/entities/telegram/forum_topic_reopened.dart b/lib/src/entities/telegram/forum_topic_reopened.dart index 3873a61..cae5dea 100644 --- a/lib/src/entities/telegram/forum_topic_reopened.dart +++ b/lib/src/entities/telegram/forum_topic_reopened.dart @@ -8,7 +8,7 @@ class ForumTopicReopened { ForumTopicReopened(); /// Creates a object from a json - static ForumTopicReopened fromJson(Map json) { + factory ForumTopicReopened.fromJson(Map _) { return ForumTopicReopened(); } diff --git a/lib/src/entities/telegram/game.dart b/lib/src/entities/telegram/game.dart index 2bc8d21..c82ac43 100644 --- a/lib/src/entities/telegram/game.dart +++ b/lib/src/entities/telegram/game.dart @@ -44,7 +44,7 @@ class Game { }); /// Creates a object from a json - static Game fromJson(Map json) { + factory Game.fromJson(Map json) { return Game( title: json['title']!, description: json['description']!, diff --git a/lib/src/entities/telegram/game_high_score.dart b/lib/src/entities/telegram/game_high_score.dart index bb3eacc..a76c99d 100644 --- a/lib/src/entities/telegram/game_high_score.dart +++ b/lib/src/entities/telegram/game_high_score.dart @@ -21,7 +21,7 @@ class GameHighScore { }); /// Creates a object from a json - static GameHighScore fromJson(Map json) { + factory GameHighScore.fromJson(Map json) { return GameHighScore( position: json['position']!, user: User.fromJson(json['user']!), diff --git a/lib/src/entities/telegram/general_forum_topic_hidden.dart b/lib/src/entities/telegram/general_forum_topic_hidden.dart index 69ddf55..cb8f756 100644 --- a/lib/src/entities/telegram/general_forum_topic_hidden.dart +++ b/lib/src/entities/telegram/general_forum_topic_hidden.dart @@ -8,7 +8,7 @@ class GeneralForumTopicHidden { GeneralForumTopicHidden(); /// Creates a object from a json - static GeneralForumTopicHidden fromJson(Map json) { + factory GeneralForumTopicHidden.fromJson(Map _) { return GeneralForumTopicHidden(); } diff --git a/lib/src/entities/telegram/general_forum_topic_unhidden.dart b/lib/src/entities/telegram/general_forum_topic_unhidden.dart index ed74211..c030b0d 100644 --- a/lib/src/entities/telegram/general_forum_topic_unhidden.dart +++ b/lib/src/entities/telegram/general_forum_topic_unhidden.dart @@ -8,7 +8,7 @@ class GeneralForumTopicUnhidden { GeneralForumTopicUnhidden(); /// Creates a object from a json - static GeneralForumTopicUnhidden fromJson(Map json) { + factory GeneralForumTopicUnhidden.fromJson(Map _) { return GeneralForumTopicUnhidden(); } diff --git a/lib/src/entities/telegram/giveaway.dart b/lib/src/entities/telegram/giveaway.dart index 478c1d5..8bd9064 100644 --- a/lib/src/entities/telegram/giveaway.dart +++ b/lib/src/entities/telegram/giveaway.dart @@ -53,7 +53,7 @@ class Giveaway { }); /// Creates a object from a json - static Giveaway fromJson(Map json) { + factory Giveaway.fromJson(Map json) { return Giveaway( chats: json['chats'], winnersSelectionDate: json['winners_selection_date'], diff --git a/lib/src/entities/telegram/giveaway_completed.dart b/lib/src/entities/telegram/giveaway_completed.dart index 2a7b0bf..eac94f4 100644 --- a/lib/src/entities/telegram/giveaway_completed.dart +++ b/lib/src/entities/telegram/giveaway_completed.dart @@ -23,7 +23,7 @@ class GiveawayCompleted { }); /// Creates a object from a json - static GiveawayCompleted fromJson(Map json) { + factory GiveawayCompleted.fromJson(Map json) { return GiveawayCompleted( winnerCount: json['winner_count'], unclaimedPrizeCount: json['unclaimed_prize_count'], diff --git a/lib/src/entities/telegram/giveaway_created.dart b/lib/src/entities/telegram/giveaway_created.dart index 12911f1..1dd7f33 100644 --- a/lib/src/entities/telegram/giveaway_created.dart +++ b/lib/src/entities/telegram/giveaway_created.dart @@ -8,7 +8,7 @@ class GiveawayCreated { GiveawayCreated(); /// Creates a object from json - static GiveawayCreated fromJson(Map json) { + factory GiveawayCreated.fromJson(Map json) { return GiveawayCreated(); } diff --git a/lib/src/entities/telegram/giveaway_winners.dart b/lib/src/entities/telegram/giveaway_winners.dart index 192e070..cd00a84 100644 --- a/lib/src/entities/telegram/giveaway_winners.dart +++ b/lib/src/entities/telegram/giveaway_winners.dart @@ -63,7 +63,7 @@ class GiveawayWinners { }); /// Creates a object from a json - static GiveawayWinners fromJson(Map json) { + factory GiveawayWinners.fromJson(Map json) { return GiveawayWinners( chat: Chat.fromJson(json['chat']), giveawayMessageId: json['giveaway_message_id'], diff --git a/lib/src/entities/telegram/inline_keyboard_button.dart b/lib/src/entities/telegram/inline_keyboard_button.dart index 444a544..ea32270 100644 --- a/lib/src/entities/telegram/inline_keyboard_button.dart +++ b/lib/src/entities/telegram/inline_keyboard_button.dart @@ -107,7 +107,7 @@ class InlineKeyboardButton { InlineKeyboardButton.pay(this.text, {this.pay}); /// Creates a object from a json - static InlineKeyboardButton fromJson(Map json) { + factory InlineKeyboardButton.fromJson(Map json) { return InlineKeyboardButton._( json['text']!, url: json['url'], @@ -132,7 +132,8 @@ class InlineKeyboardButton { /// Creates a list of list of object from a json array static List> listOfListsFromJsonArray( - List json) { + List json, + ) { return List.generate( json.length, (e) => List.generate( diff --git a/lib/src/entities/telegram/inline_keyboard_markup.dart b/lib/src/entities/telegram/inline_keyboard_markup.dart index 24cb7fa..182e3b9 100644 --- a/lib/src/entities/telegram/inline_keyboard_markup.dart +++ b/lib/src/entities/telegram/inline_keyboard_markup.dart @@ -13,7 +13,7 @@ class InlineKeyboardMarkup extends ReplyMarkup { InlineKeyboardMarkup(this.inlineKeyboard); /// Creates a object from a json - static InlineKeyboardMarkup fromJson(Map json) { + factory InlineKeyboardMarkup.fromJson(Map json) { return InlineKeyboardMarkup( InlineKeyboardButton.listOfListsFromJsonArray(json['inline_keyboard']), ); diff --git a/lib/src/entities/telegram/inline_query.dart b/lib/src/entities/telegram/inline_query.dart index bdf11cb..0502225 100644 --- a/lib/src/entities/telegram/inline_query.dart +++ b/lib/src/entities/telegram/inline_query.dart @@ -43,7 +43,7 @@ class InlineQuery { }); /// Creates a object from a json - static InlineQuery fromJson(Map json) { + factory InlineQuery.fromJson(Map json) { return InlineQuery( id: json['id']!, from: User.fromJson(json['from']!), diff --git a/lib/src/entities/telegram/inline_query_result.dart b/lib/src/entities/telegram/inline_query_result.dart index 73ad127..e13fad5 100644 --- a/lib/src/entities/telegram/inline_query_result.dart +++ b/lib/src/entities/telegram/inline_query_result.dart @@ -1,4 +1,5 @@ -/// This object represents one result of an inline query. Telegram clients currently support results of the following 20 types: +/// This object represents one result of an inline query. +/// Telegram clients currently support results of the following 20 types: /// InlineQueryResultCachedAudio, /// InlineQueryResultCachedDocument, /// InlineQueryResultCachedGif, diff --git a/lib/src/entities/telegram/inline_query_results_button.dart b/lib/src/entities/telegram/inline_query_results_button.dart index e67d42d..86ba677 100644 --- a/lib/src/entities/telegram/inline_query_results_button.dart +++ b/lib/src/entities/telegram/inline_query_results_button.dart @@ -30,7 +30,7 @@ class InlineQueryResultsButton { }); /// Creates a object from a json - static InlineQueryResultsButton fromJson(Map json) { + factory InlineQueryResultsButton.fromJson(Map json) { return InlineQueryResultsButton( text: json['text']!, webApp: callIfNotNull(WebAppInfo.fromJson, json['web_app']), diff --git a/lib/src/entities/telegram/input_contact_message_content.dart b/lib/src/entities/telegram/input_contact_message_content.dart index b71d290..04e567a 100644 --- a/lib/src/entities/telegram/input_contact_message_content.dart +++ b/lib/src/entities/telegram/input_contact_message_content.dart @@ -2,7 +2,8 @@ import 'dart:convert'; import '../../../telegram_entities.dart'; -/// Represents the content of a contact message to be sent as the result of an inline query. +/// Represents the content of a contact message to be sent as the result of an +/// inline query. class InputContactMessageContent extends InputMessageContent { /// Contact's phone number String phoneNumber; @@ -27,7 +28,7 @@ class InputContactMessageContent extends InputMessageContent { }); /// Creates a object from a json - static InputContactMessageContent fromJson(Map json) { + factory InputContactMessageContent.fromJson(Map json) { return InputContactMessageContent( json['phone_number']!, json['first_name']!, diff --git a/lib/src/entities/telegram/input_location_message_content.dart b/lib/src/entities/telegram/input_location_message_content.dart index c91c12f..8264ad3 100644 --- a/lib/src/entities/telegram/input_location_message_content.dart +++ b/lib/src/entities/telegram/input_location_message_content.dart @@ -42,7 +42,7 @@ class InputLocationMessageContent extends InputMessageContent { }); /// Creates a object from a json - static InputLocationMessageContent fromJson(Map json) { + factory InputLocationMessageContent.fromJson(Map json) { return InputLocationMessageContent( json['latitude']!, json['longitude']!, diff --git a/lib/src/entities/telegram/input_sticker.dart b/lib/src/entities/telegram/input_sticker.dart index 0fd2912..e574548 100644 --- a/lib/src/entities/telegram/input_sticker.dart +++ b/lib/src/entities/telegram/input_sticker.dart @@ -35,12 +35,12 @@ class InputSticker { }); /// Creates a object from a json - static InputSticker fromJson(Map json) { + factory InputSticker.fromJson(Map json) { return InputSticker( sticker: json['sticker']!, emojiList: json['emoji_list']!, - maskPosition: json['mask_position']!, - keywords: json['keywords']!, + maskPosition: json['mask_position'], + keywords: json['keywords'], ); } diff --git a/lib/src/entities/telegram/input_text_message_content.dart b/lib/src/entities/telegram/input_text_message_content.dart index 7f767b7..fd15f88 100644 --- a/lib/src/entities/telegram/input_text_message_content.dart +++ b/lib/src/entities/telegram/input_text_message_content.dart @@ -31,7 +31,7 @@ class InputTextMessageContent extends InputMessageContent { }); /// Creates a object from a json - static InputTextMessageContent fromJson(Map json) { + factory InputTextMessageContent.fromJson(Map json) { return InputTextMessageContent( json['message_text']!, parseMode: callIfNotNull(ParseMode.forValue, json['parse_mode']), diff --git a/lib/src/entities/telegram/input_venue_message_content.dart b/lib/src/entities/telegram/input_venue_message_content.dart index c7f2898..506e795 100644 --- a/lib/src/entities/telegram/input_venue_message_content.dart +++ b/lib/src/entities/telegram/input_venue_message_content.dart @@ -48,7 +48,7 @@ class InputVenueMessageContent extends InputMessageContent { }); /// Creates a object from a json - static InputVenueMessageContent fromJson(Map json) { + factory InputVenueMessageContent.fromJson(Map json) { return InputVenueMessageContent( json['latitude']!, json['longitude']!, diff --git a/lib/src/entities/telegram/invoice.dart b/lib/src/entities/telegram/invoice.dart index d1231a0..b5271de 100644 --- a/lib/src/entities/telegram/invoice.dart +++ b/lib/src/entities/telegram/invoice.dart @@ -33,7 +33,7 @@ class Invoice { }); /// Creates a object from a json - static Invoice fromJson(Map json) { + factory Invoice.fromJson(Map json) { return Invoice( title: json['title']!, description: json['description']!, diff --git a/lib/src/entities/telegram/keyboard_button.dart b/lib/src/entities/telegram/keyboard_button.dart index 21edb47..b0f1b2d 100644 --- a/lib/src/entities/telegram/keyboard_button.dart +++ b/lib/src/entities/telegram/keyboard_button.dart @@ -80,7 +80,7 @@ class KeyboardButton { KeyboardButton.requestWebApp(this.text, this.webApp); /// Creates a object from a json - static KeyboardButton fromJson(Map json) { + factory KeyboardButton.fromJson(Map json) { return KeyboardButton._( text: json['text']!, requestUser: callIfNotNull( @@ -114,7 +114,8 @@ class KeyboardButton { /// Creates a list of list of object from a json array static List> listOfListsFromJsonArray( - List> json) { + List> json, + ) { return List.generate( json.length, (e) => List.generate( diff --git a/lib/src/entities/telegram/keyboard_button_poll_type.dart b/lib/src/entities/telegram/keyboard_button_poll_type.dart index d0e70f5..60827ae 100644 --- a/lib/src/entities/telegram/keyboard_button_poll_type.dart +++ b/lib/src/entities/telegram/keyboard_button_poll_type.dart @@ -16,7 +16,7 @@ class KeyboardButtonPollType { KeyboardButtonPollType({this.type}); /// Creates a object from a json - static KeyboardButtonPollType fromJson(Map json) { + factory KeyboardButtonPollType.fromJson(Map json) { return KeyboardButtonPollType( type: callIfNotNull(PollType.forValue, json['type']), ); diff --git a/lib/src/entities/telegram/keyboard_button_request_chat.dart b/lib/src/entities/telegram/keyboard_button_request_chat.dart index 754655a..66755e7 100644 --- a/lib/src/entities/telegram/keyboard_button_request_chat.dart +++ b/lib/src/entities/telegram/keyboard_button_request_chat.dart @@ -64,7 +64,7 @@ class KeyboardButtonRequestChat { }); /// Creates a object from a json - static KeyboardButtonRequestChat fromJson(Map json) { + factory KeyboardButtonRequestChat.fromJson(Map json) { return KeyboardButtonRequestChat( json['request_id'], json['chat_is_channel'], diff --git a/lib/src/entities/telegram/keyboard_button_request_user.dart b/lib/src/entities/telegram/keyboard_button_request_user.dart index e39a238..3941a16 100644 --- a/lib/src/entities/telegram/keyboard_button_request_user.dart +++ b/lib/src/entities/telegram/keyboard_button_request_user.dart @@ -27,7 +27,7 @@ class KeyboardButtonRequestUser { }); /// Creates a object from a json - static KeyboardButtonRequestUser fromJson(Map json) { + factory KeyboardButtonRequestUser.fromJson(Map json) { return KeyboardButtonRequestUser( json['request_id'], userIsBot: json['user_is_bot'], diff --git a/lib/src/entities/telegram/labeled_price.dart b/lib/src/entities/telegram/labeled_price.dart index 12bb826..d4a6a21 100644 --- a/lib/src/entities/telegram/labeled_price.dart +++ b/lib/src/entities/telegram/labeled_price.dart @@ -20,7 +20,7 @@ class LabeledPrice { }); /// Creates a object from a json - static LabeledPrice fromJson(Map json) { + factory LabeledPrice.fromJson(Map json) { return LabeledPrice( label: json['label']!, amount: json['amount']!, diff --git a/lib/src/entities/telegram/link_preview_options.dart b/lib/src/entities/telegram/link_preview_options.dart index 2dfbf36..8e6a6c5 100644 --- a/lib/src/entities/telegram/link_preview_options.dart +++ b/lib/src/entities/telegram/link_preview_options.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + /// Describes the options used for link preview generation. class LinkPreviewOptions { /// Optional. @@ -36,7 +38,7 @@ class LinkPreviewOptions { }); /// Creates a object from a json - static LinkPreviewOptions fromJson(Map json) { + factory LinkPreviewOptions.fromJson(Map json) { return LinkPreviewOptions( isDisabled: json['is_disabled'], url: json['url'], @@ -55,4 +57,7 @@ class LinkPreviewOptions { 'show_above_text': showAboveText, }..removeWhere((_, v) => v == null); } + + @override + String toString() => json.encode(this); } diff --git a/lib/src/entities/telegram/location.dart b/lib/src/entities/telegram/location.dart index d7fc670..c5ab38c 100644 --- a/lib/src/entities/telegram/location.dart +++ b/lib/src/entities/telegram/location.dart @@ -37,7 +37,7 @@ class Location { }); /// Creates a object from a json - static Location fromJson(Map json) { + factory Location.fromJson(Map json) { return Location( longitude: json['longitude']!, latitude: json['latitude']!, diff --git a/lib/src/entities/telegram/login_url.dart b/lib/src/entities/telegram/login_url.dart index 344bf58..f30ee2c 100644 --- a/lib/src/entities/telegram/login_url.dart +++ b/lib/src/entities/telegram/login_url.dart @@ -39,7 +39,7 @@ class LoginUrl { }); /// Creates a object from a json - static LoginUrl fromJson(Map json) { + factory LoginUrl.fromJson(Map json) { return LoginUrl( url: json['url']!, forwardText: json['forward_text'], diff --git a/lib/src/entities/telegram/mask_position.dart b/lib/src/entities/telegram/mask_position.dart index 8c1924b..8f19857 100644 --- a/lib/src/entities/telegram/mask_position.dart +++ b/lib/src/entities/telegram/mask_position.dart @@ -30,7 +30,7 @@ class MaskPosition { }); /// Creates a object from a json - static MaskPosition fromJson(Map json) { + factory MaskPosition.fromJson(Map json) { return MaskPosition( point: json['point']!, xShift: json['x_shift']!, diff --git a/lib/src/entities/telegram/menu_button_commands.dart b/lib/src/entities/telegram/menu_button_commands.dart index eb1dec7..f8369c1 100644 --- a/lib/src/entities/telegram/menu_button_commands.dart +++ b/lib/src/entities/telegram/menu_button_commands.dart @@ -3,7 +3,7 @@ import '../../../telegram_entities.dart'; /// Represents a menu button, which opens the bot's list of commands. class MenuButtonCommands extends MenuButton { /// Type of the button, must be commands - String type = "commands"; + String type = 'commands'; /// Creates a json from the object Map toJson() { diff --git a/lib/src/entities/telegram/menu_button_default.dart b/lib/src/entities/telegram/menu_button_default.dart index 44bcd17..a30f7b1 100644 --- a/lib/src/entities/telegram/menu_button_default.dart +++ b/lib/src/entities/telegram/menu_button_default.dart @@ -3,7 +3,7 @@ import '../../../telegram_entities.dart'; /// Describes that no specific value for the menu button was set. class MenuButtonDefault extends MenuButton { /// Type of the button, must be default - String type = "default"; + String type = 'default'; /// Creates a json from the object Map toJson() { diff --git a/lib/src/entities/telegram/menu_button_web_app.dart b/lib/src/entities/telegram/menu_button_web_app.dart index 902d507..e2c1b66 100644 --- a/lib/src/entities/telegram/menu_button_web_app.dart +++ b/lib/src/entities/telegram/menu_button_web_app.dart @@ -3,7 +3,7 @@ import '../../../telegram_entities.dart'; /// Represents a menu button, which launches a Web App. class MenuButtonWebApp extends MenuButton { /// Type of the button, must be web_app - String type = "web_app"; + String type = 'web_app'; /// Text on the button String text; @@ -20,7 +20,7 @@ class MenuButtonWebApp extends MenuButton { ); /// Creates a object from a json - static MenuButtonWebApp fromJson(Map json) { + factory MenuButtonWebApp.fromJson(Map json) { return MenuButtonWebApp( json['text'], json['web_app'], diff --git a/lib/src/entities/telegram/message.dart b/lib/src/entities/telegram/message.dart index 9879013..2feba83 100644 --- a/lib/src/entities/telegram/message.dart +++ b/lib/src/entities/telegram/message.dart @@ -438,7 +438,7 @@ class Message { }); /// Creates a object from a json - static Message fromJson(Map json) { + factory Message.fromJson(Map json) { return Message( messageId: json['message_id']!, messageThreadId: json['message_thread_id'], @@ -579,7 +579,7 @@ class Message { ), giveawayCompleted: callIfNotNull( GiveawayCompleted.fromJson, - json['giveaway_ccompleted'], + json['giveaway_completed'], ), videoChatScheduled: callIfNotNull( VideoChatScheduled.fromJson, diff --git a/lib/src/entities/telegram/message_auto_delete_timer_changed.dart b/lib/src/entities/telegram/message_auto_delete_timer_changed.dart index 0f446f6..0219267 100644 --- a/lib/src/entities/telegram/message_auto_delete_timer_changed.dart +++ b/lib/src/entities/telegram/message_auto_delete_timer_changed.dart @@ -10,7 +10,7 @@ class MessageAutoDeleteTimerChanged { MessageAutoDeleteTimerChanged(this.messageAutoDeleteTime); /// Creates a object from a json - static MessageAutoDeleteTimerChanged fromJson(Map json) { + factory MessageAutoDeleteTimerChanged.fromJson(Map json) { return MessageAutoDeleteTimerChanged(json['message_auto_delete_time']); } diff --git a/lib/src/entities/telegram/message_entity.dart b/lib/src/entities/telegram/message_entity.dart index edff78f..7f4380a 100644 --- a/lib/src/entities/telegram/message_entity.dart +++ b/lib/src/entities/telegram/message_entity.dart @@ -54,7 +54,7 @@ class MessageEntity { }); /// Creates a object from a json - static MessageEntity fromJson(Map json) { + factory MessageEntity.fromJson(Map json) { return MessageEntity( type: json['type']!, offset: json['offset']!, diff --git a/lib/src/entities/telegram/message_id.dart b/lib/src/entities/telegram/message_id.dart index 7d25ebf..2f203bf 100644 --- a/lib/src/entities/telegram/message_id.dart +++ b/lib/src/entities/telegram/message_id.dart @@ -9,7 +9,7 @@ class MessageId { MessageId({required this.messageId}); /// Creates a object from a json - static MessageId fromJson(Map json) { + factory MessageId.fromJson(Map json) { return MessageId(messageId: json['message_id']); } diff --git a/lib/src/entities/telegram/order_info.dart b/lib/src/entities/telegram/order_info.dart index 99fb4f7..669e49c 100644 --- a/lib/src/entities/telegram/order_info.dart +++ b/lib/src/entities/telegram/order_info.dart @@ -30,7 +30,7 @@ class OrderInfo { }); /// Creates a object from a json - static OrderInfo fromJson(Map json) { + factory OrderInfo.fromJson(Map json) { return OrderInfo( name: json['name'], phoneNumber: json['phone_number'], diff --git a/lib/src/entities/telegram/passport_data.dart b/lib/src/entities/telegram/passport_data.dart index 6aa5861..a29e48d 100644 --- a/lib/src/entities/telegram/passport_data.dart +++ b/lib/src/entities/telegram/passport_data.dart @@ -18,7 +18,7 @@ class PassportData { }); /// Creates a object from a json - static PassportData fromJson(Map json) { + factory PassportData.fromJson(Map json) { return PassportData( data: EncryptedPassportElement.listFromJsonArray(json['data']!), credentials: EncryptedCredentials.fromJson(json['credentials']!), diff --git a/lib/src/entities/telegram/passport_file.dart b/lib/src/entities/telegram/passport_file.dart index 49c0311..f3902bd 100644 --- a/lib/src/entities/telegram/passport_file.dart +++ b/lib/src/entities/telegram/passport_file.dart @@ -26,7 +26,7 @@ class PassportFile { }); /// Creates a object from a json - static PassportFile fromJson(Map json) { + factory PassportFile.fromJson(Map json) { return PassportFile( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/photo_size.dart b/lib/src/entities/telegram/photo_size.dart index ba5c15b..ab57cd1 100644 --- a/lib/src/entities/telegram/photo_size.dart +++ b/lib/src/entities/telegram/photo_size.dart @@ -30,7 +30,7 @@ class PhotoSize { }); /// Creates a object from a json - static PhotoSize fromJson(Map json) { + factory PhotoSize.fromJson(Map json) { return PhotoSize( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/poll.dart b/lib/src/entities/telegram/poll.dart index ccf2f43..15878d6 100644 --- a/lib/src/entities/telegram/poll.dart +++ b/lib/src/entities/telegram/poll.dart @@ -71,7 +71,7 @@ class Poll { }); /// Creates a object from a json - static Poll fromJson(Map json) { + factory Poll.fromJson(Map json) { return Poll( id: json['id']!, question: json['question']!, diff --git a/lib/src/entities/telegram/poll_answer.dart b/lib/src/entities/telegram/poll_answer.dart index 6def375..d1a8830 100644 --- a/lib/src/entities/telegram/poll_answer.dart +++ b/lib/src/entities/telegram/poll_answer.dart @@ -30,7 +30,7 @@ class PollAnswer { }); /// Creates a object from a json - static PollAnswer fromJson(Map json) { + factory PollAnswer.fromJson(Map json) { return PollAnswer( pollId: json['poll_id']!, voterChat: callIfNotNull(Chat.fromJson, json['voter_chat']), diff --git a/lib/src/entities/telegram/poll_option.dart b/lib/src/entities/telegram/poll_option.dart index 6eae3a5..3977a9d 100644 --- a/lib/src/entities/telegram/poll_option.dart +++ b/lib/src/entities/telegram/poll_option.dart @@ -15,7 +15,7 @@ class PollOption { }); /// Creates a object from a json - static PollOption fromJson(Map json) { + factory PollOption.fromJson(Map json) { return PollOption( text: json['text']!, voterCount: json['voter_count']!, diff --git a/lib/src/entities/telegram/pre_checkout_query.dart b/lib/src/entities/telegram/pre_checkout_query.dart index 8df8408..676ab47 100644 --- a/lib/src/entities/telegram/pre_checkout_query.dart +++ b/lib/src/entities/telegram/pre_checkout_query.dart @@ -45,7 +45,7 @@ class PreCheckoutQuery { }); /// Creates a object from a json - static PreCheckoutQuery fromJson(Map json) { + factory PreCheckoutQuery.fromJson(Map json) { return PreCheckoutQuery( id: json['id']!, from: User.fromJson(json['from']!), diff --git a/lib/src/entities/telegram/proximity_alert_triggered.dart b/lib/src/entities/telegram/proximity_alert_triggered.dart index a9f4b8f..b686502 100644 --- a/lib/src/entities/telegram/proximity_alert_triggered.dart +++ b/lib/src/entities/telegram/proximity_alert_triggered.dart @@ -22,7 +22,7 @@ class ProximityAlertTriggered { }); /// Creates a object from a json - static ProximityAlertTriggered fromJson(Map json) { + factory ProximityAlertTriggered.fromJson(Map json) { return ProximityAlertTriggered( traveler: User.fromJson(json['traveler']), watcher: User.fromJson(json['watcher']), diff --git a/lib/src/entities/telegram/reply_keyboard_markup.dart b/lib/src/entities/telegram/reply_keyboard_markup.dart index 40efbc1..c09575b 100644 --- a/lib/src/entities/telegram/reply_keyboard_markup.dart +++ b/lib/src/entities/telegram/reply_keyboard_markup.dart @@ -55,7 +55,7 @@ class ReplyKeyboardMarkup extends ReplyMarkup { }); /// Creates a object from a json - static ReplyKeyboardMarkup fromJson(Map json) { + factory ReplyKeyboardMarkup.fromJson(Map json) { return ReplyKeyboardMarkup( KeyboardButton.listOfListsFromJsonArray(json['keyboard']!), isPersistent: json['is_persistent'], diff --git a/lib/src/entities/telegram/reply_keyboard_remove.dart b/lib/src/entities/telegram/reply_keyboard_remove.dart index 9ad11f2..aa01a1e 100644 --- a/lib/src/entities/telegram/reply_keyboard_remove.dart +++ b/lib/src/entities/telegram/reply_keyboard_remove.dart @@ -31,7 +31,7 @@ class ReplyKeyboardRemove extends ReplyMarkup { }); /// Creates a object from a json - static ReplyKeyboardRemove fromJson(Map json) { + factory ReplyKeyboardRemove.fromJson(Map json) { return ReplyKeyboardRemove( removeKeyboard: json['remove_keyboard']!, selective: json['selective'], diff --git a/lib/src/entities/telegram/response_parameters.dart b/lib/src/entities/telegram/response_parameters.dart index 004e86e..535e3a1 100644 --- a/lib/src/entities/telegram/response_parameters.dart +++ b/lib/src/entities/telegram/response_parameters.dart @@ -22,7 +22,7 @@ class ResponseParameters { }); /// Creates a object from a json - static ResponseParameters fromJson(Map json) { + factory ResponseParameters.fromJson(Map json) { return ResponseParameters( migrateToChatId: json['migrate_to_chat_id'], retryAfter: json['retry_after'], diff --git a/lib/src/entities/telegram/sent_web_app_message.dart b/lib/src/entities/telegram/sent_web_app_message.dart index c0ad511..691fd08 100644 --- a/lib/src/entities/telegram/sent_web_app_message.dart +++ b/lib/src/entities/telegram/sent_web_app_message.dart @@ -11,7 +11,7 @@ class SentWebAppMessage { ); /// Creates a object from a json - static SentWebAppMessage fromJson(Map json) { + factory SentWebAppMessage.fromJson(Map json) { return SentWebAppMessage( json['inline_message_id'], ); diff --git a/lib/src/entities/telegram/shipping_address.dart b/lib/src/entities/telegram/shipping_address.dart index 2aaa165..6475f5a 100644 --- a/lib/src/entities/telegram/shipping_address.dart +++ b/lib/src/entities/telegram/shipping_address.dart @@ -31,7 +31,7 @@ class ShippingAddress { }); /// Creates a object from a json - static ShippingAddress fromJson(Map json) { + factory ShippingAddress.fromJson(Map json) { return ShippingAddress( countryCode: json['country_code']!, state: json['state']!, diff --git a/lib/src/entities/telegram/shipping_option.dart b/lib/src/entities/telegram/shipping_option.dart index 35eca09..9937e82 100644 --- a/lib/src/entities/telegram/shipping_option.dart +++ b/lib/src/entities/telegram/shipping_option.dart @@ -21,7 +21,7 @@ class ShippingOption { }); /// Creates a object from a json - static ShippingOption fromJson(Map json) { + factory ShippingOption.fromJson(Map json) { return ShippingOption( id: json['id']!, title: json['title']!, diff --git a/lib/src/entities/telegram/shipping_query.dart b/lib/src/entities/telegram/shipping_query.dart index 4b42e6d..170c3d7 100644 --- a/lib/src/entities/telegram/shipping_query.dart +++ b/lib/src/entities/telegram/shipping_query.dart @@ -25,7 +25,7 @@ class ShippingQuery { }); /// Creates a object from a json - static ShippingQuery fromJson(Map json) { + factory ShippingQuery.fromJson(Map json) { return ShippingQuery( id: json['id']!, from: User.fromJson(json['from']!), diff --git a/lib/src/entities/telegram/sticker.dart b/lib/src/entities/telegram/sticker.dart index fc7eb64..86a1b32 100644 --- a/lib/src/entities/telegram/sticker.dart +++ b/lib/src/entities/telegram/sticker.dart @@ -84,7 +84,7 @@ class Sticker { }); /// Creates a object from a json - static Sticker fromJson(Map json) { + factory Sticker.fromJson(Map json) { return Sticker( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/sticker_set.dart b/lib/src/entities/telegram/sticker_set.dart index f4bbad9..53f3664 100644 --- a/lib/src/entities/telegram/sticker_set.dart +++ b/lib/src/entities/telegram/sticker_set.dart @@ -40,7 +40,7 @@ class StickerSet { }); /// Creates a object from a json - static StickerSet fromJson(Map json) { + factory StickerSet.fromJson(Map json) { return StickerSet( name: json['name']!, title: json['title']!, diff --git a/lib/src/entities/telegram/story.dart b/lib/src/entities/telegram/story.dart index 6b73f1d..2b8248c 100644 --- a/lib/src/entities/telegram/story.dart +++ b/lib/src/entities/telegram/story.dart @@ -7,7 +7,7 @@ class Story { Story(); /// Creates a object from a json - static Story fromJson(Map json) { + factory Story.fromJson(Map _) { return Story(); } diff --git a/lib/src/entities/telegram/successful_payment.dart b/lib/src/entities/telegram/successful_payment.dart index 3c9d1bf..d8113bc 100644 --- a/lib/src/entities/telegram/successful_payment.dart +++ b/lib/src/entities/telegram/successful_payment.dart @@ -45,7 +45,7 @@ class SuccessfulPayment { }); /// Creates a object from a json - static SuccessfulPayment fromJson(Map json) { + factory SuccessfulPayment.fromJson(Map json) { return SuccessfulPayment( currency: json['currency']!, totalAmount: json['total_amount']!, diff --git a/lib/src/entities/telegram/switch_inline_query_chosen_chat.dart b/lib/src/entities/telegram/switch_inline_query_chosen_chat.dart index 792793b..e522df6 100644 --- a/lib/src/entities/telegram/switch_inline_query_chosen_chat.dart +++ b/lib/src/entities/telegram/switch_inline_query_chosen_chat.dart @@ -34,7 +34,7 @@ class SwitchInlineQueryChosenChat { }); /// Creates a object from a json - static SwitchInlineQueryChosenChat fromJson(Map json) { + factory SwitchInlineQueryChosenChat.fromJson(Map json) { return SwitchInlineQueryChosenChat( query: json['query'], allowUserChats: json['allow_user_chats'], diff --git a/lib/src/entities/telegram/update.dart b/lib/src/entities/telegram/update.dart index e031459..5b29827 100644 --- a/lib/src/entities/telegram/update.dart +++ b/lib/src/entities/telegram/update.dart @@ -105,7 +105,7 @@ class Update { }); /// Creates a object from a json - static Update fromJson(Map json) { + factory Update.fromJson(Map json) { return Update( updateId: json['update_id']!, message: callIfNotNull( diff --git a/lib/src/entities/telegram/user.dart b/lib/src/entities/telegram/user.dart index 903001f..e3049f4 100644 --- a/lib/src/entities/telegram/user.dart +++ b/lib/src/entities/telegram/user.dart @@ -63,7 +63,7 @@ class User { }); /// Creates a object from a json - static User fromJson(Map json) { + factory User.fromJson(Map json) { return User( id: json['id']!, isBot: json['is_bot']!, diff --git a/lib/src/entities/telegram/user_profile_photos.dart b/lib/src/entities/telegram/user_profile_photos.dart index 869710b..9723ba2 100644 --- a/lib/src/entities/telegram/user_profile_photos.dart +++ b/lib/src/entities/telegram/user_profile_photos.dart @@ -17,7 +17,7 @@ class UserProfilePhotos { }); /// Creates a object from a json - static UserProfilePhotos fromJson(Map json) { + factory UserProfilePhotos.fromJson(Map json) { return UserProfilePhotos( totalCount: json['total_count']!, photos: PhotoSize.listOfListsFromJsonArray(json['photos']!), diff --git a/lib/src/entities/telegram/user_shared.dart b/lib/src/entities/telegram/user_shared.dart index 874cdbc..6aa9f2d 100644 --- a/lib/src/entities/telegram/user_shared.dart +++ b/lib/src/entities/telegram/user_shared.dart @@ -23,7 +23,7 @@ class UserShared { ); /// Creates a object from a json - static UserShared fromJson(Map json) { + factory UserShared.fromJson(Map json) { return UserShared( json['request_id'], json['user_id'], diff --git a/lib/src/entities/telegram/venue.dart b/lib/src/entities/telegram/venue.dart index b05f788..41b2e7f 100644 --- a/lib/src/entities/telegram/venue.dart +++ b/lib/src/entities/telegram/venue.dart @@ -43,7 +43,7 @@ class Venue { }); /// Creates a object from a json - static Venue fromJson(Map json) { + factory Venue.fromJson(Map json) { return Venue( location: Location.fromJson(json['location']!), title: json['title']!, diff --git a/lib/src/entities/telegram/video.dart b/lib/src/entities/telegram/video.dart index 231a576..75aecb8 100644 --- a/lib/src/entities/telegram/video.dart +++ b/lib/src/entities/telegram/video.dart @@ -54,7 +54,7 @@ class Video { }); /// Creates a object from a json - static Video fromJson(Map json) { + factory Video.fromJson(Map json) { return Video( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/video_chat_ended.dart b/lib/src/entities/telegram/video_chat_ended.dart index 52fcc3d..8c4b34c 100644 --- a/lib/src/entities/telegram/video_chat_ended.dart +++ b/lib/src/entities/telegram/video_chat_ended.dart @@ -1,6 +1,7 @@ import 'dart:convert'; -///This object represents a service message about a video chat ended in the chat. +/// This object represents a service message about a video chat ended in the +/// chat. class VideoChatEnded { /// Video chat duration in seconds int duration; @@ -9,7 +10,7 @@ class VideoChatEnded { VideoChatEnded(this.duration); /// Creates a object from a json - static VideoChatEnded fromJson(Map json) { + factory VideoChatEnded.fromJson(Map json) { return VideoChatEnded(json['duration']); } diff --git a/lib/src/entities/telegram/video_chat_participants_invited.dart b/lib/src/entities/telegram/video_chat_participants_invited.dart index 135a319..9939b8a 100644 --- a/lib/src/entities/telegram/video_chat_participants_invited.dart +++ b/lib/src/entities/telegram/video_chat_participants_invited.dart @@ -10,10 +10,10 @@ class VideoChatParticipantsInvited { List? users; /// Basic constructor - VideoChatParticipantsInvited(users); + VideoChatParticipantsInvited(this.users); /// Creates a object from a json - static VideoChatParticipantsInvited fromJson(Map json) { + factory VideoChatParticipantsInvited.fromJson(Map json) { return VideoChatParticipantsInvited( callIfNotNull( User.listFromJsonArray, diff --git a/lib/src/entities/telegram/video_chat_scheduled.dart b/lib/src/entities/telegram/video_chat_scheduled.dart index 195d00e..248af37 100644 --- a/lib/src/entities/telegram/video_chat_scheduled.dart +++ b/lib/src/entities/telegram/video_chat_scheduled.dart @@ -13,7 +13,7 @@ class VideoChatScheduled { }); /// Creates a object from a json - static VideoChatScheduled fromJson(Map json) { + factory VideoChatScheduled.fromJson(Map json) { return VideoChatScheduled( startDate: json['start_date'], ); diff --git a/lib/src/entities/telegram/video_chat_started.dart b/lib/src/entities/telegram/video_chat_started.dart index c90da5b..0f0a5b8 100644 --- a/lib/src/entities/telegram/video_chat_started.dart +++ b/lib/src/entities/telegram/video_chat_started.dart @@ -7,7 +7,7 @@ class VideoChatStarted { VideoChatStarted(); /// Creates a object from a json - static VideoChatStarted fromJson(Map json) { + factory VideoChatStarted.fromJson(Map _) { return VideoChatStarted(); } diff --git a/lib/src/entities/telegram/video_note.dart b/lib/src/entities/telegram/video_note.dart index edcdd89..25ada46 100644 --- a/lib/src/entities/telegram/video_note.dart +++ b/lib/src/entities/telegram/video_note.dart @@ -39,7 +39,7 @@ class VideoNote { }); /// Creates a object from a json - static VideoNote fromJson(Map json) { + factory VideoNote.fromJson(Map json) { return VideoNote( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/voice.dart b/lib/src/entities/telegram/voice.dart index 96954a9..08988a3 100644 --- a/lib/src/entities/telegram/voice.dart +++ b/lib/src/entities/telegram/voice.dart @@ -34,7 +34,7 @@ class Voice { }); /// Creates a object from a json - static Voice fromJson(Map json) { + factory Voice.fromJson(Map json) { return Voice( fileId: json['file_id']!, fileUniqueId: json['file_unique_id']!, diff --git a/lib/src/entities/telegram/web_app_data.dart b/lib/src/entities/telegram/web_app_data.dart index 936d4c9..2ed8885 100644 --- a/lib/src/entities/telegram/web_app_data.dart +++ b/lib/src/entities/telegram/web_app_data.dart @@ -15,7 +15,7 @@ class WebAppData { ); /// Creates a object from a json - static WebAppData fromJson(Map json) { + factory WebAppData.fromJson(Map json) { return WebAppData( json['data'], json['button_text'], diff --git a/lib/src/entities/telegram/web_app_info.dart b/lib/src/entities/telegram/web_app_info.dart index 2ddb843..4b6f97f 100644 --- a/lib/src/entities/telegram/web_app_info.dart +++ b/lib/src/entities/telegram/web_app_info.dart @@ -8,7 +8,7 @@ class WebAppInfo { WebAppInfo(this.url); /// Creates a object from a json - static WebAppInfo fromJson(Map json) { + factory WebAppInfo.fromJson(Map json) { return WebAppInfo(json['url']); } diff --git a/lib/src/entities/telegram/write_access_allowed.dart b/lib/src/entities/telegram/write_access_allowed.dart index 05c2e92..452afc0 100644 --- a/lib/src/entities/telegram/write_access_allowed.dart +++ b/lib/src/entities/telegram/write_access_allowed.dart @@ -26,7 +26,7 @@ class WriteAccessAllowed { }); /// Creates a object from a json - static WriteAccessAllowed fromJson(Map json) { + factory WriteAccessAllowed.fromJson(Map json) { return WriteAccessAllowed( fromRequest: json['from_request'], webAppName: json['web_app_name'], diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index 82724f7..5d37125 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -12,9 +12,13 @@ export 'src/entities/telegram/bot_command_scope_chat.dart'; export 'src/entities/telegram/bot_command_scope_chat_administrators.dart'; export 'src/entities/telegram/bot_command_scope_chat_member.dart'; export 'src/entities/telegram/bot_command_scope_default.dart'; +export 'src/entities/telegram/bot_description.dart'; +export 'src/entities/telegram/bot_name.dart'; +export 'src/entities/telegram/bot_short_description.dart'; export 'src/entities/telegram/callback_game.dart'; export 'src/entities/telegram/callback_query.dart'; export 'src/entities/telegram/chat.dart'; +export 'src/entities/telegram/chat_administrator_rights.dart'; export 'src/entities/telegram/chat_invite_link.dart'; export 'src/entities/telegram/chat_join_request.dart'; export 'src/entities/telegram/chat_location.dart'; @@ -22,6 +26,7 @@ export 'src/entities/telegram/chat_member.dart'; export 'src/entities/telegram/chat_member_updated.dart'; export 'src/entities/telegram/chat_permissions.dart'; export 'src/entities/telegram/chat_photo.dart'; +export 'src/entities/telegram/chat_shared.dart'; export 'src/entities/telegram/chosen_inline_result.dart'; export 'src/entities/telegram/contact.dart'; export 'src/entities/telegram/dice.dart'; @@ -31,12 +36,19 @@ export 'src/entities/telegram/encrypted_passport_element.dart'; export 'src/entities/telegram/enums.dart'; export 'src/entities/telegram/file.dart'; export 'src/entities/telegram/force_reply.dart'; -export 'src/entities/telegram/forum_topic_created.dart'; +export 'src/entities/telegram/forum_topic.dart'; export 'src/entities/telegram/forum_topic_closed.dart'; +export 'src/entities/telegram/forum_topic_created.dart'; +export 'src/entities/telegram/forum_topic_edited.dart'; export 'src/entities/telegram/forum_topic_reopened.dart'; -export 'src/entities/telegram/forum_topic.dart'; export 'src/entities/telegram/game.dart'; export 'src/entities/telegram/game_high_score.dart'; +export 'src/entities/telegram/general_forum_topic_hidden.dart'; +export 'src/entities/telegram/general_forum_topic_unhidden.dart'; +export 'src/entities/telegram/giveaway.dart'; +export 'src/entities/telegram/giveaway_completed.dart'; +export 'src/entities/telegram/giveaway_created.dart'; +export 'src/entities/telegram/giveaway_winners.dart'; export 'src/entities/telegram/inline_keyboard_button.dart'; export 'src/entities/telegram/inline_keyboard_markup.dart'; export 'src/entities/telegram/inline_query.dart'; @@ -61,6 +73,7 @@ export 'src/entities/telegram/inline_query_result_photo.dart'; export 'src/entities/telegram/inline_query_result_venue.dart'; export 'src/entities/telegram/inline_query_result_video.dart'; export 'src/entities/telegram/inline_query_result_voice.dart'; +export 'src/entities/telegram/inline_query_results_button.dart'; export 'src/entities/telegram/input_contact_message_content.dart'; export 'src/entities/telegram/input_location_message_content.dart'; export 'src/entities/telegram/input_media.dart'; @@ -70,16 +83,23 @@ export 'src/entities/telegram/input_media_document.dart'; export 'src/entities/telegram/input_media_photo.dart'; export 'src/entities/telegram/input_media_video.dart'; export 'src/entities/telegram/input_message_content.dart'; +export 'src/entities/telegram/input_sticker.dart'; export 'src/entities/telegram/input_text_message_content.dart'; export 'src/entities/telegram/input_venue_message_content.dart'; export 'src/entities/telegram/invoice.dart'; export 'src/entities/telegram/keyboard_button.dart'; export 'src/entities/telegram/keyboard_button_poll_type.dart'; +export 'src/entities/telegram/keyboard_button_request_chat.dart'; +export 'src/entities/telegram/keyboard_button_request_user.dart'; export 'src/entities/telegram/labeled_price.dart'; export 'src/entities/telegram/link_preview_options.dart'; export 'src/entities/telegram/location.dart'; export 'src/entities/telegram/login_url.dart'; export 'src/entities/telegram/mask_position.dart'; +export 'src/entities/telegram/menu_button.dart'; +export 'src/entities/telegram/menu_button_commands.dart'; +export 'src/entities/telegram/menu_button_default.dart'; +export 'src/entities/telegram/menu_button_web_app.dart'; export 'src/entities/telegram/message.dart'; export 'src/entities/telegram/message_auto_delete_timer_changed.dart'; export 'src/entities/telegram/message_entity.dart'; @@ -97,47 +117,27 @@ export 'src/entities/telegram/reply_keyboard_markup.dart'; export 'src/entities/telegram/reply_keyboard_remove.dart'; export 'src/entities/telegram/reply_markup.dart'; export 'src/entities/telegram/response_parameters.dart'; +export 'src/entities/telegram/sent_web_app_message.dart'; export 'src/entities/telegram/shipping_address.dart'; export 'src/entities/telegram/shipping_option.dart'; export 'src/entities/telegram/shipping_query.dart'; export 'src/entities/telegram/sticker.dart'; export 'src/entities/telegram/sticker_set.dart'; +export 'src/entities/telegram/story.dart'; export 'src/entities/telegram/successful_payment.dart'; +export 'src/entities/telegram/switch_inline_query_chosen_chat.dart'; export 'src/entities/telegram/update.dart'; export 'src/entities/telegram/user.dart'; export 'src/entities/telegram/user_profile_photos.dart'; +export 'src/entities/telegram/user_shared.dart'; export 'src/entities/telegram/venue.dart'; export 'src/entities/telegram/video.dart'; -export 'src/entities/telegram/video_note.dart'; -export 'src/entities/telegram/voice.dart'; export 'src/entities/telegram/video_chat_ended.dart'; export 'src/entities/telegram/video_chat_participants_invited.dart'; export 'src/entities/telegram/video_chat_scheduled.dart'; export 'src/entities/telegram/video_chat_started.dart'; -export 'src/entities/telegram/web_app_info.dart'; -export 'src/entities/telegram/sent_web_app_message.dart'; +export 'src/entities/telegram/video_note.dart'; +export 'src/entities/telegram/voice.dart'; export 'src/entities/telegram/web_app_data.dart'; -export 'src/entities/telegram/menu_button.dart'; -export 'src/entities/telegram/menu_button_commands.dart'; -export 'src/entities/telegram/menu_button_web_app.dart'; -export 'src/entities/telegram/menu_button_default.dart'; -export 'src/entities/telegram/chat_administrator_rights.dart'; -export 'src/entities/telegram/forum_topic_edited.dart'; -export 'src/entities/telegram/general_forum_topic_hidden.dart'; -export 'src/entities/telegram/general_forum_topic_unhidden.dart'; +export 'src/entities/telegram/web_app_info.dart'; export 'src/entities/telegram/write_access_allowed.dart'; -export 'src/entities/telegram/keyboard_button_request_user.dart'; -export 'src/entities/telegram/keyboard_button_request_chat.dart'; -export 'src/entities/telegram/chat_shared.dart'; -export 'src/entities/telegram/user_shared.dart'; -export 'src/entities/telegram/bot_description.dart'; -export 'src/entities/telegram/bot_short_description.dart'; -export 'src/entities/telegram/input_sticker.dart'; -export 'src/entities/telegram/inline_query_results_button.dart'; -export 'src/entities/telegram/switch_inline_query_chosen_chat.dart'; -export 'src/entities/telegram/bot_name.dart'; -export 'src/entities/telegram/story.dart'; -export 'src/entities/telegram/giveaway_created.dart'; -export 'src/entities/telegram/giveaway.dart'; -export 'src/entities/telegram/giveaway_winners.dart'; -export 'src/entities/telegram/giveaway_completed.dart'; diff --git a/test/main_test.dart b/test/main_test.dart index e613243..d68033d 100644 --- a/test/main_test.dart +++ b/test/main_test.dart @@ -25,7 +25,10 @@ void main() { if (!initialized) { print('Setting up bot...'); var token = io.Platform.environment['BOT_TOKEN']; - if (token == null) throw ('BOT_TOKEN environment variable is missing!'); + if (token == null) { + throw Exception('BOT_TOKEN environment variable is missing!'); + } + testBot = Bot(token: token); initialized = true; } @@ -58,7 +61,7 @@ void main() { // TODO fix test Bot(token: 'Wrong token'); }, - throwsA(TypeMatcher()), + throwsA(const TypeMatcher()), ); }, skip: true, @@ -69,7 +72,7 @@ void main() { () async { expect( testBot.stop, - throwsA(TypeMatcher()), + throwsA(const TypeMatcher()), ); }, skip: true, @@ -123,7 +126,9 @@ void main() { 'Send photo with ID', () async { var message = await testBot.sendPhoto( - ChatID(chatId), HttpFile.fromToken(photoToken!)); + ChatID(chatId), + HttpFile.fromToken(photoToken!), + ); expect(message.photo, isNotNull); }, skip: false, @@ -164,7 +169,9 @@ void main() { 'Send audio with ID', () async { var message = await testBot.sendAudio( - ChatID(chatId), HttpFile.fromToken(audioToken!)); + ChatID(chatId), + HttpFile.fromToken(audioToken!), + ); expect(message.audio, isNotNull); }, skip: false, @@ -207,27 +214,31 @@ void main() { skip: false, ); - test('Send video from file with all args works', () async { - var message = await testBot.sendVideo( - ChatID(chatId), - HttpFile.fromBytes( - 'video.mp4', - await io.File('resources/video.mp4').readAsBytes(), - ), - // thumb: HttpFile.fromPath('resources/test.jpg'), - caption: '*Test*', - parseMode: ParseMode.markdown, - disableNotification: true, - replyToMessageId: replyId, - ); - expect(message.captionEntities!.length, equals(1)); - expect(message.captionEntities!.first.type, equals('bold')); - expect(message.chat.id, equals(chatId)); - expect(message.replyToMessage!.messageId, equals(replyId)); - expect(message.video, isNotNull); - expect(message.video!.fileUniqueId, isNotNull); - expect(message.caption, equals('Test')); - }, skip: true); + test( + 'Send video from file with all args works', + () async { + var message = await testBot.sendVideo( + ChatID(chatId), + HttpFile.fromBytes( + 'video.mp4', + await io.File('resources/video.mp4').readAsBytes(), + ), + // thumb: HttpFile.fromPath('resources/test.jpg'), + caption: '*Test*', + parseMode: ParseMode.markdown, + disableNotification: true, + replyToMessageId: replyId, + ); + expect(message.captionEntities!.length, equals(1)); + expect(message.captionEntities!.first.type, equals('bold')); + expect(message.chat.id, equals(chatId)); + expect(message.replyToMessage!.messageId, equals(replyId)); + expect(message.video, isNotNull); + expect(message.video!.fileUniqueId, isNotNull); + expect(message.caption, equals('Test')); + }, + skip: true, + ); test( 'Send video with ID', @@ -368,7 +379,7 @@ void main() { ); expect(message.text, equals('Buttons!')); - var markup = message.replyMarkup as InlineKeyboardMarkup; + var markup = message.replyMarkup! as InlineKeyboardMarkup; expect(markup.inlineKeyboard.length, equals(2)); expect(markup.inlineKeyboard[0][0].text, equals('Button 1')); expect(markup.inlineKeyboard[0][0].callbackData, equals('btn1')); @@ -407,8 +418,10 @@ void main() { expect(markup, isNotNull); if (markup == null) throw Exception('Markup is null'); expect(markup.inlineKeyboard.length, equals(2)); - expect(markup.inlineKeyboard[0][0].text, - equals('Button 1')); // Just check first button text + expect( + markup.inlineKeyboard[0][0].text, + equals('Button 1'), + ); // Just check first button text expect(markup.inlineKeyboard[0][0].callbackData, equals('cbd1')); expect( @@ -444,7 +457,7 @@ void main() { KeyboardButton.requestPoll( 'Poll (Regular)', KeyboardButtonPollType(type: PollType.regular), - ) + ), ] ]; var message = await testBot.sendMessage( @@ -463,7 +476,7 @@ void main() { 'sendMessage with ReplyMarkup (ReplyKeyboardRemove) works', () async { var buttons = [ - [KeyboardButton.requestLocation('Location', requestLocation: true)] + [KeyboardButton.requestLocation('Location', requestLocation: true)], ]; await testBot.sendMessage( ChatID(chatId), @@ -483,7 +496,7 @@ void main() { 'sendMessage with ReplyMarkup (ForceReply) works', () async { var buttons = [ - [KeyboardButton.requestLocation('Location', requestLocation: true)] + [KeyboardButton.requestLocation('Location', requestLocation: true)], ]; await testBot.sendMessage( ChatID(chatId), @@ -539,11 +552,12 @@ void main() { 'setChatPhoto works', () async { var ok = await testBot.setChatPhoto( - ChatID(groupId), - HttpFile.fromBytes( - 'test.jpg', - await io.File('resources/test.jpg').readAsBytes(), - )); + ChatID(groupId), + HttpFile.fromBytes( + 'test.jpg', + await io.File('resources/test.jpg').readAsBytes(), + ), + ); expect(ok, isTrue); }, skip: true, From 70329fc150b7a62289e5b70578bc119acae9ea53 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Mon, 26 Feb 2024 00:09:47 +0100 Subject: [PATCH 07/12] fixes --- lib/src/entities/telegram/chat.dart | 5 +++++ lib/src/entities/telegram/giveaway.dart | 4 ++-- lib/src/entities/telegram/giveaway_completed.dart | 7 ++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/src/entities/telegram/chat.dart b/lib/src/entities/telegram/chat.dart index 650c5d5..5693124 100644 --- a/lib/src/entities/telegram/chat.dart +++ b/lib/src/entities/telegram/chat.dart @@ -231,6 +231,11 @@ class Chat { ); } + /// Creates a list of object from a json array + static List listFromJsonArray(List json) { + return List.generate(json.length, (i) => Chat.fromJson(json[i])); + } + /// Creates a json from the object Map toJson() { return { diff --git a/lib/src/entities/telegram/giveaway.dart b/lib/src/entities/telegram/giveaway.dart index 8bd9064..3f6288f 100644 --- a/lib/src/entities/telegram/giveaway.dart +++ b/lib/src/entities/telegram/giveaway.dart @@ -55,13 +55,13 @@ class Giveaway { /// Creates a object from a json factory Giveaway.fromJson(Map json) { return Giveaway( - chats: json['chats'], + chats: Chat.listFromJsonArray(json['chats']), winnersSelectionDate: json['winners_selection_date'], winnerCount: json['winner_count'], onlyNewMembers: json['only_new_members'], hasPublicWinners: json['has_public_winners'], prizeDescription: json['prize_description'], - countryCodes: json['country_codes'], + countryCodes: List.from(json['country_codes'] ?? []), premiumSubscriptionMonthCount: json['premium_subscription_month_count'], ); } diff --git a/lib/src/entities/telegram/giveaway_completed.dart b/lib/src/entities/telegram/giveaway_completed.dart index eac94f4..a799f61 100644 --- a/lib/src/entities/telegram/giveaway_completed.dart +++ b/lib/src/entities/telegram/giveaway_completed.dart @@ -1,4 +1,6 @@ import 'dart:convert'; +import 'package:dart_telegram_bot/src/entities/internal/helpers/util.dart'; + import '../../../telegram_entities.dart'; /// This object represents a service message about the completion of a @@ -27,7 +29,10 @@ class GiveawayCompleted { return GiveawayCompleted( winnerCount: json['winner_count'], unclaimedPrizeCount: json['unclaimed_prize_count'], - giveawayMessage: json['giveaway_message'], + giveawayMessage: callIfNotNull( + Message.fromJson, + json['giveaway_message'], + ), ); } From cfc0e97d4afddde272f6d6e41ec142dc3c00fe9a Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Tue, 9 Apr 2024 23:49:12 +0200 Subject: [PATCH 08/12] Added "Other Changes" content --- lib/src/entities/telegram/callback_query.dart | 6 +- lib/src/entities/telegram/chat.dart | 53 ++++++++++++++++-- .../telegram/inaccessible_message.dart | 48 ++++++++++++++++ .../telegram/maybe_inaccessible_message.dart | 20 +++++++ lib/src/entities/telegram/message.dart | 9 ++- lib/src/entities/telegram/message_origin.dart | 26 +++++++++ .../telegram/message_origin_channel.dart | 55 +++++++++++++++++++ .../telegram/message_origin_chat.dart | 50 +++++++++++++++++ .../telegram/message_origin_hidden_user.dart | 42 ++++++++++++++ .../telegram/message_origin_user.dart | 42 ++++++++++++++ lib/telegram_entities.dart | 7 +++ 11 files changed, 347 insertions(+), 11 deletions(-) create mode 100644 lib/src/entities/telegram/inaccessible_message.dart create mode 100644 lib/src/entities/telegram/maybe_inaccessible_message.dart create mode 100644 lib/src/entities/telegram/message_origin.dart create mode 100644 lib/src/entities/telegram/message_origin_channel.dart create mode 100644 lib/src/entities/telegram/message_origin_chat.dart create mode 100644 lib/src/entities/telegram/message_origin_hidden_user.dart create mode 100644 lib/src/entities/telegram/message_origin_user.dart diff --git a/lib/src/entities/telegram/callback_query.dart b/lib/src/entities/telegram/callback_query.dart index f29d418..f1825e1 100644 --- a/lib/src/entities/telegram/callback_query.dart +++ b/lib/src/entities/telegram/callback_query.dart @@ -17,10 +17,8 @@ class CallbackQuery { User from; /// Optional. - /// Message with the callback button that originated the query. - /// Note that message content and message date will not be available if the - /// message is too old - Message? message; + /// Message sent by the bot with the callback button that originated the query + MaybeInaccessibleMessage? message; /// Optional. /// Identifier of the message sent via the bot in inline mode, diff --git a/lib/src/entities/telegram/chat.dart b/lib/src/entities/telegram/chat.dart index 5693124..58f686b 100644 --- a/lib/src/entities/telegram/chat.dart +++ b/lib/src/entities/telegram/chat.dart @@ -45,6 +45,32 @@ class Chat { /// Returned only in getChat. List? activeUsernames; + /// Optional. + /// Identifier of the accent color for the chat name and backgrounds of + /// the chat photo, reply header, and link preview. + /// See accent colors for more details. + /// Returned only in getChat. + /// Always returned in getChat. + int? accentColorId; + + /// Optional. + /// Custom emoji identifier of emoji chosen by the chat for the reply header + /// and link preview background. + /// Returned only in getChat. + String? backgroundCustomEmojiId; + + /// Optional. + /// Identifier of the accent color for the chat's profile background. + /// See profile accent colors for more details. + /// Returned only in getChat. + int? profileAccentColorId; + + /// Optional. + /// Custom emoji identifier of the emoji chosen by the chat for + /// its profile background. + /// Returned only in getChat. + String? profileBackgroundCustomEmojiId; + /// Optional. /// Custom emoji identifier of emoji status of the other party in a /// private chat. @@ -133,6 +159,12 @@ class Chat { /// Returned only in getChat. bool? hasProtectedContent; + /// Optional. + /// True, if new chat members will have access to old messages; + /// available only to chat administrators. + /// Returned only in getChat. + bool? hasVisibleHistory; + /// Optional. /// For supergroups, name of group sticker set. /// Returned only in getChat. @@ -170,6 +202,10 @@ class Chat { this.isForum, this.photo, this.activeUsernames, + this.accentColorId, + this.backgroundCustomEmojiId, + this.profileAccentColorId, + this.profileBackgroundCustomEmojiId, this.emojiStatusCustomEmojiId, this.emojiStatusExpirationDate, this.bio, @@ -186,6 +222,7 @@ class Chat { this.hasAggressiveAntiSpamEnabled, this.hasHiddenMembers, this.hasProtectedContent, + this.hasVisibleHistory, this.stickerSetName, this.canSetStickerSet, this.linkedChatId, @@ -204,6 +241,11 @@ class Chat { isForum: json['is_forum'], photo: callIfNotNull(ChatPhoto.fromJson, json['photo']), activeUsernames: List.from(json['active_usernames'] ?? []), + accentColorId: json['accent_color_id'], + backgroundCustomEmojiId: json['background_custom_emoji_id'], + profileAccentColorId: json['profile_accent_color_id'], + profileBackgroundCustomEmojiId: + json['profile_background_custom_emoji_id'], emojiStatusCustomEmojiId: json['emoji_status_custom_emoji_id'], emojiStatusExpirationDate: json['emoji_status_expiration_date'], bio: json['bio'], @@ -221,13 +263,11 @@ class Chat { hasAggressiveAntiSpamEnabled: json['has_aggressive_anti_spam_enabled'], hasHiddenMembers: json['has_hidden_members'], hasProtectedContent: json['has_protected_content'], + hasVisibleHistory: json['has_visible_history'], stickerSetName: json['sticker_set_name'], canSetStickerSet: json['can_set_sticker_set'], linkedChatId: json['linked_chat_id'], - location: callIfNotNull( - ChatLocation.fromJson, - json['location'], - ), + location: callIfNotNull(ChatLocation.fromJson, json['location']), ); } @@ -248,6 +288,10 @@ class Chat { 'is_forum': isForum, 'photo': photo, 'active_usernames': activeUsernames, + 'accent_color_id': accentColorId, + 'background_custom_emoji_id': backgroundCustomEmojiId, + 'profile_accent_color_id': profileAccentColorId, + 'profile_background_custom_emoji_id': profileBackgroundCustomEmojiId, 'emoji_status_custom_emoji_id': emojiStatusCustomEmojiId, 'emoji_status_expiration_date': emojiStatusExpirationDate, 'bio': bio, @@ -265,6 +309,7 @@ class Chat { 'has_aggressive_anti_spam_enabled': hasAggressiveAntiSpamEnabled, 'has_hidden_members': hasHiddenMembers, 'has_protected_content': hasProtectedContent, + 'has_visible_history': hasVisibleHistory, 'sticker_set_name': stickerSetName, 'can_set_sticker_set': canSetStickerSet, 'linked_chat_id': linkedChatId, diff --git a/lib/src/entities/telegram/inaccessible_message.dart b/lib/src/entities/telegram/inaccessible_message.dart new file mode 100644 index 0000000..3efe761 --- /dev/null +++ b/lib/src/entities/telegram/inaccessible_message.dart @@ -0,0 +1,48 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// This object describes a message that was deleted or is otherwise +/// inaccessible to the bot. +class InaccessibleMessage extends MaybeInaccessibleMessage { + /// Chat the message belonged to + @override + Chat chat; + + /// Unique message identifier inside the chat + @override + int messageId; + + /// Always 0. + /// The field can be used to differentiate regular and inaccessible messages. + @override + int date; + + /// Basic constructor + InaccessibleMessage({ + required this.chat, + required this.messageId, + required this.date, + }); + + /// Creates a object from a json + factory InaccessibleMessage.fromJson(Map json) { + return InaccessibleMessage( + chat: Chat.fromJson(json['chat']), + messageId: json['message_id'], + date: json['date'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'chat': chat, + 'message_id': messageId, + 'date': date, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/maybe_inaccessible_message.dart b/lib/src/entities/telegram/maybe_inaccessible_message.dart new file mode 100644 index 0000000..5343da6 --- /dev/null +++ b/lib/src/entities/telegram/maybe_inaccessible_message.dart @@ -0,0 +1,20 @@ +import '../../../telegram_entities.dart'; + +/// This object describes a message that can be inaccessible to the bot. +/// It can be one of: +/// Message, +/// InaccessibleMessage +abstract class MaybeInaccessibleMessage { + abstract Chat chat; + abstract int messageId; + abstract int date; + + /// Creates a object from a json + static MaybeInaccessibleMessage fromJson(Map json) { + if (json['date'] == 0) { + return InaccessibleMessage.fromJson(json); + } else { + return Message.fromJson(json); + } + } +} diff --git a/lib/src/entities/telegram/message.dart b/lib/src/entities/telegram/message.dart index 2feba83..83d86a1 100644 --- a/lib/src/entities/telegram/message.dart +++ b/lib/src/entities/telegram/message.dart @@ -4,8 +4,9 @@ import '../../../telegram_entities.dart'; import '../internal/helpers/util.dart'; /// This object represents a message. -class Message { +class Message extends MaybeInaccessibleMessage { /// Unique message identifier inside this chat + @override int messageId; /// Optional. @@ -29,9 +30,11 @@ class Message { Chat? senderChat; /// Date the message was sent in Unix time + @override int date; /// Conversation the message belongs to + @override Chat chat; /// Optional. @@ -255,8 +258,8 @@ class Message { /// Optional. /// Specified message was pinned. /// Note that the Message object in this field will not contain further - /// reply_to_message fields even if it is itself a reply. - Message? pinnedMessage; + /// reply_to_message fields even if it itself is a reply. + MaybeInaccessibleMessage? pinnedMessage; /// Optional. /// Message is an invoice for a payment, information about the invoice. diff --git a/lib/src/entities/telegram/message_origin.dart b/lib/src/entities/telegram/message_origin.dart new file mode 100644 index 0000000..f067de3 --- /dev/null +++ b/lib/src/entities/telegram/message_origin.dart @@ -0,0 +1,26 @@ +import '../../../telegram_entities.dart'; + +/// This object describes the origin of a message. +/// It can be one of: +/// MessageOriginUser, +/// MessageOriginHiddenUser, +/// MessageOriginChat, +/// MessageOriginChannel +abstract class MessageOrigin { + abstract final String type; + + static MessageOrigin fromJson(Map json) { + switch (json['type']) { + case 'user': + return MessageOriginUser.fromJson(json); + case 'hidden_user': + return MessageOriginHiddenUser.fromJson(json); + case 'chat': + return MessageOriginChat.fromJson(json); + case 'channel': + return MessageOriginChannel.fromJson(json); + default: + throw Exception('MessageOrigin type not recognized'); + } + } +} diff --git a/lib/src/entities/telegram/message_origin_channel.dart b/lib/src/entities/telegram/message_origin_channel.dart new file mode 100644 index 0000000..2e5a470 --- /dev/null +++ b/lib/src/entities/telegram/message_origin_channel.dart @@ -0,0 +1,55 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// The message was originally sent to a channel chat. +class MessageOriginChannel extends MessageOrigin { + /// Type of the message origin, always โ€œchannelโ€ + @override + String type = 'user'; + + /// Date the message was sent originally in Unix time + int date; + + /// Channel chat to which the message was originally sent + Chat chat; + + /// Unique message identifier inside the chat + int messageId; + + /// Optional. + /// Signature of the original post author + String? authorSignature; + + /// Basic constructor + MessageOriginChannel({ + required this.date, + required this.chat, + required this.messageId, + this.authorSignature, + }); + + /// Creates a object from a json + factory MessageOriginChannel.fromJson(Map json) { + return MessageOriginChannel( + date: json['date'], + chat: Chat.fromJson(json['chat']), + messageId: json['message_id'], + authorSignature: json['author_signature'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'type': type, + 'date': date, + 'chat': chat, + 'message_id': messageId, + 'author_signature': authorSignature, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/message_origin_chat.dart b/lib/src/entities/telegram/message_origin_chat.dart new file mode 100644 index 0000000..07afaab --- /dev/null +++ b/lib/src/entities/telegram/message_origin_chat.dart @@ -0,0 +1,50 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// The message was originally sent on behalf of a chat to a group chat. +class MessageOriginChat extends MessageOrigin { + /// Type of the message origin, always โ€œchatโ€ + @override + String type = 'user'; + + /// Date the message was sent originally in Unix time + int date; + + /// Chat that sent the message originally + Chat senderChat; + + /// Optional. + /// For messages originally sent by an anonymous chat administrator, + /// original message author signature + String? authorSignature; + + /// Basic constructor + MessageOriginChat({ + required this.date, + required this.senderChat, + this.authorSignature, + }); + + /// Creates a object from a json + factory MessageOriginChat.fromJson(Map json) { + return MessageOriginChat( + date: json['date'], + senderChat: Chat.fromJson(json['sender_chat']), + authorSignature: json['author_signature'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'type': type, + 'date': date, + 'sender_chat': senderChat, + 'author_signature': authorSignature, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/message_origin_hidden_user.dart b/lib/src/entities/telegram/message_origin_hidden_user.dart new file mode 100644 index 0000000..76eccbe --- /dev/null +++ b/lib/src/entities/telegram/message_origin_hidden_user.dart @@ -0,0 +1,42 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// The message was originally sent by an unknown user. +class MessageOriginHiddenUser extends MessageOrigin { + /// Type of the message origin, always โ€œhidden_userโ€ + @override + String type = 'user'; + + /// Date the message was sent originally in Unix time + int date; + + /// Name of the user that sent the message originally + String senderUserName; + + /// Basic constructor + MessageOriginHiddenUser({ + required this.date, + required this.senderUserName, + }); + + /// Creates a object from a json + factory MessageOriginHiddenUser.fromJson(Map json) { + return MessageOriginHiddenUser( + date: json['date'], + senderUserName: json['sender_user_name'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'type': type, + 'date': date, + 'sender_user_name': senderUserName, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/message_origin_user.dart b/lib/src/entities/telegram/message_origin_user.dart new file mode 100644 index 0000000..f5e4199 --- /dev/null +++ b/lib/src/entities/telegram/message_origin_user.dart @@ -0,0 +1,42 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// The message was originally sent by a known user. +class MessageOriginUser extends MessageOrigin { + /// Type of the message origin, always โ€œuserโ€ + @override + String type = 'user'; + + /// Date the message was sent originally in Unix time + int date; + + /// User that sent the message originally + User senderUser; + + /// Basic constructor + MessageOriginUser({ + required this.date, + required this.senderUser, + }); + + /// Creates a object from a json + factory MessageOriginUser.fromJson(Map json) { + return MessageOriginUser( + date: json['date'], + senderUser: User.fromJson(json['sender_user']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'type': type, + 'date': date, + 'sender_user': senderUser, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index 5d37125..855498f 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -49,6 +49,7 @@ export 'src/entities/telegram/giveaway.dart'; export 'src/entities/telegram/giveaway_completed.dart'; export 'src/entities/telegram/giveaway_created.dart'; export 'src/entities/telegram/giveaway_winners.dart'; +export 'src/entities/telegram/inaccessible_message.dart'; export 'src/entities/telegram/inline_keyboard_button.dart'; export 'src/entities/telegram/inline_keyboard_markup.dart'; export 'src/entities/telegram/inline_query.dart'; @@ -96,6 +97,7 @@ export 'src/entities/telegram/link_preview_options.dart'; export 'src/entities/telegram/location.dart'; export 'src/entities/telegram/login_url.dart'; export 'src/entities/telegram/mask_position.dart'; +export 'src/entities/telegram/maybe_inaccessible_message.dart'; export 'src/entities/telegram/menu_button.dart'; export 'src/entities/telegram/menu_button_commands.dart'; export 'src/entities/telegram/menu_button_default.dart'; @@ -104,6 +106,11 @@ export 'src/entities/telegram/message.dart'; export 'src/entities/telegram/message_auto_delete_timer_changed.dart'; export 'src/entities/telegram/message_entity.dart'; export 'src/entities/telegram/message_id.dart'; +export 'src/entities/telegram/message_origin.dart'; +export 'src/entities/telegram/message_origin_channel.dart'; +export 'src/entities/telegram/message_origin_chat.dart'; +export 'src/entities/telegram/message_origin_hidden_user.dart'; +export 'src/entities/telegram/message_origin_user.dart'; export 'src/entities/telegram/order_info.dart'; export 'src/entities/telegram/passport_data.dart'; export 'src/entities/telegram/passport_file.dart'; From d6feba065bbae8cd6e66941c9edf1ba6b783e1c0 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Wed, 10 Apr 2024 00:35:56 +0200 Subject: [PATCH 09/12] Added "Chat Boost" content --- lib/src/entities/internal/tgapi_client.dart | 1 + lib/src/entities/internal/tgapi_methods.dart | 14 +++++ lib/src/entities/telegram/chat_boost.dart | 55 +++++++++++++++++++ .../entities/telegram/chat_boost_removed.dart | 49 +++++++++++++++++ .../entities/telegram/chat_boost_source.dart | 23 ++++++++ .../telegram/chat_boost_source_gift_code.dart | 35 ++++++++++++ .../telegram/chat_boost_source_giveaway.dart | 54 ++++++++++++++++++ .../telegram/chat_boost_source_premium.dart | 33 +++++++++++ .../entities/telegram/chat_boost_updated.dart | 37 +++++++++++++ lib/src/entities/telegram/update.dart | 22 ++++++++ .../entities/telegram/user_chat_boosts.dart | 31 +++++++++++ lib/telegram_entities.dart | 8 +++ 12 files changed, 362 insertions(+) create mode 100644 lib/src/entities/telegram/chat_boost.dart create mode 100644 lib/src/entities/telegram/chat_boost_removed.dart create mode 100644 lib/src/entities/telegram/chat_boost_source.dart create mode 100644 lib/src/entities/telegram/chat_boost_source_gift_code.dart create mode 100644 lib/src/entities/telegram/chat_boost_source_giveaway.dart create mode 100644 lib/src/entities/telegram/chat_boost_source_premium.dart create mode 100644 lib/src/entities/telegram/chat_boost_updated.dart create mode 100644 lib/src/entities/telegram/user_chat_boosts.dart diff --git a/lib/src/entities/internal/tgapi_client.dart b/lib/src/entities/internal/tgapi_client.dart index 5f61287..be5e79d 100644 --- a/lib/src/entities/internal/tgapi_client.dart +++ b/lib/src/entities/internal/tgapi_client.dart @@ -27,6 +27,7 @@ class TGAPIClient { static final _typeFactories = )>{ 'User': User.fromJson, 'Message': Message.fromJson, + 'UserChatBoosts': UserChatBoosts.fromJson, 'UserProfilePhotos': UserProfilePhotos.fromJson, 'File': File.fromJson, 'ChatMember': ChatMember.fromJson, diff --git a/lib/src/entities/internal/tgapi_methods.dart b/lib/src/entities/internal/tgapi_methods.dart index 0e26c16..82ee329 100644 --- a/lib/src/entities/internal/tgapi_methods.dart +++ b/lib/src/entities/internal/tgapi_methods.dart @@ -1506,6 +1506,20 @@ mixin TGAPIMethods { }); } + /// Use this method to get the list of boosts added to a chat by a user. + /// Requires administrator rights in the chat. + /// + /// Returns a UserChatBoosts object. + Future getUserChatBoosts( + ChatID chatId, + int userId, + ) { + return _client.apiCall(_token, 'getUserChatBoosts', { + 'chat_id': chatId, + 'user_id': userId, + }); + } + /// Use this method to change the list of the bot's commands. /// See https://core.telegram.org/bots#commands for more details about /// bot commands. diff --git a/lib/src/entities/telegram/chat_boost.dart b/lib/src/entities/telegram/chat_boost.dart new file mode 100644 index 0000000..75e12bc --- /dev/null +++ b/lib/src/entities/telegram/chat_boost.dart @@ -0,0 +1,55 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// This object contains information about a chat boost. +class ChatBoost { + /// Unique identifier of the boost + String boostId; + + /// Point in time (Unix timestamp) when the chat was boosted + int addDate; + + /// Point in time (Unix timestamp) when the boost will automatically expire, + /// unless the booster's Telegram Premium subscription is prolonged + int expirationDate; + + /// Source of the added boost + ChatBoostSource source; + + /// Basic constructor + ChatBoost({ + required this.boostId, + required this.addDate, + required this.expirationDate, + required this.source, + }); + + /// Creates a object from a json + factory ChatBoost.fromJson(Map json) { + return ChatBoost( + boostId: json['boost_id'], + addDate: json['add_date'], + expirationDate: json['expiration_date'], + source: ChatBoostSource.fromJson(json['source']), + ); + } + + /// Creates a list of object from a json array + static List listFromJsonArray(List array) { + return List.generate(array.length, (i) => ChatBoost.fromJson(array[i])); + } + + /// Creates a json from the object + Map toJson() { + return { + 'boost_id': boostId, + 'add_date': addDate, + 'expiration_date': expirationDate, + 'source': source, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/chat_boost_removed.dart b/lib/src/entities/telegram/chat_boost_removed.dart new file mode 100644 index 0000000..796e9af --- /dev/null +++ b/lib/src/entities/telegram/chat_boost_removed.dart @@ -0,0 +1,49 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// This object represents a boost removed from a chat. +class ChatBoostRemoved { + /// Chat which was boosted + Chat chat; + + /// Unique identifier of the boost + String boostId; + + /// Point in time (Unix timestamp) when the boost was removed + int removeDate; + + /// Source of the removed boost + ChatBoostSource source; + + /// Basic constructor + ChatBoostRemoved({ + required this.chat, + required this.boostId, + required this.removeDate, + required this.source, + }); + + /// Creates a object from a json + factory ChatBoostRemoved.fromJson(Map json) { + return ChatBoostRemoved( + chat: Chat.fromJson(json['chat']), + boostId: json['boost_id'], + removeDate: json['remove_date'], + source: ChatBoostSource.fromJson(json['source']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'chat': chat, + 'boost_id': boostId, + 'remove_date': removeDate, + 'source': source, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/chat_boost_source.dart b/lib/src/entities/telegram/chat_boost_source.dart new file mode 100644 index 0000000..058f89d --- /dev/null +++ b/lib/src/entities/telegram/chat_boost_source.dart @@ -0,0 +1,23 @@ +import '../../../telegram_entities.dart'; + +/// This object describes the source of a chat boost. +/// It can be one of: +/// ChatBoostSourcePremium, +/// ChatBoostSourceGiftCode, +/// ChatBoostSourceGiveaway +abstract class ChatBoostSource { + abstract final String source; + + static ChatBoostSource fromJson(Map json) { + switch (json['type']) { + case 'user': + return ChatBoostSourcePremium.fromJson(json); + case 'hidden_user': + return ChatBoostSourceGiftCode.fromJson(json); + case 'chat': + return ChatBoostSourceGiveaway.fromJson(json); + default: + throw Exception('ChatBoostSource type not recognized'); + } + } +} diff --git a/lib/src/entities/telegram/chat_boost_source_gift_code.dart b/lib/src/entities/telegram/chat_boost_source_gift_code.dart new file mode 100644 index 0000000..7f657f8 --- /dev/null +++ b/lib/src/entities/telegram/chat_boost_source_gift_code.dart @@ -0,0 +1,35 @@ +import 'package:dart_telegram_bot/telegram_entities.dart'; + +/// The boost was obtained by the creation of Telegram Premium gift codes +/// to boost a chat. +/// Each such code boosts the chat 4 times for the duration of thecorresponding +/// Telegram Premium subscription. +class ChatBoostSourceGiftCode extends ChatBoostSource { + /// Source of the boost, always โ€œgift_codeโ€ + @override + final String source = 'gift_code'; + + /// User for which the gift code was created + User user; + + /// Basic constructor + ChatBoostSourceGiftCode({ + required this.user, + }); + + /// Creates a object from a json + factory ChatBoostSourceGiftCode.fromJson(Map json) { + return ChatBoostSourceGiftCode(user: User.fromJson(json['user'])); + } + + /// Creates a json from the object + Map toJson() { + return { + 'source': source, + 'user': user, + }; + } + + @override + String toString() => toJson().toString(); +} diff --git a/lib/src/entities/telegram/chat_boost_source_giveaway.dart b/lib/src/entities/telegram/chat_boost_source_giveaway.dart new file mode 100644 index 0000000..118bad3 --- /dev/null +++ b/lib/src/entities/telegram/chat_boost_source_giveaway.dart @@ -0,0 +1,54 @@ +import 'package:dart_telegram_bot/src/entities/internal/helpers/util.dart'; + +import '../../../telegram_entities.dart'; + +/// The boost was obtained by the creation of a Telegram Premium giveaway. +/// This boosts the chat 4 times for the duration of the corresponding +/// Telegram Premium subscription. +class ChatBoostSourceGiveaway extends ChatBoostSource { + /// Source of the boost, always โ€œgiveawayโ€ + @override + final String source = 'giveaway'; + + /// Identifier of a message in the chat with the giveaway; + /// the message could have been deleted already. + /// May be 0 if the message isn't sent yet. + int giveawayMessageId; + + /// Optional. + /// User that won the prize in the giveaway if any + User? user; + + /// Optional. + /// True, if the giveaway was completed, but there was no user to win the prize + bool? isUnclaimed; + + /// Basic constructor + ChatBoostSourceGiveaway({ + required this.giveawayMessageId, + this.user, + this.isUnclaimed, + }); + + /// Creates a object from a json + factory ChatBoostSourceGiveaway.fromJson(Map json) { + return ChatBoostSourceGiveaway( + giveawayMessageId: json['giveaway_message_id'], + user: callIfNotNull(User.fromJson, json['user']), + isUnclaimed: json['is_unclaimed'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'source': source, + 'giveaway_message_id': giveawayMessageId, + 'user': user, + 'is_unclaimed': isUnclaimed, + }; + } + + @override + String toString() => toJson().toString(); +} diff --git a/lib/src/entities/telegram/chat_boost_source_premium.dart b/lib/src/entities/telegram/chat_boost_source_premium.dart new file mode 100644 index 0000000..385b215 --- /dev/null +++ b/lib/src/entities/telegram/chat_boost_source_premium.dart @@ -0,0 +1,33 @@ +import '../../../telegram_entities.dart'; + +/// The boost was obtained by subscribing to Telegram Premium or by gifting a +/// Telegram Premium subscription to another user. +class ChatBoostSourcePremium extends ChatBoostSource { + /// Source of the boost, always โ€œpremiumโ€ + @override + final String source = 'premium'; + + /// User that boosted the chat + User user; + + /// Basic constructor + ChatBoostSourcePremium({ + required this.user, + }); + + /// Creates a object from a json + factory ChatBoostSourcePremium.fromJson(Map json) { + return ChatBoostSourcePremium(user: User.fromJson(json['user'])); + } + + /// Creates a json from the object + Map toJson() { + return { + 'source': source, + 'user': user, + }; + } + + @override + String toString() => toJson().toString(); +} diff --git a/lib/src/entities/telegram/chat_boost_updated.dart b/lib/src/entities/telegram/chat_boost_updated.dart new file mode 100644 index 0000000..a836c0f --- /dev/null +++ b/lib/src/entities/telegram/chat_boost_updated.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// This object represents a boost added to a chat or changed. +class ChatBoostUpdated { + /// Chat which was boosted + Chat chat; + + /// Information about the chat boost + ChatBoost boost; + + /// Basic constructor + ChatBoostUpdated({ + required this.chat, + required this.boost, + }); + + /// Creates a object from a json + factory ChatBoostUpdated.fromJson(Map json) { + return ChatBoostUpdated( + chat: Chat.fromJson(json['chat']), + boost: ChatBoost.fromJson(json['boost']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'chat': chat, + 'boost': boost, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/update.dart b/lib/src/entities/telegram/update.dart index 5b29827..dcf1a32 100644 --- a/lib/src/entities/telegram/update.dart +++ b/lib/src/entities/telegram/update.dart @@ -85,6 +85,16 @@ class Update { /// receive these updates. ChatJoinRequest? chatJoinRequest; + /// Optional. + /// A chat boost was added or changed. + /// The bot must be an administrator in the chat to receive these updates. + ChatBoost? chatBoost; + + /// Optional. + /// A boost was removed from a chat. + /// The bot must be an administrator in the chat to receive these updates. + ChatBoostRemoved? removedChatBoost; + /// Basic constructor Update({ required this.updateId, @@ -102,6 +112,8 @@ class Update { this.myChatMember, this.chatMember, this.chatJoinRequest, + this.chatBoost, + this.removedChatBoost, }); /// Creates a object from a json @@ -164,6 +176,14 @@ class Update { ChatJoinRequest.fromJson, json['chat_join_request'], ), + chatBoost: callIfNotNull( + ChatBoost.fromJson, + json['chat_boost'], + ), + removedChatBoost: callIfNotNull( + ChatBoostRemoved.fromJson, + json['removed_chat_boost'], + ), ); } @@ -190,6 +210,8 @@ class Update { 'my_chat_member': myChatMember, 'chat_member': chatMember, 'chat_join_request': chatJoinRequest, + 'chat_boost': chatBoost, + 'removed_chat_boost': removedChatBoost, }..removeWhere((_, v) => v == null); } diff --git a/lib/src/entities/telegram/user_chat_boosts.dart b/lib/src/entities/telegram/user_chat_boosts.dart new file mode 100644 index 0000000..9f846b4 --- /dev/null +++ b/lib/src/entities/telegram/user_chat_boosts.dart @@ -0,0 +1,31 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// This object represents a list of boosts added to a chat by a user. +class UserChatBoosts { + /// The list of boosts added to the chat by the user + List boosts; + + /// Basic constructor + UserChatBoosts({ + required this.boosts, + }); + + /// Creates a object from a json + factory UserChatBoosts.fromJson(Map json) { + return UserChatBoosts( + boosts: ChatBoost.listFromJsonArray(json['boosts']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'boosts': boosts, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index 855498f..ab955c5 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -19,6 +19,13 @@ export 'src/entities/telegram/callback_game.dart'; export 'src/entities/telegram/callback_query.dart'; export 'src/entities/telegram/chat.dart'; export 'src/entities/telegram/chat_administrator_rights.dart'; +export 'src/entities/telegram/chat_boost.dart'; +export 'src/entities/telegram/chat_boost_removed.dart'; +export 'src/entities/telegram/chat_boost_source.dart'; +export 'src/entities/telegram/chat_boost_source_gift_code.dart'; +export 'src/entities/telegram/chat_boost_source_giveaway.dart'; +export 'src/entities/telegram/chat_boost_source_premium.dart'; +export 'src/entities/telegram/chat_boost_updated.dart'; export 'src/entities/telegram/chat_invite_link.dart'; export 'src/entities/telegram/chat_join_request.dart'; export 'src/entities/telegram/chat_location.dart'; @@ -135,6 +142,7 @@ export 'src/entities/telegram/successful_payment.dart'; export 'src/entities/telegram/switch_inline_query_chosen_chat.dart'; export 'src/entities/telegram/update.dart'; export 'src/entities/telegram/user.dart'; +export 'src/entities/telegram/user_chat_boosts.dart'; export 'src/entities/telegram/user_profile_photos.dart'; export 'src/entities/telegram/user_shared.dart'; export 'src/entities/telegram/venue.dart'; From e34a3dcabbdc08bc7a0cd0a0b02fa67fcfbd8512 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Wed, 10 Apr 2024 01:01:54 +0200 Subject: [PATCH 10/12] Added "Request for multiple users" content --- .../entities/telegram/keyboard_button.dart | 32 ++++---- ...art => keyboard_button_request_users.dart} | 19 +++-- lib/src/entities/telegram/message.dart | 14 ++-- lib/src/entities/telegram/shared_user.dart | 73 +++++++++++++++++++ lib/src/entities/telegram/user_shared.dart | 43 ----------- lib/src/entities/telegram/users_shared.dart | 38 ++++++++++ lib/telegram_entities.dart | 5 +- 7 files changed, 154 insertions(+), 70 deletions(-) rename lib/src/entities/telegram/{keyboard_button_request_user.dart => keyboard_button_request_users.dart} (71%) create mode 100644 lib/src/entities/telegram/shared_user.dart delete mode 100644 lib/src/entities/telegram/user_shared.dart create mode 100644 lib/src/entities/telegram/users_shared.dart diff --git a/lib/src/entities/telegram/keyboard_button.dart b/lib/src/entities/telegram/keyboard_button.dart index b0f1b2d..0264010 100644 --- a/lib/src/entities/telegram/keyboard_button.dart +++ b/lib/src/entities/telegram/keyboard_button.dart @@ -9,8 +9,9 @@ import '../internal/helpers/util.dart'; /// Optional fields web_app, request_contact, request_location, and request_poll /// are mutually exclusive. class KeyboardButton { - /// Text of the button. If none of the optional fields are used, - /// it will be sent as a message when the button is pressed + /// Text of the button. + /// If none of the optional fields are used, it will be sent as a message + /// when the button is pressed String text; /// Optional. @@ -18,27 +19,31 @@ class KeyboardButton { /// Tapping on any user will send their identifier to the bot in a /// โ€œuser_sharedโ€ service message. /// Available in private chats only. - KeyboardButtonRequestUser? requestUser; + KeyboardButtonRequestUsers? requestUsers; /// Optional. /// If specified, pressing the button will open a list of suitable chats. /// Tapping on a chat will send its identifier to the bot in a โ€œchat_sharedโ€ - /// service message. Available in private chats only. + /// service message. + /// Available in private chats only. KeyboardButtonRequestChat? requestChat; /// Optional. /// If True, the user's phone number will be sent as a contact when the button - /// is pressed. Available in private chats only. + /// is pressed. + /// Available in private chats only. bool? requestContact; /// Optional. /// If True, the user's current location will be sent when the button is - /// pressed. Available in private chats only. + /// pressed. + /// Available in private chats only. bool? requestLocation; /// Optional. /// If specified, the user will be asked to create a poll and send it to the - /// bot when the button is pressed. Available in private chats only. + /// bot when the button is pressed. + /// Available in private chats only. KeyboardButtonPollType? requestPoll; /// Optional. @@ -48,9 +53,10 @@ class KeyboardButton { /// Available in private chats only. WebAppInfo? webApp; + /// Basic constructor KeyboardButton._({ required this.text, - this.requestUser, + this.requestUsers, this.requestChat, this.requestContact, this.requestLocation, @@ -62,7 +68,7 @@ class KeyboardButton { KeyboardButton.text(this.text); /// RequestUser constructor - KeyboardButton.requestUser(this.text, {this.requestUser}); + KeyboardButton.requestUsers(this.text, {this.requestUsers}); /// RequestChat constructor KeyboardButton.requestChat(this.text, {this.requestChat}); @@ -83,9 +89,9 @@ class KeyboardButton { factory KeyboardButton.fromJson(Map json) { return KeyboardButton._( text: json['text']!, - requestUser: callIfNotNull( - KeyboardButtonRequestUser.fromJson, - json['request_user'], + requestUsers: callIfNotNull( + KeyboardButtonRequestUsers.fromJson, + json['request_users'], ), requestChat: callIfNotNull( KeyboardButtonRequestChat.fromJson, @@ -129,7 +135,7 @@ class KeyboardButton { Map toJson() { return { 'text': text, - 'request_user': requestUser, + 'request_users': requestUsers, 'request_chat': requestChat, 'request_contact': requestContact, 'request_location': requestLocation, diff --git a/lib/src/entities/telegram/keyboard_button_request_user.dart b/lib/src/entities/telegram/keyboard_button_request_users.dart similarity index 71% rename from lib/src/entities/telegram/keyboard_button_request_user.dart rename to lib/src/entities/telegram/keyboard_button_request_users.dart index 3941a16..5291b51 100644 --- a/lib/src/entities/telegram/keyboard_button_request_user.dart +++ b/lib/src/entities/telegram/keyboard_button_request_users.dart @@ -3,7 +3,7 @@ import 'dart:convert'; /// This object defines the criteria used to request a suitable user. /// The identifier of the selected user will be shared with the bot when the /// corresponding button is pressed. -class KeyboardButtonRequestUser { +class KeyboardButtonRequestUsers { /// Signed 32-bit identifier of the request, which will be received back in /// the UserShared object. /// Must be unique within the message @@ -16,22 +16,30 @@ class KeyboardButtonRequestUser { /// Optional. /// Pass True to request a premium user, pass False to request a non-premium - /// user. If not specified, no additional restrictions are applied. + /// user. + /// If not specified, no additional restrictions are applied. bool? userIsPremium; + /// Optional. + /// The maximum number of users to be selected; 1-10. + /// Defaults to 1. + int? maxQuantity; + /// Basic constructor - KeyboardButtonRequestUser( + KeyboardButtonRequestUsers( this.requestId, { this.userIsBot, this.userIsPremium, + this.maxQuantity, }); /// Creates a object from a json - factory KeyboardButtonRequestUser.fromJson(Map json) { - return KeyboardButtonRequestUser( + factory KeyboardButtonRequestUsers.fromJson(Map json) { + return KeyboardButtonRequestUsers( json['request_id'], userIsBot: json['user_is_bot'], userIsPremium: json['user_is_premium'], + maxQuantity: json['max_quantity'], ); } @@ -41,6 +49,7 @@ class KeyboardButtonRequestUser { 'request_id': requestId, 'user_is_bot': userIsBot, 'user_is_premium': userIsPremium, + 'max_quantity': maxQuantity, }..removeWhere((_, v) => v == null); } diff --git a/lib/src/entities/telegram/message.dart b/lib/src/entities/telegram/message.dart index 83d86a1..8807519 100644 --- a/lib/src/entities/telegram/message.dart +++ b/lib/src/entities/telegram/message.dart @@ -271,8 +271,8 @@ class Message extends MaybeInaccessibleMessage { SuccessfulPayment? successfulPayment; /// Optional. - /// Service message: a user was shared with the bot - UserShared? userShared; + /// Service message: users were shared with the bot + UsersShared? usersShared; /// Optional. /// Service message: a chat was shared with the bot @@ -418,7 +418,7 @@ class Message extends MaybeInaccessibleMessage { this.pinnedMessage, this.invoice, this.successfulPayment, - this.userShared, + this.usersShared, this.chatShared, this.connectedWebsite, this.passportData, @@ -531,9 +531,9 @@ class Message extends MaybeInaccessibleMessage { SuccessfulPayment.fromJson, json['successful_payment'], ), - userShared: callIfNotNull( - UserShared.fromJson, - json['user_shared'], + usersShared: callIfNotNull( + UsersShared.fromJson, + json['users_shared'], ), chatShared: callIfNotNull( ChatShared.fromJson, @@ -677,7 +677,7 @@ class Message extends MaybeInaccessibleMessage { 'pinned_message': pinnedMessage, 'invoice': invoice, 'successful_payment': successfulPayment, - 'user_shared': userShared, + 'users_shared': usersShared, 'chat_shared': chatShared, 'connected_website': connectedWebsite, 'passport_data': passportData, diff --git a/lib/src/entities/telegram/shared_user.dart b/lib/src/entities/telegram/shared_user.dart new file mode 100644 index 0000000..e8004f4 --- /dev/null +++ b/lib/src/entities/telegram/shared_user.dart @@ -0,0 +1,73 @@ +import 'dart:convert'; + +import 'package:dart_telegram_bot/src/entities/internal/helpers/util.dart'; +import 'package:dart_telegram_bot/telegram_entities.dart'; + +/// This object contains information about a user that was shared with the bot +/// using a KeyboardButtonRequestUser button. +class SharedUser { + /// Identifier of the shared user. + /// This number may have more than 32 significant bits and some programming + /// languages may have difficulty/silent defects in interpreting it. + /// But it has at most 52 significant bits, so 64-bit integers or + /// double-precision float types are safe for storing these identifiers. + /// The bot may not have access to the user and could be unable to use this + /// identifier, unless the user is already known to the bot by some other + /// means. + int userId; + + /// Optional. + /// First name of the user, if the name was requested by the bot + String? firstName; + + /// Optional. + /// Last name of the user, if the name was requested by the bot + String? lastName; + + /// Optional. + /// Username of the user, if the username was requested by the bot + String? username; + + /// Optional. + /// Available sizes of the chat photo, if the photo was requested by the bot + List? photo; + + /// Basic constructor + SharedUser({ + required this.userId, + this.firstName, + this.lastName, + this.username, + this.photo, + }); + + /// Creates a object from a json + factory SharedUser.fromJson(Map json) { + return SharedUser( + userId: json['user_id'], + firstName: json['first_name'], + lastName: json['last_name'], + username: json['username'], + photo: callIfNotNull(PhotoSize.listFromJsonArray, json['photo']), + ); + } + + /// Creates a list of object from a json array + static List listFromJsonArray(List json) { + return List.generate(json.length, (i) => SharedUser.fromJson(json[i])); + } + + /// Creates a json from the object + Map toJson() { + return { + 'user_id': userId, + 'first_name': firstName, + 'last_name': lastName, + 'username': username, + 'photo': photo, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/user_shared.dart b/lib/src/entities/telegram/user_shared.dart deleted file mode 100644 index 6aa9f2d..0000000 --- a/lib/src/entities/telegram/user_shared.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'dart:convert'; - -/// This object contains information about the user whose identifier was shared -/// with the bot using a KeyboardButtonRequestUser button. -class UserShared { - /// Identifier of the request - int requestId; - - /// Identifier of the shared user. - /// This number may have more than 32 significant bits and some programming - /// languages may have difficulty/silent defects in interpreting it. - /// But it has at most 52 significant bits, so a 64-bit integer or - /// double-precision float type are safe for storing this identifier. - /// The bot may not have access to the user and could be unable to use this - /// identifier, unless the user is already known to the bot by some - /// other means. - int userId; - - /// Basic constructor - UserShared( - this.requestId, - this.userId, - ); - - /// Creates a object from a json - factory UserShared.fromJson(Map json) { - return UserShared( - json['request_id'], - json['user_id'], - ); - } - - /// Creates a json from the object - Map toJson() { - return { - 'request_id': requestId, - 'user_id': userId, - }..removeWhere((_, v) => v == null); - } - - @override - String toString() => json.encode(this); -} diff --git a/lib/src/entities/telegram/users_shared.dart b/lib/src/entities/telegram/users_shared.dart new file mode 100644 index 0000000..bc1c628 --- /dev/null +++ b/lib/src/entities/telegram/users_shared.dart @@ -0,0 +1,38 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// This object contains information about the users whose identifiers were +/// shared with the bot using a KeyboardButtonRequestUsers button. +class UsersShared { + /// Identifier of the request + int requestId; + + /// Information about users shared with the bot. + List users; + + /// Basic constructor + UsersShared({ + required this.requestId, + required this.users, + }); + + /// Creates a object from a json + factory UsersShared.fromJson(Map json) { + return UsersShared( + requestId: json['request_id'], + users: SharedUser.listFromJsonArray(json['users']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'request_id': requestId, + 'users': users, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index ab955c5..f85d239 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -98,7 +98,7 @@ export 'src/entities/telegram/invoice.dart'; export 'src/entities/telegram/keyboard_button.dart'; export 'src/entities/telegram/keyboard_button_poll_type.dart'; export 'src/entities/telegram/keyboard_button_request_chat.dart'; -export 'src/entities/telegram/keyboard_button_request_user.dart'; +export 'src/entities/telegram/keyboard_button_request_users.dart'; export 'src/entities/telegram/labeled_price.dart'; export 'src/entities/telegram/link_preview_options.dart'; export 'src/entities/telegram/location.dart'; @@ -132,6 +132,7 @@ export 'src/entities/telegram/reply_keyboard_remove.dart'; export 'src/entities/telegram/reply_markup.dart'; export 'src/entities/telegram/response_parameters.dart'; export 'src/entities/telegram/sent_web_app_message.dart'; +export 'src/entities/telegram/shared_user.dart'; export 'src/entities/telegram/shipping_address.dart'; export 'src/entities/telegram/shipping_option.dart'; export 'src/entities/telegram/shipping_query.dart'; @@ -144,7 +145,7 @@ export 'src/entities/telegram/update.dart'; export 'src/entities/telegram/user.dart'; export 'src/entities/telegram/user_chat_boosts.dart'; export 'src/entities/telegram/user_profile_photos.dart'; -export 'src/entities/telegram/user_shared.dart'; +export 'src/entities/telegram/users_shared.dart'; export 'src/entities/telegram/venue.dart'; export 'src/entities/telegram/video.dart'; export 'src/entities/telegram/video_chat_ended.dart'; From 161d5286f716bbfb78adc2a6b32b77123ca15f94 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Fri, 12 Apr 2024 02:14:42 +0200 Subject: [PATCH 11/12] Added "Replies 2.0" content, minor fixes --- example/bot_example.dart | 15 +- .../entities/internal/entities/chat_id.dart | 8 + lib/src/entities/internal/tgapi_client.dart | 2 +- lib/src/entities/internal/tgapi_methods.dart | 120 ++++------- .../telegram/chat_administrator_rights.dart | 52 ++--- .../telegram/chat_boost_source_gift_code.dart | 2 +- .../telegram/chat_boost_source_giveaway.dart | 6 +- .../telegram/external_reply_info.dart | 198 ++++++++++++++++++ .../entities/telegram/giveaway_completed.dart | 2 +- .../keyboard_button_request_chat.dart | 6 +- lib/src/entities/telegram/message.dart | 72 +++---- lib/src/entities/telegram/poll_answer.dart | 3 +- .../entities/telegram/reply_parameters.dart | 92 ++++++++ lib/src/entities/telegram/shared_user.dart | 4 +- lib/src/entities/telegram/text_quote.dart | 61 ++++++ lib/telegram_entities.dart | 3 + test/main_test.dart | 16 +- 17 files changed, 484 insertions(+), 178 deletions(-) create mode 100644 lib/src/entities/telegram/external_reply_info.dart create mode 100644 lib/src/entities/telegram/reply_parameters.dart create mode 100644 lib/src/entities/telegram/text_quote.dart diff --git a/example/bot_example.dart b/example/bot_example.dart index 6133698..69aa270 100644 --- a/example/bot_example.dart +++ b/example/bot_example.dart @@ -74,7 +74,7 @@ void main(List arguments) async { ChatID(update.message!.chat.id), 'Nani desu ka?', ['Hai!', 'Ara ara?', '!'], - replyToMessageId: update.message!.messageId, + replyParameters: ReplyParameters(update.message!.messageId), allowsMultipleAnswers: true, isAnonymous: true, type: 'quiz', @@ -136,7 +136,6 @@ Future _onUpdate(Bot bot, Update update) async { // Those will be converted into tests if (update.message == null) return; - if (update.editedMessage != null) return; // Ignore edited messages var chatId = ChatID(update.message!.chat.id); print('$chatId - ${update.message!.messageId}'); @@ -221,11 +220,13 @@ Future _onUpdate(Bot bot, Update update) async { ); } - if (update.message!.forwardFrom != null) { - var user = update.message!.forwardFrom!; - var resp = 'Forwarded from ${user.firstName} ' - '(${user.id} / @${user.username})'; - return bot.sendMessage(chatId, resp); + if (update.message!.forwardOrigin != null) { + var forwardOrigin = update.message!.forwardOrigin!; + if (forwardOrigin is MessageOriginUser) { + var resp = 'Forwarded from ${forwardOrigin.senderUser.firstName} ' + '(${forwardOrigin.senderUser.id} / @${forwardOrigin.senderUser.username})'; + return bot.sendMessage(chatId, resp); + } } if (update.message!.videoNote != null) { diff --git a/lib/src/entities/internal/entities/chat_id.dart b/lib/src/entities/internal/entities/chat_id.dart index e70184f..a335718 100644 --- a/lib/src/entities/internal/entities/chat_id.dart +++ b/lib/src/entities/internal/entities/chat_id.dart @@ -16,6 +16,14 @@ class ChatID { return ChatID._internal(chatUsername: username); } + factory ChatID.fromJson(Map json) { + if (int.tryParse(json['chat_id']) == null) { + return ChatID.fromUsername(json['chat_id']); + } else { + return ChatID(int.parse(json['chat_id'])); + } + } + @override String toString() => (chatId ?? chatUsername)!.toString(); } diff --git a/lib/src/entities/internal/tgapi_client.dart b/lib/src/entities/internal/tgapi_client.dart index be5e79d..ef67820 100644 --- a/lib/src/entities/internal/tgapi_client.dart +++ b/lib/src/entities/internal/tgapi_client.dart @@ -15,7 +15,7 @@ class TGAPIClient { static final log = Logger('TGAPIClient'); /// Telegram API BaseUrl - static final baseUrl = 'api.telegram.org'; + static const baseUrl = 'api.telegram.org'; static final _listTypeFactories = )>{ 'List': Update.listFromJsonArray, diff --git a/lib/src/entities/internal/tgapi_methods.dart b/lib/src/entities/internal/tgapi_methods.dart index 82ee329..410a2d4 100644 --- a/lib/src/entities/internal/tgapi_methods.dart +++ b/lib/src/entities/internal/tgapi_methods.dart @@ -51,8 +51,7 @@ mixin TGAPIMethods { LinkPreviewOptions? linkPreviewOptions, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendMessage', { @@ -64,8 +63,7 @@ mixin TGAPIMethods { 'link_preview_options': linkPreviewOptions, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -138,8 +136,7 @@ mixin TGAPIMethods { List? captionEntities, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'copyMessage', { @@ -152,8 +149,7 @@ mixin TGAPIMethods { 'caption_entities': captionEntities, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -208,8 +204,7 @@ mixin TGAPIMethods { bool? hasSpoiler, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendPhoto', { @@ -222,8 +217,7 @@ mixin TGAPIMethods { 'has_spoiler': hasSpoiler, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -252,8 +246,7 @@ mixin TGAPIMethods { HttpFile? thumbnail, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendAudio', { @@ -269,8 +262,7 @@ mixin TGAPIMethods { 'thumbnail': thumbnail, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -291,8 +283,7 @@ mixin TGAPIMethods { List? captionEntities, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, bool? disableContentTypeDetection, }) { @@ -306,8 +297,7 @@ mixin TGAPIMethods { 'thumbnail': thumbnail, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, 'disable_content_type_detection': disableContentTypeDetection, }); @@ -336,8 +326,7 @@ mixin TGAPIMethods { bool? supportsStreaming, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendVideo', { @@ -355,8 +344,7 @@ mixin TGAPIMethods { 'supports_streaming': supportsStreaming, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -381,8 +369,7 @@ mixin TGAPIMethods { bool? hasSpoiler, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendAnimation', { @@ -399,8 +386,7 @@ mixin TGAPIMethods { 'has_spoiler': hasSpoiler, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -426,8 +412,7 @@ mixin TGAPIMethods { int? duration, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendVoice', { @@ -440,8 +425,7 @@ mixin TGAPIMethods { 'duration': duration, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -458,8 +442,7 @@ mixin TGAPIMethods { HttpFile? thumbnail, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendVideoNote', { @@ -471,8 +454,7 @@ mixin TGAPIMethods { 'thumbnail': thumbnail, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -490,8 +472,7 @@ mixin TGAPIMethods { int? messageThreadId, bool? disableNotification, bool? protectContent, - bool? allowSendingWithoutReply, - int? replyToMessageId, + ReplyParameters? replyParameters, }) { return _client.apiCall(_token, 'sendMediaGroup', { 'chat_id': chatId, @@ -499,8 +480,7 @@ mixin TGAPIMethods { 'message_thread_id': messageThreadId, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'allow_sending_without_reply': allowSendingWithoutReply, - 'reply_to_message_id': replyToMessageId, + 'reply_parameters': replyParameters, }); } @@ -518,8 +498,7 @@ mixin TGAPIMethods { int? proximityAlertRadius, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendLocation', { @@ -533,8 +512,7 @@ mixin TGAPIMethods { 'proximity_alert_radius': proximityAlertRadius, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -639,8 +617,7 @@ mixin TGAPIMethods { String? googlePlaceType, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendVenue', { @@ -656,8 +633,7 @@ mixin TGAPIMethods { 'google_place_type': googlePlaceType, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -674,8 +650,7 @@ mixin TGAPIMethods { String? vcard, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendContact', { @@ -687,8 +662,7 @@ mixin TGAPIMethods { 'vcard': vcard, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -713,8 +687,7 @@ mixin TGAPIMethods { bool? isClosed, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendPoll', { @@ -734,8 +707,7 @@ mixin TGAPIMethods { 'is_closed': isClosed, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -750,8 +722,7 @@ mixin TGAPIMethods { Emoji? emoji, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendDice', { @@ -760,8 +731,7 @@ mixin TGAPIMethods { 'emoji': emoji, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -1922,8 +1892,7 @@ mixin TGAPIMethods { String? emoji, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, ReplyMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendSticker', { @@ -1933,8 +1902,7 @@ mixin TGAPIMethods { 'emoji': emoji, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -2190,8 +2158,7 @@ mixin TGAPIMethods { bool? isFlexible, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, InlineKeyboardMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendInvoice', { @@ -2218,8 +2185,7 @@ mixin TGAPIMethods { 'is_flexible': isFlexible, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } @@ -2282,10 +2248,10 @@ mixin TGAPIMethods { /// On success, True is returned. Future answerShippingQuery( String shippingQueryId, - bool ok, List? shippingOptions, - String errorMessage, - ) { + String errorMessage, { + required bool ok, + }) { return _client.apiCall(_token, 'answerShippingQuery', { 'shipping_query_id': shippingQueryId, 'ok': ok, @@ -2306,9 +2272,9 @@ mixin TGAPIMethods { /// pre-checkout query was sent. Future answerPreCheckoutQuery( String preCheckoutQueryId, - bool ok, - String errorMessage, - ) { + String errorMessage, { + required bool ok, + }) { return _client.apiCall(_token, 'answerPreCheckoutQuery', { 'pre_checkout_query_id': preCheckoutQueryId, 'ok': ok, @@ -2325,8 +2291,7 @@ mixin TGAPIMethods { int? messageThreadId, bool? disableNotification, bool? protectContent, - int? replyToMessageId, - bool? allowSendingWithoutReply, + ReplyParameters? replyParameters, InlineKeyboardMarkup? replyMarkup, }) { return _client.apiCall(_token, 'sendGame', { @@ -2335,8 +2300,7 @@ mixin TGAPIMethods { 'message_thread_id': messageThreadId, 'disable_notification': disableNotification, 'protect_content': protectContent, - 'reply_to_message_id': replyToMessageId, - 'allow_sending_without_reply': allowSendingWithoutReply, + 'reply_parameters': replyParameters, 'reply_markup': replyMarkup, }); } diff --git a/lib/src/entities/telegram/chat_administrator_rights.dart b/lib/src/entities/telegram/chat_administrator_rights.dart index 0309109..a4ff856 100644 --- a/lib/src/entities/telegram/chat_administrator_rights.dart +++ b/lib/src/entities/telegram/chat_administrator_rights.dart @@ -64,15 +64,15 @@ class ChatAdministratorRights { bool? canManageTopics; /// Basic constructor - ChatAdministratorRights( - this.isAnonymous, - this.canManageChat, - this.canDeleteMessages, - this.canManageVideoChats, - this.canRestrictMembers, - this.canPromoteMembers, - this.canChangeInfo, - this.canInviteUsers, + ChatAdministratorRights({ + required this.isAnonymous, + required this.canManageChat, + required this.canDeleteMessages, + required this.canManageVideoChats, + required this.canRestrictMembers, + required this.canPromoteMembers, + required this.canChangeInfo, + required this.canInviteUsers, this.canPostMessages, this.canEditMessages, this.canPinMessages, @@ -80,26 +80,26 @@ class ChatAdministratorRights { this.canEditStories, this.canDeleteStories, this.canManageTopics, - ); + }); /// Creates a object from a json factory ChatAdministratorRights.fromJson(Map json) { return ChatAdministratorRights( - json['is_anonymous'], - json['can_manage_chat'], - json['can_delete_messages'], - json['can_manage_video_chats'], - json['can_restrict_members'], - json['can_promote_members'], - json['can_change_info'], - json['can_invite_users'], - json['can_post_messages'], - json['can_edit_messages'], - json['can_pin_messages'], - json['can_post_stories'], - json['can_edit_stories'], - json['can_delete_stories'], - json['can_manage_topics'], + isAnonymous: json['is_anonymous'], + canManageChat: json['can_manage_chat'], + canDeleteMessages: json['can_delete_messages'], + canManageVideoChats: json['can_manage_video_chats'], + canRestrictMembers: json['can_restrict_members'], + canPromoteMembers: json['can_promote_members'], + canChangeInfo: json['can_change_info'], + canInviteUsers: json['can_invite_users'], + canPostMessages: json['can_post_messages'], + canEditMessages: json['can_edit_messages'], + canPinMessages: json['can_pin_messages'], + canPostStories: json['can_post_stories'], + canEditStories: json['can_edit_stories'], + canDeleteStories: json['can_delete_stories'], + canManageTopics: json['can_manage_topics'], ); } @@ -121,6 +121,6 @@ class ChatAdministratorRights { 'can_edit_stories': canEditStories, 'can_delete_stories': canDeleteStories, 'can_manage_topics': canManageTopics, - }; + }..removeWhere((_, v) => v == null); } } diff --git a/lib/src/entities/telegram/chat_boost_source_gift_code.dart b/lib/src/entities/telegram/chat_boost_source_gift_code.dart index 7f657f8..0b74483 100644 --- a/lib/src/entities/telegram/chat_boost_source_gift_code.dart +++ b/lib/src/entities/telegram/chat_boost_source_gift_code.dart @@ -1,4 +1,4 @@ -import 'package:dart_telegram_bot/telegram_entities.dart'; +import '../../../telegram_entities.dart'; /// The boost was obtained by the creation of Telegram Premium gift codes /// to boost a chat. diff --git a/lib/src/entities/telegram/chat_boost_source_giveaway.dart b/lib/src/entities/telegram/chat_boost_source_giveaway.dart index 118bad3..d8807e0 100644 --- a/lib/src/entities/telegram/chat_boost_source_giveaway.dart +++ b/lib/src/entities/telegram/chat_boost_source_giveaway.dart @@ -1,6 +1,5 @@ -import 'package:dart_telegram_bot/src/entities/internal/helpers/util.dart'; - import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; /// The boost was obtained by the creation of a Telegram Premium giveaway. /// This boosts the chat 4 times for the duration of the corresponding @@ -20,7 +19,8 @@ class ChatBoostSourceGiveaway extends ChatBoostSource { User? user; /// Optional. - /// True, if the giveaway was completed, but there was no user to win the prize + /// True, if the giveaway was completed, + /// but there was no user to win the prize bool? isUnclaimed; /// Basic constructor diff --git a/lib/src/entities/telegram/external_reply_info.dart b/lib/src/entities/telegram/external_reply_info.dart new file mode 100644 index 0000000..06f0f2b --- /dev/null +++ b/lib/src/entities/telegram/external_reply_info.dart @@ -0,0 +1,198 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; + +/// This object contains information about a message that is being replied to, +/// which may come from another chat or forum topic. +class ExternalReplyInfo { + /// Origin of the message replied to by the given message + MessageOrigin messageOrigin; + + /// Optional. + /// Chat the original message belongs to. + /// Available only if the chat is a supergroup or a channel. + Chat? chat; + + /// Optional. + /// Unique message identifier inside the original chat. + /// Available only if the original chat is a supergroup or a channel. + int? messageId; + + /// Optional. + /// Options used for link preview generation for the original message, + /// if it is a text message + LinkPreviewOptions? linkPreviewOptions; + + /// Optional. + /// Message is an animation, information about the animation + Animation? animation; + + /// Optional. + /// Message is an audio file, information about the file + Audio? audio; + + /// Optional. + /// Message is a general file, information about the file + Document? document; + + /// Optional. + /// Message is a photo, available sizes of the photo + List? photo; + + /// Optional. + /// Message is a sticker, information about the sticker + Sticker? sticker; + + /// Optional. + /// Message is a forwarded story + Story? story; + + /// Optional. + /// Message is a video, information about the video + Video? video; + + /// Optional. + /// Message is a video note, information about the video message + VideoNote? videoNote; + + /// Optional. + /// Message is a voice message, information about the file + Voice? voice; + + /// Optional. + /// True, if the message media is covered by a spoiler animation + bool? hasMediaSpoiler; + + /// Optional. + /// Message is a shared contact, information about the contact + Contact? contact; + + /// Optional. + /// Message is a dice with random value + Dice? dice; + + /// Optional. + /// Message is a game, information about the game. + Game? game; + + /// Optional. + /// Message is a scheduled giveaway, information about the giveaway + Giveaway? giveaway; + + /// Optional. + /// A giveaway with public winners was completed + GiveawayWinners? giveawayWinners; + + /// Optional. + /// Message is an invoice for a payment, information about the invoice. + Invoice? invoice; + + /// Optional. + /// Message is a shared location, information about the location + Location? location; + + /// Optional. + /// Message is a native poll, information about the poll + Poll? poll; + + /// Optional. + /// Message is a venue, information about the venue. + /// For backward compatibility, when this field is set, the location field + /// will also be set + Venue? venue; + + /// Basic constructor + ExternalReplyInfo( + this.messageOrigin, { + this.chat, + this.messageId, + this.linkPreviewOptions, + this.animation, + this.audio, + this.document, + this.photo, + this.sticker, + this.story, + this.video, + this.videoNote, + this.voice, + this.hasMediaSpoiler, + this.contact, + this.dice, + this.game, + this.giveaway, + this.giveawayWinners, + this.invoice, + this.location, + this.poll, + this.venue, + }); + + /// Creates a object from a json + factory ExternalReplyInfo.fromJson(Map json) { + return ExternalReplyInfo( + MessageOrigin.fromJson(json['origin']), + chat: callIfNotNull(Chat.fromJson, json['chat']), + messageId: json['message_id'], + linkPreviewOptions: callIfNotNull( + LinkPreviewOptions.fromJson, + json['link_preview_options'], + ), + animation: callIfNotNull(Animation.fromJson, json['animation']), + audio: callIfNotNull(Audio.fromJson, json['audio']), + document: callIfNotNull(Document.fromJson, json['document']), + photo: callIfNotNull(PhotoSize.listFromJsonArray, json['photo']), + sticker: callIfNotNull(Sticker.fromJson, json['sticker']), + story: callIfNotNull(Story.fromJson, json['story']), + video: callIfNotNull(Video.fromJson, json['video']), + videoNote: callIfNotNull(VideoNote.fromJson, json['video_note']), + voice: callIfNotNull(Voice.fromJson, json['voice']), + hasMediaSpoiler: json['has_media_spoiler'], + contact: callIfNotNull(Contact.fromJson, json['contact']), + dice: callIfNotNull(Dice.fromJson, json['dice']), + game: callIfNotNull(Game.fromJson, json['game']), + giveaway: callIfNotNull(Giveaway.fromJson, json['giveaway']), + giveawayWinners: callIfNotNull( + GiveawayWinners.fromJson, + json['giveaway_winners'], + ), + invoice: callIfNotNull(Invoice.fromJson, json['invoice']), + location: callIfNotNull(Location.fromJson, json['location']), + poll: callIfNotNull(Poll.fromJson, json['poll']), + venue: callIfNotNull(Venue.fromJson, json['venue']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'origin': messageOrigin, + 'chat': chat, + 'message_id': messageId, + 'link_preview_options': linkPreviewOptions, + 'animation': animation, + 'audio': audio, + 'document': document, + 'photo': photo, + 'sticker': sticker, + 'story': story, + 'video': video, + 'video_note': videoNote, + 'voice': voice, + 'has_media_spoiler': hasMediaSpoiler, + 'contact': contact, + 'dice': dice, + 'game': game, + 'giveaway': giveaway, + 'giveaway_winners': giveawayWinners, + 'invoice': invoice, + 'location': location, + 'poll': poll, + 'venue': venue, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/giveaway_completed.dart b/lib/src/entities/telegram/giveaway_completed.dart index a799f61..f12fe7b 100644 --- a/lib/src/entities/telegram/giveaway_completed.dart +++ b/lib/src/entities/telegram/giveaway_completed.dart @@ -1,7 +1,7 @@ import 'dart:convert'; -import 'package:dart_telegram_bot/src/entities/internal/helpers/util.dart'; import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; /// This object represents a service message about the completion of a /// giveaway without public winners. diff --git a/lib/src/entities/telegram/keyboard_button_request_chat.dart b/lib/src/entities/telegram/keyboard_button_request_chat.dart index 66755e7..03b036b 100644 --- a/lib/src/entities/telegram/keyboard_button_request_chat.dart +++ b/lib/src/entities/telegram/keyboard_button_request_chat.dart @@ -53,8 +53,8 @@ class KeyboardButtonRequestChat { /// Basic constructor KeyboardButtonRequestChat( - this.requestId, - this.chatIsChannel, { + this.requestId, { + required this.chatIsChannel, this.chatIsForum, this.chatHasUsername, this.chatIsCreated, @@ -67,7 +67,7 @@ class KeyboardButtonRequestChat { factory KeyboardButtonRequestChat.fromJson(Map json) { return KeyboardButtonRequestChat( json['request_id'], - json['chat_is_channel'], + chatIsChannel: json['chat_is_channel'], chatIsForum: json['chat_is_forum'], chatHasUsername: json['chat_has_username'], chatIsCreated: json['chat_is_created'], diff --git a/lib/src/entities/telegram/message.dart b/lib/src/entities/telegram/message.dart index 8807519..6a23259 100644 --- a/lib/src/entities/telegram/message.dart +++ b/lib/src/entities/telegram/message.dart @@ -38,32 +38,8 @@ class Message extends MaybeInaccessibleMessage { Chat chat; /// Optional. - /// For forwarded messages, sender of the original message - User? forwardFrom; - - /// Optional. - /// For messages forwarded from channels or from anonymous administrators, - /// information about the original sender chat - Chat? forwardFromChat; - - /// Optional. - /// For messages forwarded from channels, identifier of the original - /// message in the channel - int? forwardFromMessageId; - - /// Optional. - /// For forwarded messages that were originally sent in channels or by an - /// anonymous chat administrator, signature of the message sender if present - String? forwardSignature; - - /// Optional. - /// Sender's name for messages forwarded from users who disallow adding a - /// link to their account in forwarded messages - String? forwardSenderName; - - /// Optional. - /// For forwarded messages, date the original message was sent in Unix time - int? forwardDate; + /// Information about the original message for forwarded messages + MessageOrigin? forwardOrigin; /// Optional. /// True, if the message is sent to a forum topic @@ -80,6 +56,16 @@ class Message extends MaybeInaccessibleMessage { /// reply_to_message fields even if it itself is a reply. Message? replyToMessage; + /// Optional. + /// Information about the message that is being replied to, + /// which may come from another chat or forum topic + ExternalReplyInfo? externalReply; + + /// Optional. + /// For replies that quote part of the original message, + /// the quoted part of the message + TextQuote? quote; + /// Optional. /// Bot through which the message was sent User? viaBot; @@ -369,15 +355,12 @@ class Message extends MaybeInaccessibleMessage { this.senderChat, required this.date, required this.chat, - this.forwardFrom, - this.forwardFromChat, - this.forwardFromMessageId, - this.forwardSignature, - this.forwardSenderName, - this.forwardDate, + this.forwardOrigin, this.isTopicMessage, this.isAutomaticForward, this.replyToMessage, + this.externalReply, + this.quote, this.viaBot, this.editDate, this.hasProtectedContent, @@ -449,21 +432,21 @@ class Message extends MaybeInaccessibleMessage { senderChat: callIfNotNull(Chat.fromJson, json['sender_chat']), date: json['date']!, chat: Chat.fromJson(json['chat']!), - forwardFrom: callIfNotNull(User.fromJson, json['forward_from']), - forwardFromChat: callIfNotNull( - Chat.fromJson, - json['forward_from_chat'], + forwardOrigin: callIfNotNull( + MessageOrigin.fromJson, + json['forward_origin'], ), - forwardFromMessageId: json['forward_from_message_id'], - forwardSignature: json['forward_signature'], - forwardSenderName: json['forward_sender_name'], - forwardDate: json['forward_date'], isTopicMessage: json['is_topic_message'], isAutomaticForward: json['is_automatic_forward'], replyToMessage: callIfNotNull( Message.fromJson, json['reply_to_message'], ), + externalReply: callIfNotNull( + ExternalReplyInfo.fromJson, + json['external_reply'], + ), + quote: callIfNotNull(TextQuote.fromJson, json['quote']), viaBot: callIfNotNull(User.fromJson, json['via_bot']), editDate: json['edit_date'], hasProtectedContent: json['has_protected_content'], @@ -628,15 +611,12 @@ class Message extends MaybeInaccessibleMessage { 'sender_chat': senderChat, 'date': date, 'chat': chat, - 'forward_from': forwardFrom, - 'forward_from_chat': forwardFromChat, - 'forward_from_message_id': forwardFromMessageId, - 'forward_signature': forwardSignature, - 'forward_sender_name': forwardSenderName, - 'forward_date': forwardDate, + 'forward_origin': forwardOrigin, 'is_topic_message': isTopicMessage, 'is_automatic_forward': isAutomaticForward, 'reply_to_message': replyToMessage, + 'external_reply': externalReply, + 'quote': quote, 'via_bot': viaBot, 'edit_date': editDate, 'has_protected_content': hasProtectedContent, diff --git a/lib/src/entities/telegram/poll_answer.dart b/lib/src/entities/telegram/poll_answer.dart index d1a8830..727c957 100644 --- a/lib/src/entities/telegram/poll_answer.dart +++ b/lib/src/entities/telegram/poll_answer.dart @@ -1,8 +1,7 @@ import 'dart:convert'; -import 'package:dart_telegram_bot/src/entities/internal/helpers/util.dart'; - import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; /// This object represents an answer of a user in a non-anonymous poll. class PollAnswer { diff --git a/lib/src/entities/telegram/reply_parameters.dart b/lib/src/entities/telegram/reply_parameters.dart new file mode 100644 index 0000000..0c6d8b0 --- /dev/null +++ b/lib/src/entities/telegram/reply_parameters.dart @@ -0,0 +1,92 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; + +/// Describes reply parameters for the message that is being sent. +class ReplyParameters { + /// Identifier of the message that will be replied to in the current chat, + /// or in the chat chat_id if it is specified + int messageId; + + /// Optional. + /// If the message to be replied to is from a different chat, unique + /// identifier for the chat or username of the channel + /// (in the format @channelusername). + /// Not supported for messages sent on behalf of a business account. + ChatID? chatId; + + /// Optional. + /// Pass True if the message should be sent even if the specified message to + /// be replied to is not found. + /// Always False for replies in another chat or forum topic. + /// Always True for messages sent on behalf of a business account. + bool? allowSendingWithoutReply; + + /// Optional. + /// Quoted part of the message to be replied to; + /// 0-1024 characters after entities parsing. + /// The quote must be an exact substring of the message to be replied to, + /// including bold, italic, underline, strikethrough, spoiler, + /// and custom_emoji entities. + /// The message will fail to send if the quote isn't found in the + /// original message. + String? quote; + + /// Optional. + /// Mode for parsing entities in the quote. + /// See formatting options for more details. + String? quoteParseMode; + + /// Optional. + /// A JSON-serialized list of special entities that appear in the quote. + /// It can be specified instead of quote_parse_mode. + List? quoteEntities; + + /// Optional. + /// Position of the quote in the original message in UTF-16 code units + int? quotePosition; + + /// Basic constructor + ReplyParameters( + this.messageId, { + this.chatId, + this.allowSendingWithoutReply, + this.quote, + this.quoteParseMode, + this.quoteEntities, + this.quotePosition, + }); + + /// Creates a object from a json + factory ReplyParameters.fromJson(Map json) { + return ReplyParameters( + json['message_id'], + chatId: callIfNotNull(ChatID.fromJson, json['chat_id']), + allowSendingWithoutReply: json['allow_sending_without_reply'], + quote: json['quote'], + quoteParseMode: json['quote_parse_mode'], + quoteEntities: callIfNotNull( + MessageEntity.listFromJsonArray, + json['quote_entities'], + ), + quotePosition: json['quote_position'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'message_id': messageId, + 'chat_id': chatId, + 'allow_sending_without_reply': allowSendingWithoutReply, + 'quote': quote, + 'quote_parse_mode': quoteParseMode, + 'quote_entities': quoteEntities, + 'quote_position': quotePosition, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/shared_user.dart b/lib/src/entities/telegram/shared_user.dart index e8004f4..d1d98f3 100644 --- a/lib/src/entities/telegram/shared_user.dart +++ b/lib/src/entities/telegram/shared_user.dart @@ -1,7 +1,7 @@ import 'dart:convert'; -import 'package:dart_telegram_bot/src/entities/internal/helpers/util.dart'; -import 'package:dart_telegram_bot/telegram_entities.dart'; +import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; /// This object contains information about a user that was shared with the bot /// using a KeyboardButtonRequestUser button. diff --git a/lib/src/entities/telegram/text_quote.dart b/lib/src/entities/telegram/text_quote.dart new file mode 100644 index 0000000..457d878 --- /dev/null +++ b/lib/src/entities/telegram/text_quote.dart @@ -0,0 +1,61 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; + +/// This object contains information about the quoted part of a message that is +/// replied to by the given message. +class TextQuote { + /// Text of the quoted part of a message that is replied to + /// by the given message + String text; + + /// Optional. + /// Special entities that appear in the quote. Currently, only bold, italic, + /// underline, strikethrough, spoiler, and custom_emoji entities are kept + /// in quotes. + List? entities; + + /// Approximate quote position in the original message in UTF-16 code units + /// as specified by the sender + int position; + + /// Optional. + /// True, if the quote was chosen manually by the message sender. + /// Otherwise, the quote was added automatically by the server. + bool? isManual; + + /// Basic constructor + TextQuote({ + required this.text, + this.entities, + required this.position, + this.isManual, + }); + + /// Creates a object from a json + factory TextQuote.fromJson(Map json) { + return TextQuote( + text: json['text'], + entities: callIfNotNull( + MessageEntity.listFromJsonArray, + json['entities'], + ), + position: json['position'], + isManual: json['is_manual'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'text': text, + 'entities': entities?.map((e) => e.toJson()).toList(), + 'position': position, + 'is_manual': isManual, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index f85d239..6c88be9 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -41,6 +41,7 @@ export 'src/entities/telegram/document.dart'; export 'src/entities/telegram/encrypted_credentials.dart'; export 'src/entities/telegram/encrypted_passport_element.dart'; export 'src/entities/telegram/enums.dart'; +export 'src/entities/telegram/external_reply_info.dart'; export 'src/entities/telegram/file.dart'; export 'src/entities/telegram/force_reply.dart'; export 'src/entities/telegram/forum_topic.dart'; @@ -130,6 +131,7 @@ export 'src/entities/telegram/proximity_alert_triggered.dart'; export 'src/entities/telegram/reply_keyboard_markup.dart'; export 'src/entities/telegram/reply_keyboard_remove.dart'; export 'src/entities/telegram/reply_markup.dart'; +export 'src/entities/telegram/reply_parameters.dart'; export 'src/entities/telegram/response_parameters.dart'; export 'src/entities/telegram/sent_web_app_message.dart'; export 'src/entities/telegram/shared_user.dart'; @@ -141,6 +143,7 @@ export 'src/entities/telegram/sticker_set.dart'; export 'src/entities/telegram/story.dart'; export 'src/entities/telegram/successful_payment.dart'; export 'src/entities/telegram/switch_inline_query_chosen_chat.dart'; +export 'src/entities/telegram/text_quote.dart'; export 'src/entities/telegram/update.dart'; export 'src/entities/telegram/user.dart'; export 'src/entities/telegram/user_chat_boosts.dart'; diff --git a/test/main_test.dart b/test/main_test.dart index d68033d..3bd1f12 100644 --- a/test/main_test.dart +++ b/test/main_test.dart @@ -84,7 +84,7 @@ void main() { var message = await testBot.sendMessage( ChatID(chatId), '*Test*', - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), disableNotification: true, linkPreviewOptions: LinkPreviewOptions(isDisabled: true), parseMode: ParseMode.markdown, @@ -109,7 +109,7 @@ void main() { ), caption: '*Test*', parseMode: ParseMode.markdown, - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), disableNotification: true, ); expect(message.captionEntities!.length, equals(1)); @@ -150,7 +150,7 @@ void main() { title: 'Nya', // thumb: HttpFile.fromPath('resources/test.jpg'), disableNotification: true, - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), ); expect(message.captionEntities!.length, equals(1)); expect(message.captionEntities!.first.type, equals('bold')); @@ -190,7 +190,7 @@ void main() { caption: '*Test*', parseMode: ParseMode.markdown, disableNotification: true, - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), ); expect(message.captionEntities!.length, equals(1)); expect(message.captionEntities!.first.type, equals('bold')); @@ -227,7 +227,7 @@ void main() { caption: '*Test*', parseMode: ParseMode.markdown, disableNotification: true, - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), ); expect(message.captionEntities!.length, equals(1)); expect(message.captionEntities!.first.type, equals('bold')); @@ -267,7 +267,7 @@ void main() { caption: '*Test*', parseMode: ParseMode.markdown, disableNotification: true, - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), ); expect(message.captionEntities!.length, equals(1)); expect(message.captionEntities!.first.type, equals('bold')); @@ -307,7 +307,7 @@ void main() { duration: 1, parseMode: ParseMode.markdown, disableNotification: true, - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), ); expect(message.captionEntities!.length, equals(1)); expect(message.captionEntities!.first.type, equals('bold')); @@ -506,7 +506,7 @@ void main() { await testBot.sendMessage( ChatID(chatId), 'Remove', - replyToMessageId: replyId, + replyParameters: ReplyParameters(replyId), replyMarkup: ForceReply(selective: true), ); }, From 83ff92e380481317d781ad87e7ac7f5c8520ff92 Mon Sep 17 00:00:00 2001 From: KyouinDev Date: Fri, 12 Apr 2024 02:58:53 +0200 Subject: [PATCH 12/12] Added "Reactions" content --- CHANGELOG.md | 2 +- lib/src/entities/internal/tgapi_methods.dart | 26 +++++++ lib/src/entities/telegram/chat.dart | 12 ++++ lib/src/entities/telegram/enums.dart | 1 + .../message_reaction_count_updated.dart | 50 +++++++++++++ .../telegram/message_reaction_updated.dart | 72 +++++++++++++++++++ lib/src/entities/telegram/reaction_count.dart | 46 ++++++++++++ lib/src/entities/telegram/reaction_type.dart | 30 ++++++++ .../telegram/reaction_type_custom_emoji.dart | 37 ++++++++++ .../telegram/reaction_type_emoji.dart | 46 ++++++++++++ lib/src/entities/telegram/update.dart | 28 ++++++++ lib/telegram_entities.dart | 6 ++ 12 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 lib/src/entities/telegram/message_reaction_count_updated.dart create mode 100644 lib/src/entities/telegram/message_reaction_updated.dart create mode 100644 lib/src/entities/telegram/reaction_count.dart create mode 100644 lib/src/entities/telegram/reaction_type.dart create mode 100644 lib/src/entities/telegram/reaction_type_custom_emoji.dart create mode 100644 lib/src/entities/telegram/reaction_type_emoji.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 3deb448..e4c8e93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## 1.2.0 - Updated to bot API 7.0 -- Minor improvements +- Minor improvements and fixes ## 1.1.0 diff --git a/lib/src/entities/internal/tgapi_methods.dart b/lib/src/entities/internal/tgapi_methods.dart index 410a2d4..0053f98 100644 --- a/lib/src/entities/internal/tgapi_methods.dart +++ b/lib/src/entities/internal/tgapi_methods.dart @@ -760,6 +760,32 @@ mixin TGAPIMethods { ); } + /// 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 True on success. + Future setMessageReaction( + ChatID chatId, + int messageId, { + List? reaction, + bool? isBig, + }) { + return _client.apiCall( + _token, + 'setMessageReaction', + { + 'chat_id': chatId, + 'message_id': messageId, + 'reaction': reaction, + 'is_big': isBig, + }, + ); + } + /// Use this method to get a list of profile pictures for a user. /// /// Returns a [UserProfilePhotos] object. diff --git a/lib/src/entities/telegram/chat.dart b/lib/src/entities/telegram/chat.dart index 58f686b..8b1fe0c 100644 --- a/lib/src/entities/telegram/chat.dart +++ b/lib/src/entities/telegram/chat.dart @@ -45,6 +45,12 @@ class Chat { /// Returned only in getChat. List? activeUsernames; + /// Optional. + /// List of available reactions allowed in the chat. + /// If omitted, then all emoji reactions are allowed. + /// Returned only in getChat. + List? availableReactions; + /// Optional. /// Identifier of the accent color for the chat name and backgrounds of /// the chat photo, reply header, and link preview. @@ -202,6 +208,7 @@ class Chat { this.isForum, this.photo, this.activeUsernames, + this.availableReactions, this.accentColorId, this.backgroundCustomEmojiId, this.profileAccentColorId, @@ -241,6 +248,10 @@ class Chat { isForum: json['is_forum'], photo: callIfNotNull(ChatPhoto.fromJson, json['photo']), activeUsernames: List.from(json['active_usernames'] ?? []), + availableReactions: callIfNotNull( + ReactionType.listFromJsonArray, + json['available_reactions'], + ), accentColorId: json['accent_color_id'], backgroundCustomEmojiId: json['background_custom_emoji_id'], profileAccentColorId: json['profile_accent_color_id'], @@ -288,6 +299,7 @@ class Chat { 'is_forum': isForum, 'photo': photo, 'active_usernames': activeUsernames, + 'available_reactions': availableReactions, 'accent_color_id': accentColorId, 'background_custom_emoji_id': backgroundCustomEmojiId, 'profile_accent_color_id': profileAccentColorId, diff --git a/lib/src/entities/telegram/enums.dart b/lib/src/entities/telegram/enums.dart index a1f4a1b..92b8a7f 100644 --- a/lib/src/entities/telegram/enums.dart +++ b/lib/src/entities/telegram/enums.dart @@ -11,6 +11,7 @@ class _Enum { String toJson() => '$this'; } +//TODO: Update enum /// UpdateType for GetUpdates class UpdateType extends _Enum { /// Message diff --git a/lib/src/entities/telegram/message_reaction_count_updated.dart b/lib/src/entities/telegram/message_reaction_count_updated.dart new file mode 100644 index 0000000..cd5aef9 --- /dev/null +++ b/lib/src/entities/telegram/message_reaction_count_updated.dart @@ -0,0 +1,50 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// This object represents reaction changes on a message with anonymous +/// reactions. +class MessageReactionCountUpdated { + /// The chat containing the message + Chat chat; + + /// Unique message identifier inside the chat + int messageId; + + /// Date of the change in Unix time + int date; + + /// List of reactions that are present on the message + List reactions; + + /// Basic constructor + MessageReactionCountUpdated( + this.chat, + this.messageId, + this.date, + this.reactions, + ); + + /// Creates a object from a json + factory MessageReactionCountUpdated.fromJson(Map json) { + return MessageReactionCountUpdated( + Chat.fromJson(json['chat']), + json['message_id'], + json['date'], + ReactionCount.listFromJsonArray(json['reactions']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'chat': chat, + 'message_id': messageId, + 'date': date, + 'reactions': reactions, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/message_reaction_updated.dart b/lib/src/entities/telegram/message_reaction_updated.dart new file mode 100644 index 0000000..ab9cd56 --- /dev/null +++ b/lib/src/entities/telegram/message_reaction_updated.dart @@ -0,0 +1,72 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; +import '../internal/helpers/util.dart'; + +/// This object represents a change of a reaction on a message performed +/// by a user. +class MessageReactionUpdated { + /// The chat containing the message the user reacted to + Chat chat; + + /// Unique identifier of the message inside the chat + int messageId; + + /// Optional. + /// The user that changed the reaction, if the user isn't anonymous + User? user; + + /// Optional. + /// The chat on behalf of which the reaction was changed, + /// if the user is anonymous + Chat? actorChat; + + /// Date of the change in Unix time + int date; + + /// Previous list of reaction types that were set by the user + List oldReaction; + + /// New list of reaction types that have been set by the user + List newReaction; + + /// Basic constructor + MessageReactionUpdated({ + required this.chat, + required this.messageId, + this.user, + this.actorChat, + required this.date, + required this.oldReaction, + required this.newReaction, + }); + + /// Creates a object from a json + factory MessageReactionUpdated.fromJson(Map json) { + return MessageReactionUpdated( + chat: Chat.fromJson(json['chat']), + messageId: json['message_id'], + user: callIfNotNull(User.fromJson, json['user']), + actorChat: callIfNotNull(Chat.fromJson, json['actor_chat']), + date: json['date'], + oldReaction: ReactionType.listFromJsonArray(json['old_reaction']), + newReaction: ReactionType.listFromJsonArray(json['new_reaction']), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'chat': chat, + 'message_id': messageId, + 'user': user, + 'actor_chat': actorChat, + 'date': date, + 'old_reaction': oldReaction, + 'new_reaction': newReaction, + }..removeWhere((_, v) => v == null); + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/reaction_count.dart b/lib/src/entities/telegram/reaction_count.dart new file mode 100644 index 0000000..c59faa3 --- /dev/null +++ b/lib/src/entities/telegram/reaction_count.dart @@ -0,0 +1,46 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; + +/// Represents a reaction added to a message along with the number of times +/// it was added. +class ReactionCount { + /// Type of the reaction + ReactionType type; + + /// Number of times the reaction was added + int totalCount; + + /// Basic constructor + ReactionCount( + this.type, + this.totalCount, + ); + + /// Creates a object from a json + factory ReactionCount.fromJson(Map json) { + return ReactionCount( + ReactionType.fromJson(json['type']), + json['total_count'], + ); + } + + /// Creates a list of object from a json array + static List listFromJsonArray(List json) { + return List.generate( + json.length, + (i) => ReactionCount.fromJson(json[i]), + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'type': type, + 'total_count': totalCount, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/reaction_type.dart b/lib/src/entities/telegram/reaction_type.dart new file mode 100644 index 0000000..f21577e --- /dev/null +++ b/lib/src/entities/telegram/reaction_type.dart @@ -0,0 +1,30 @@ +import '../../../telegram_entities.dart'; + +/// This object describes the type of a reaction. +/// Currently, it can be one of: +/// It can be one of: +/// ReactionTypeEmoji, +/// ReactionTypeCustomEmoji +abstract class ReactionType { + abstract final String type; + + /// Creates a object from a json + static ReactionType fromJson(Map json) { + switch (json['type']) { + case 'emoji': + return ReactionTypeEmoji.fromJson(json); + case 'custom_emoji': + return ReactionTypeCustomEmoji.fromJson(json); + default: + throw Exception('ReactionType type not recognized'); + } + } + + /// Creates a list of object from a json array + static List listFromJsonArray(List json) { + return List.generate( + json.length, + (i) => ReactionType.fromJson(json[i]), + ); + } +} diff --git a/lib/src/entities/telegram/reaction_type_custom_emoji.dart b/lib/src/entities/telegram/reaction_type_custom_emoji.dart new file mode 100644 index 0000000..7e84a8b --- /dev/null +++ b/lib/src/entities/telegram/reaction_type_custom_emoji.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; +import 'reaction_type.dart'; + +/// The message was originally sent by an unknown user. +class ReactionTypeCustomEmoji extends ReactionType { + /// Type of the reaction, always โ€œcustom_emojiโ€ + @override + String type = 'custom_emoji'; + + /// Custom emoji identifier + String customEmojiId; + + /// Basic constructor + ReactionTypeCustomEmoji( + this.customEmojiId, + ); + + /// Creates a object from a json + factory ReactionTypeCustomEmoji.fromJson(Map json) { + return ReactionTypeCustomEmoji( + json['custom_emoji_id'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'type': type, + 'custom_emoji_id': customEmojiId, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/reaction_type_emoji.dart b/lib/src/entities/telegram/reaction_type_emoji.dart new file mode 100644 index 0000000..a1b3280 --- /dev/null +++ b/lib/src/entities/telegram/reaction_type_emoji.dart @@ -0,0 +1,46 @@ +import 'dart:convert'; + +import '../../../telegram_entities.dart'; +import 'reaction_type.dart'; + +/// The message was originally sent by an unknown user. +class ReactionTypeEmoji extends ReactionType { + /// Type of the reaction, always โ€œemojiโ€ + @override + String type = 'emoji'; + + //TODO: Create emoji enum + /// Reaction emoji. + /// Currently, it can be one of: + /// "๐Ÿ‘", "๐Ÿ‘Ž", "โค", "๐Ÿ”ฅ", "๐Ÿฅฐ", "๐Ÿ‘", "๐Ÿ˜","๐Ÿค”", "๐Ÿคฏ", "๐Ÿ˜ฑ", "๐Ÿคฌ", + /// "๐Ÿ˜ข", "๐ŸŽ‰", "๐Ÿคฉ", "๐Ÿคฎ", "๐Ÿ’ฉ", "๐Ÿ™", "๐Ÿ‘Œ", "๐Ÿ•Š", "๐Ÿคก", "๐Ÿฅฑ", "๐Ÿฅด", + /// "๐Ÿ˜", "๐Ÿณ", "โคโ€๐Ÿ”ฅ", "๐ŸŒš", "๐ŸŒญ", "๐Ÿ’ฏ", "๐Ÿคฃ", "โšก", "๐ŸŒ", "๐Ÿ†", "๐Ÿ’”", + /// "๐Ÿคจ", "๐Ÿ˜", "๐Ÿ“", "๐Ÿพ", "๐Ÿ’‹", "๐Ÿ–•", "๐Ÿ˜ˆ", "๐Ÿ˜ด", "๐Ÿ˜ญ", "๐Ÿค“", "๐Ÿ‘ป", + /// "๐Ÿ‘จโ€๐Ÿ’ป", "๐Ÿ‘€", "๐ŸŽƒ", "๐Ÿ™ˆ", "๐Ÿ˜‡", "๐Ÿ˜จ", "๐Ÿค", "โœ", "๐Ÿค—", "๐Ÿซก", "๐ŸŽ…", + /// "๐ŸŽ„", "โ˜ƒ", "๐Ÿ’…", "๐Ÿคช", "๐Ÿ—ฟ", "๐Ÿ†’", "๐Ÿ’˜", "๐Ÿ™‰", "๐Ÿฆ„", "๐Ÿ˜˜", "๐Ÿ’Š", + /// "๐Ÿ™Š", "๐Ÿ˜Ž", "๐Ÿ‘พ", "๐Ÿคทโ€โ™‚", "๐Ÿคท", "๐Ÿคทโ€โ™€", "๐Ÿ˜ก" + String emoji; + + /// Basic constructor + ReactionTypeEmoji( + this.emoji, + ); + + /// Creates a object from a json + factory ReactionTypeEmoji.fromJson(Map json) { + return ReactionTypeEmoji( + json['emoji'], + ); + } + + /// Creates a json from the object + Map toJson() { + return { + 'type': type, + 'emoji': emoji, + }; + } + + @override + String toString() => json.encode(this); +} diff --git a/lib/src/entities/telegram/update.dart b/lib/src/entities/telegram/update.dart index dcf1a32..836a126 100644 --- a/lib/src/entities/telegram/update.dart +++ b/lib/src/entities/telegram/update.dart @@ -33,6 +33,22 @@ class Update { /// New version of a channel post that is known to the bot and was edited Message? editedChannelPost; + /// Optional. + /// A reaction to a message was changed by a user. + /// The bot must be an administrator in the chat and must explicitly specify + /// "message_reaction" in the list of allowed_updates + /// to receive these updates. + /// The update isn't received for reactions set by bots. + MessageReactionUpdated? messageReaction; + + /// Optional. + /// Reactions to a message with anonymous reactions were changed. + /// The bot must be an administrator in the chat and must explicitly specify + /// "message_reaction_count" in the list of allowed_updates to receive these + /// updates. + /// The updates are grouped and can be sent with delay up to a few minutes. + MessageReactionCountUpdated? messageReactionCountUpdated; + /// Optional. /// New incoming inline query InlineQuery? inlineQuery; @@ -102,6 +118,8 @@ class Update { this.editedMessage, this.channelPost, this.editedChannelPost, + this.messageReaction, + this.messageReactionCountUpdated, this.inlineQuery, this.chosenInlineResult, this.callbackQuery, @@ -136,6 +154,14 @@ class Update { Message.fromJson, json['edited_channel_post'], ), + messageReaction: callIfNotNull( + MessageReactionUpdated.fromJson, + json['message_reaction'], + ), + messageReactionCountUpdated: callIfNotNull( + MessageReactionCountUpdated.fromJson, + json['message_reaction_count'], + ), inlineQuery: callIfNotNull( InlineQuery.fromJson, json['inline_query'], @@ -200,6 +226,8 @@ class Update { 'edited_message': editedMessage, 'channel_post': channelPost, 'edited_channel_post': editedChannelPost, + 'message_reaction': messageReaction, + 'message_reaction_count': messageReactionCountUpdated, 'inline_query': inlineQuery, 'chosen_inline_result': chosenInlineResult, 'callback_query': callbackQuery, diff --git a/lib/telegram_entities.dart b/lib/telegram_entities.dart index 6c88be9..7daf049 100644 --- a/lib/telegram_entities.dart +++ b/lib/telegram_entities.dart @@ -119,6 +119,8 @@ export 'src/entities/telegram/message_origin_channel.dart'; export 'src/entities/telegram/message_origin_chat.dart'; export 'src/entities/telegram/message_origin_hidden_user.dart'; export 'src/entities/telegram/message_origin_user.dart'; +export 'src/entities/telegram/message_reaction_count_updated.dart'; +export 'src/entities/telegram/message_reaction_updated.dart'; export 'src/entities/telegram/order_info.dart'; export 'src/entities/telegram/passport_data.dart'; export 'src/entities/telegram/passport_file.dart'; @@ -128,6 +130,10 @@ export 'src/entities/telegram/poll_answer.dart'; export 'src/entities/telegram/poll_option.dart'; export 'src/entities/telegram/pre_checkout_query.dart'; export 'src/entities/telegram/proximity_alert_triggered.dart'; +export 'src/entities/telegram/reaction_count.dart'; +export 'src/entities/telegram/reaction_type.dart'; +export 'src/entities/telegram/reaction_type_custom_emoji.dart'; +export 'src/entities/telegram/reaction_type_emoji.dart'; export 'src/entities/telegram/reply_keyboard_markup.dart'; export 'src/entities/telegram/reply_keyboard_remove.dart'; export 'src/entities/telegram/reply_markup.dart';