Merge branch 'master' into example/composite-state

This commit is contained in:
Tima Kinsart 2024-08-28 18:42:33 -04:00 committed by GitHub
commit 294f3f5447
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
149 changed files with 6276 additions and 1847 deletions

View file

@ -3,7 +3,7 @@ name: Feature request
about: Suggest an idea for this project
title: 'Feature Request: <feature>'
labels: K-feature-request
assignees: Hirrolot, WaffleLapkin
assignees: Hirrolot
---

View file

@ -3,7 +3,6 @@ name: Parse error
about: Report issue with `teloxide` parsing of telegram response
title: 'Parse Error: <type or error description>'
labels: K-bug, FIXME, C-core
assignees: WaffleLapkin
---

View file

@ -27,7 +27,7 @@ env:
# - down below in a matrix
# - `Cargo.toml`
# - **/CHANGELOG.md
rust_msrv: 1.70.0
rust_msrv: 1.80.0
CI: 1
@ -108,7 +108,7 @@ jobs:
toolchain: nightly-2024-07-03
features: "--features full nightly"
- rust: msrv
toolchain: 1.70.0
toolchain: 1.80.0
features: "--features full"
steps:
@ -138,8 +138,6 @@ jobs:
- name: Downgrade deps for MSRV
if: ${{ matrix.rust == 'msrv' }}
run: |
cargo update -p sqlx --precise 0.7.3
cargo update -p atomic-write-file --precise 0.1.2
exit 0

View file

@ -8,10 +8,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add `filter_boost_added` and `filter_reply_to_story` filters to `MessageFilterExt` trait
- Add `filter_mention_command` filter to `HandlerExt` trait ([issue #494](https://github.com/teloxide/teloxide/issues/494))
- Add `filter_business_connection`, `filter_business_message`, `filter_edited_business_message`, and `filter_deleted_business_messages` filters to update filters ([PR 1146](https://github.com/teloxide/teloxide/pull/1146))
### Changed
- Environment bumps: ([#1147][pr1147])
- MSRV (Minimal Supported Rust Version) was bumped from `1.70.0` to `1.80.0`
- Some dependencies was bumped: `sqlx` to `0.8.1`, `tower` to `0.5.0`, `reqwest` to `0.12.7`
- `tokio` version was explicitly specified as `1.39`
[pr1147]: https://github.com/teloxide/teloxide/pull/1147
## 0.13.0 - 2024-08-16
### Added
- Documentation regarding the way captions work for the official clients on `SendMediaGroup` ([PR 992](https://github.com/teloxide/teloxide/pull/992))
- Add `MessageToCopyNotFound` error to `teloxide::errors::ApiError` ([PR 917](https://github.com/teloxide/teloxide/pull/917))
- Add `MessageToCopyNotFound` error to `teloxide::errors::ApiError` ([PR 917](https://github.com/teloxide/teloxide/pull/917))
- `Dispatcher::try_dispatch_with_listener` ([PR 913](https://github.com/teloxide/teloxide/pull/913))
- Missing Message::filter_* functions ([PR 982](https://github.com/teloxide/teloxide/pull/982)):
- Missing Message::filter_* functions ([PR 982](https://github.com/teloxide/teloxide/pull/982)):
- `filter_game`
- `filter_venue`
- `filter_video`
@ -43,12 +60,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `filter_video_chat_started`
- `filter_video_chat_ended`
- `filter_video_chat_participants_invited`
- `filter_web_app_data`
- `filter_web_app_data`
- Implement `PostgresStorage`, a persistent dialogue storage based on [PostgreSQL](https://www.postgresql.org/)([PR 996](https://github.com/teloxide/teloxide/pull/996)).
- Implement `GetChatId` for `teloxide_core::types::{Chat, ChatJoinRequest, ChatMemberUpdated}`.
- Use [deadpool-redis](https://crates.io/crates/deadpool-redis) for Redis connection pooling ([PR 1081](https://github.com/teloxide/teloxide/pull/1081)).
- Add `MessageExt::filter_story` method for the corresponding `MediaKind::Story` variant ([PR 1087](https://github.com/teloxide/teloxide/pull/1087)).
- Add `update_listeners::webhooks::Options::path`, an option to make the webhook server listen on a different path, which can be useful behind a reverse proxy.
- Add `filter_giveaway`, `filter_giveaway_completed`, `filter_giveaway_created` and `filter_giveaway_winners` filters to `MessageFilterExt` trait ([PR 1101](https://github.com/teloxide/teloxide/pull/1101))
- Add `teloxide::utils::command::BotCommands` to the `prelude` ([PR 1123](https://github.com/teloxide/teloxide/pull/1123))
### Fixed
@ -70,6 +88,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- MSRV (Minimal Supported Rust Version) was bumped from `1.68.0` to `1.70.0` ([PR 996][https://github.com/teloxide/teloxide/pull/996])
- `axum` was bumped to `0.7`, along with related libraries used for webhooks ([PR 1093][https://github.com/teloxide/teloxide/pull/1093])
- `Polling`'s exponential backoff now results in 64 seconds maximum delay instead of 17 minutes ([PR 1113][https://github.com/teloxide/teloxide/pull/1113])
- `filter_forward_from` was renamed to `filter_forward_origin` and now returns `MessageOrigin` instead of `ForwardFrom` ([PR 1101](https://github.com/teloxide/teloxide/pull/1101))
### Removed

817
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ resolver = "2"
# The settings below will be applied to all crates in the workspace
[workspace.package]
# MSRV (minimal supported Rust version).
rust-version = "1.70"
rust-version = "1.80"
edition = "2021"
license = "MIT"

View file

@ -1,5 +1,3 @@
> [v0.11 -> v0.12 migration guide >>](MIGRATION_GUIDE.md#011---012)
<div align="center">
<img src="./media/teloxide-logo.png" width="250"/>
<h1><code>teloxide</code></h1>
@ -13,7 +11,7 @@
<img src="https://img.shields.io/crates/v/teloxide.svg">
</a>
<a href="https://core.telegram.org/bots/api">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%206.9%20(inclusively)-green.svg">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%207.2%20(inclusively)-green.svg">
</a>
<a href="https://t.me/teloxide">
<img src="https://img.shields.io/badge/support-t.me%2Fteloxide-blueviolet">
@ -58,7 +56,7 @@ $ set TELOXIDE_TOKEN=<Your token here>
$ $env:TELOXIDE_TOKEN=<Your token here>
```
4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.70):
4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.80):
```bash
# If you're using stable
$ rustup update stable
@ -72,9 +70,9 @@ $ rustup override set nightly
5. Run `cargo new my_bot`, enter the directory and put these lines into your `Cargo.toml`:
```toml
[dependencies]
teloxide = { version = "0.12", features = ["macros"] }
teloxide = { version = "0.13", features = ["macros"] }
log = "0.4"
pretty_env_logger = "0.4"
pretty_env_logger = "0.5"
tokio = { version = "1.8", features = ["rt-multi-thread", "macros"] }
```
@ -356,7 +354,7 @@ Feel free to propose your own bot to our collection!
</details>
See [1600+ other public repositories using `teloxide` >>](https://github.com/teloxide/teloxide/network/dependents)
See [1900+ other public repositories using `teloxide` >>](https://github.com/teloxide/teloxide/network/dependents)
## Contributing

View file

@ -9,6 +9,80 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Support for TBA 7.1 ([#1131](pr1131))
- Updated docs for `can_post_stories`, `can_edit_stories` and `can_delete_stories` admin privileges
- Add `ChatBoostAdded` and `StoryId` structs
- Add `ChatBoostAdded` variant to `MessageKind` enum
- Add `sender_boost_count` and `reply_to_story` fields to `MessageCommon` struct
- Add `chat` and `id` fields to `Story` struct
- Add `unrestrict_boost_count` and `custom_emoji_sticker_set_name` fields to `PublicChatSupergroup` struct
- Add `boost_added` and `reply_to_story` getters to `Message` struct
- Add `unrestrict_boost_count` and `custom_emoji_sticker_set_name` getters to `Chat` struct
- Support for TBA 7.2 ([#1146](pr1146))
- Update documentation of `SendSticker` method
- Add `is_from_offline` field to `MessageCommon` struct
- Add `can_connect_to_business` field to `Me` struct
- Add `personal_chat` field to `ChatPrivate` struct
- Add `ReplaceStickerInSet` and `GetBusinessConnection` methods
- Add `Birthdate` struct and corresponding field `birthdate` in `ChatPrivate`
- Add `request_name`, `request_username` and `request_photo` fields to `KeyboardButtonRequestUsers` struct
- Add `request_title`, `request_username` and `request_photo` fields to `KeyboardButtonRequestChat` struct
- Add `SharedUser` struct
- Add `title`, `username` and `photo` fields to `ChatShared` struct
- Add `format` field to `InputSticker` struct
- Add `format` parameter to `SetStickerSetThumbnail` method
- Add `BusinessConnectionId` struct
- Add `business_connection_id` parameter to `SendMessage`, `SendPhoto`, `SendVideo`, `SendAnimation`, `SendAudio`, `SendDocument`, `SendSticker`, `SendVideoNote`, `SendVoice`, `SendLocation`, `SendVenue`, `SendContact`, `SendPoll`, `SendDice`, `SendGame`, and `SendMediaGroup` methods
- Add `sender_business_bot` and `business_connection_id` fields to `Message` struct
- Add `BusinessIntro` struct and corresponding field `business_intro` to `ChatPrivate` struct
- Add `BusinessLocation` struct and corresponding field `business_location` to `ChatPrivate` struct
- Add `BusinessOpeningHoursInterval` and `BusinessOpeningHours` structs and corresponding field `business_opening_hours` to `ChatPrivate` struct
- Add `BusinessConnection` struct
- Add `BusinessMessagesDeleted` struct
- Add `BusinessConnection`, `BusinessMessage`, `EditedBusinessMessage` and `DeletedBusinessMessages` variants to `UpdateKind` enum
### Changed
- `MaybeAnonymousUser` type introduced, which replaced `PollAnswer::voter: Voter` and `MessageReactionUpdated::{user, actor_chat}` in `MessageReactionUpdated`([#1134][pr1134])
- Environment bumps: ([#1147][pr1147])
- MSRV (Minimal Supported Rust Version) was bumped from `1.70.0` to `1.80.0`
- Some dependencies was bumped: `reqwest` to `0.12.7` and `ron` to `0.8.1`
- `tokio` version was explicitly specified as `1.39` and feature `io-util` was enabled for it
- `[u8; 3]` sometimes used for RGB values was replaced with dedicated `Rgb` struct: ([#1151][pr1151])
- `serde_rgb` module from `types.rs` file was removed
- `CreateForumTopic`, `ForumTopicCreated` and `ForumTopic` structs now use `Rgb` instead of `[u8; 3]` for `icon_color` field
- Added `rgb` crate dependency to Cargo.toml
- Added `Rgb` struct with `From` implementation for `RGB8` type from popular `rgb` crate
- Support for TBA 7.2 ([#1146](pr1146))
- Remove `flags` field from `StickerSet` struct
- Remove `sticker_format` parameter from `CreateNewStickerSet` method
- Wrap `Public` variant of `ChatKind` in `Box`
- Replaced `user_ids` with `users` in `UsersShared` struct
[pr1131]: https://github.com/teloxide/teloxide/pull/1131
[pr1134]: https://github.com/teloxide/teloxide/pull/1134
[pr1146]: https://github.com/teloxide/teloxide/pull/1146
[pr1147]: https://github.com/teloxide/teloxide/pull/1147
[pr1151]: https://github.com/teloxide/teloxide/pull/1151
### Removed
- `Currency` enum removed, its usages replaced with `String`.
## 0.10.1 - 2024-08-17
### Fixed
- Issue, when using `ReplyParameters` and multipart-requests involving file-sending it failed with `unimplemented error` ([#1136][pr1136], issue [#1135][issue1135])
[pr1136]: https://github.com/teloxide/teloxide/pull/1136
[issue1135]: https://github.com/teloxide/teloxide/issues/1135
## 0.10.0 - 2024-08-16
### Added
- `ChatPermission::can_*` helper functions ([#851][pr851])
- `mentioned_users` functions for `CallbackQuery`, `Chat`, `ChatJoinRequest`, `ChatMemberUpdated`, `Game`, `Message`, `Poll`, `Update` which return all contained `User` instances ([#850][pr850])
- `Message::video_chat_participants_invited` ([#850][pr850])
@ -19,7 +93,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `ChatId::as_user` ([#905][pr905])
- Implement `PartialEq<ChatId> for UserId` and `PartialEq<UserId> for ChatId` ([#905][pr905])
- `ChatId::{MIN, MAX}` ([#905][pr905])
- Missing `Message` getters ([#982][pr982]):
- Missing `Message` getters ([#982][pr982]):
- `message_auto_delete_timer_changed`
- `write_access_allowed`
- `forum_topic_created`
@ -31,7 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `video_chat_scheduled`
- `video_chat_started`
- `video_chat_ended`
- `web_app_data`
- `web_app_data`
- `is_delete_chat_photo`, `is_group_chat_created`, `is_super_group_chat_created`, `is_channel_chat_created` functions to `Message` ([#982][pr982])
- Support for TBA 6.5 ([#954][pr954])
- Add `can_send_audios`, `can_send_documents`, `can_send_photos`, `can_send_videos`, `can_send_video_notes`, and `can_send_voice_notes` to `ChatPermissions` and `Restricted`
@ -43,7 +117,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `shared_chat` method to `Message`
- Add `KeyboardButtonRequestUser` and `UserShared` types
- Add `RequestUser` variant to `ButtonRequest`
- Add `UserShared` variant to `MessageKind`
- Add `UserShared` variant to `MessageKind`
- Add `shared_user` method to `Message`
- Support for TBA 6.6 ([#1040](pr1040))
- Add methods for working with bot's description:
@ -61,7 +135,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add parameter `emoji` to the `send_sticker` method to specify an emoji for just uploaded stickers
- Add support for the creation of custom emoji sticker sets in `create_new_sticker_set`
- Add parameter `needs_repainting` to the `create_new_sticker_set` methodto automatically change the color of emoji based on context (e.g., use text color in messages, accent color in statuses, etc.)
- Add field `needs_repainting` to the `Sticker` struct
- Add field `needs_repainting` to the `Sticker` struct
- Add support for the creation of sticker sets with multiple initial stickers in `create_new_sticker_set` by replacing the parameters `sticker`, `emojis` and `mask_position` with the parameters `stickers` and `sticker_format`.
- Add support for .WEBP files in `create_new_sticker_set` and `add_sticker_to_set`
- Add support for .WEBP, .TGS, and .WEBM files in `upload_sticker_file` by replacing the parameter `png_sticker` with the parameters `sticker` and `sticker_format`
@ -88,6 +162,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for TBA 6.9 ([#1095](pr1095))
- Add `can_post_stories`, `can_edit_stories` and `can_delete_stories` fields to `ChatMemberKind::Administrator`, `ChatAdministratorRights` and `PromoteChatMember`
- Add `from_request` and `from_attachment_menu` fields to `WriteAccessAllowed`
- Support for TBA 7.0 ([#1101](pr1101))
- Reactions:
- Add `ReactionType` enum
- Add `MessageReactionUpdated` and `MessageReactionCountUpdated` structs
- Add `MessageReaction` and `MessageReactionCount` variants to `UpdateKind` enum
- Add `filter_message_reaction_updated` and `filter_message_reaction_count_updated` filters to `UpdateFilterExt` trait
- Add `set_message_reaction` TBA method to `Requester` trait
- Add `available_reactions` field to `Chat` struct
- Replies 2.0
- Add the fields `MessageCommon::{external_reply, quote}` of types `ExternalReplyInfo` and `TextQuote` respectively
- Link Preview Customization
- `disable_web_page_preview` replaced with `link_preview_options`:
- Remove `disable_web_page_preview` field from `send_message` and `send_message` TBA methods and `InputMessageContentText` struct
- Add `LinkPreviewOptions` struct
- Add `link_preview_options` field to `InputMessageContentText` and `Message` structs
- Add `link_preview_options` field to `send_message` and `send_message` TBA methods
- Multiple Message Actions
- Add TBA methods `delete_messages`, `forward_messages` and `copy_messages` to `Requester` trait
- Chat Boost
- Add `ChatBoostSource` enum
- Add `ChatBoost`, `ChatBoostUpdated`, `ChatBoostRemoved` and `UserChatBoosts` structs
- Add `ChatBoost` and `RemovedChatBoost` variants to `UpdateKind` enum
- Add `filter_chat_boost` and `filter_removed_chat_boost` filters to `UpdateFilterExt` trait
- Add `get_user_chat_boosts` TBA method to `Requester` trait
- Giveaway:
- Add `Giveaway`, `GiveawayCreated`, `GiveawayWinners` and `GiveawayCompleted` structs
- Add `Giveaway`, `GiveawayCreated`, `GiveawayWinners` and `GiveawayCompleted` variants to `MessageKind` enum
- Add `giveaway`, `giveaway_created`, `giveaway_winners` and `giveaway_completed` getters to `Message`
- Other Changes
- Add fields `ChafFullInfo::{has_visible_history, accent_color_id, background_custom_emoji_id, profile_accent_color_id, profile_background_custom_emoji_id}`
- Add `RequestId` type
- Add `CallbackQuery::regular_message` getter
[pr851]: https://github.com/teloxide/teloxide/pull/851
[pr887]: https://github.com/teloxide/teloxide/pull/887
@ -97,6 +203,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[pr1086]: https://github.com/teloxide/teloxide/pull/1086
[pr1087]: https://github.com/teloxide/teloxide/pull/1087
[pr1095]: https://github.com/teloxide/teloxide/pull/1095
[pr1101]: https://github.com/teloxide/teloxide/pull/1101
### Fixed
@ -108,6 +215,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Deserialization of empty (content-less) messages that can sometimes appear as a part of callback query ([#850][pr850], issue [#873][issue873])
- Type of `chat_id` in `send_game`: `u32` => `ChatId` ([#1066][pr1066])
- `Requester::Err` was bounded to the `AsResponseParameters`. In case of `RetryAfter(..)` errors the polling is paused for the specified delay instead of falling into the backoff strategy ([#1113][pr1113])
- `SendPoll` documentation ([#1101][pr1101], issue [#1058][issue1058])
- `from`, `sender_chat` and `is_topic_message` are moved into the `Message` from the `MessageCommon` ([#1101][pr1101], issue [#945][issue945]). Initially [#946][pr946]
- Add support for `blockquote` entity in received messages + in `MarkdownV2` and `HTML` ([#1101][pr1101], issue [#1062][issue1062])
[pr839]: https://github.com/teloxide/teloxide/pull/839
[pr879]: https://github.com/teloxide/teloxide/pull/879
@ -131,7 +241,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `InlineQueryResultLocation::live_period`
- `Location::live_period`
- `MessageAutoDeleteTimerChanged::message_auto_delete_time`
- `Poll::open_period`
- `Poll::open_period`
- `Video::duration`
- `VideoNote::duration`
- `Voice::duration`
@ -169,6 +279,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Method `set_sticker_set_thumb` and it's parameter `thumb` have been renamed to `set_sticker_set_thumbnail` and `thumbnail` respectively
- Fields `{InlineQueryResultArticle, InlineQueryResultContact, InlineQueryResultDocument, InlineQueryResultLocation, InlineQueryResultVenue}::{thumb_url, thumb_width, thumb_height}` have been renamed to `{thumbnail_url, thumbnail_width, thumbnail_height}` respectively
- Field `{InlineQueryResultPhoto, InlineQueryResultVideo, InlineQueryResultGif, InlineQueryResultMpeg4Gif}::thumb_url` has been renamed to `thumbnail_url`
- Support for TBA 7.0 ([#1101](pr1101))
- Replies 2.0
- Parameter `reply_parameters` of type `ReplyParameters` replaces parameters `reply_to_message_id` and `allow_sending_without_reply` in the methods:
- `copy_message`
- `send_message`
- `send_photo`
- `send_video`
- `send_animation`
- `send_audio`
- `send_document`
- `send_sticker`
- `send_video_note`
- `send_voice`
- `send_location`
- `send_venue`
- `send_contact`
- `send_poll`
- `send_dice`
- `send_invoice`
- `send_game`
- `send_media_group`
- Request for multiple users
- Struct `KeyboardButtonRequestUser` was renamed to `KeyboardButtonRequestUsers` + added field `max_quantity` to it
- Field `KeyboardButton::request_user` was renamed to `request_users`
- `MessageUserShared` was renamed to `MessageUsersShared`
- Other Changes
- `Message::pinned_message` and `CallbackQuery::message` now have `MaybeInaccessibleMessage` type
- Field `emoji_status_custom_emoji_id` is allowed in non-private chats (moved to the `ChatFullInfo`)
- Struct `Forward` was replaced by `MessageOrigin` in `MessageCommon`
- `RequestId` replaces `i32` in `ChatShared` and `KeyboardButtonRequestChat` structs
[pr852]: https://github.com/teloxide/teloxide/pull/853
[pr859]: https://github.com/teloxide/teloxide/pull/859
@ -182,8 +323,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Deprecated
- `Update::user`, use `Update::from` instead ([#850][pr850])
- `Message::from()` and `Message::sender_chat()` in favour of fields with the same name([initially #946][pr946][#1101][pr1101])
[pr850]: https://github.com/teloxide/teloxide/pull/850
[pr946]: https://github.com/teloxide/teloxide/pull/946
### Removed
@ -209,7 +352,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## 0.9.1 - 2023-02-15
### Fixed
### Fixed
- `Update::user` now handles channel posts, chat member changes and chat join request updates correctly ([#835][pr835])
- In cases when `teloxide` can't deserialize an update, error now includes the full json value ([#826][pr826])

View file

@ -1,6 +1,6 @@
[package]
name = "teloxide-core"
version = "0.9.1"
version = "0.10.1"
description = "Core part of the `teloxide` library - telegram bot API client"
rust-version.workspace = true
@ -49,11 +49,11 @@ full = ["throttle", "trace_adaptor", "erased", "cache_me"]
[dependencies]
futures = "0.3.5"
tokio = { version = "1.12.0", features = ["fs"] }
tokio = { version = "1.39", features = ["fs", "io-util"] }
tokio-util = { version = "0.7.0", features = ["codec"] }
pin-project = "1.0.12"
bytes = "1.0.0"
reqwest = { version = "0.11.10", features = [
reqwest = { version = "0.12.7", features = [
"json",
"stream",
"multipart",
@ -76,12 +76,13 @@ rc-box = "1.1.1"
chrono = { version = "0.4.32", default-features = false }
either = "1.6.1"
bitflags = { version = "1.2" }
rgb = "0.8.48"
vecrem = { version = "0.1", optional = true }
[dev-dependencies]
pretty_env_logger = "0.4"
pretty_env_logger = "0.5"
tokio = { version = "1.8.0", features = [
"fs",
"macros",
@ -91,10 +92,11 @@ tokio = { version = "1.8.0", features = [
cool_asserts = "2.0.3"
xshell = "0.2"
ron = "0.7"
ron = "0.8.1"
indexmap = { version = "1.9", features = ["serde-1"] }
aho-corasick = "0.7"
itertools = "0.10"
pretty_assertions = "1.4.0"
[package.metadata.docs.rs]

View file

@ -12,7 +12,7 @@
<img src="https://img.shields.io/badge/license-MIT-blue.svg">
</a>
<a href="https://core.telegram.org/bots/api">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%206.9%20(inclusively)-green.svg">
<img src="https://img.shields.io/badge/API%20coverage-Up%20to%207.2%20(inclusively)-green.svg">
</a>
<a href="https://crates.io/crates/teloxide_core">
<img src="https://img.shields.io/crates/v/teloxide_core.svg">
@ -25,9 +25,9 @@
</div>
```toml
teloxide-core = "0.9"
teloxide-core = "0.10.1"
```
_Compiler support: requires rustc 1.68+_.
_Compiler support: requires rustc 1.80+_.
[`teloxide`]: https://docs.rs/teloxide
[Telegram Bot API]: https://core.telegram.org/bots/api

File diff suppressed because it is too large Load diff

View file

@ -94,7 +94,9 @@ where
delete_webhook,
get_webhook_info,
forward_message,
forward_messages,
copy_message,
copy_messages,
send_message,
send_photo,
send_audio,
@ -114,6 +116,7 @@ where
send_poll,
send_dice,
send_chat_action,
set_message_reaction,
get_user_profile_photos,
get_file,
kick_chat_member,
@ -158,7 +161,9 @@ where
unhide_general_forum_topic,
unpin_all_general_forum_topic_messages,
answer_callback_query,
get_user_chat_boosts,
set_my_commands,
get_business_connection,
get_my_commands,
set_my_name,
get_my_name,
@ -183,6 +188,7 @@ where
edit_message_reply_markup_inline,
stop_poll,
delete_message,
delete_messages,
send_sticker,
get_sticker_set,
get_custom_emoji_stickers,
@ -191,6 +197,7 @@ where
add_sticker_to_set,
set_sticker_position_in_set,
delete_sticker_from_set,
replace_sticker_in_set,
set_sticker_set_thumbnail,
set_custom_emoji_sticker_set_thumbnail,
set_sticker_set_title,

View file

@ -170,6 +170,9 @@ macro_rules! fwd_erased {
(@convert $m:ident, $arg:ident, emoji_list: $T:ty) => {
$arg.into_iter().collect()
};
(@convert $m:ident, $arg:ident, message_ids: $T:ty) => {
$arg.into_iter().collect()
};
(@convert $m:ident, $arg:ident, $arg_:ident : $T:ty) => {
$arg.into()
};
@ -190,7 +193,9 @@ where
delete_webhook,
get_webhook_info,
forward_message,
forward_messages,
copy_message,
copy_messages,
send_message,
send_photo,
send_audio,
@ -210,6 +215,7 @@ where
send_poll,
send_dice,
send_chat_action,
set_message_reaction,
get_user_profile_photos,
get_file,
kick_chat_member,
@ -254,7 +260,9 @@ where
unhide_general_forum_topic,
unpin_all_general_forum_topic_messages,
answer_callback_query,
get_user_chat_boosts,
set_my_commands,
get_business_connection,
get_my_commands,
set_my_name,
get_my_name,
@ -279,6 +287,7 @@ where
edit_message_reply_markup_inline,
stop_poll,
delete_message,
delete_messages,
send_sticker,
get_sticker_set,
get_custom_emoji_stickers,
@ -287,6 +296,7 @@ where
add_sticker_to_set,
set_sticker_position_in_set,
delete_sticker_from_set,
replace_sticker_in_set,
set_sticker_set_thumbnail,
set_custom_emoji_sticker_set_thumbnail,
set_sticker_set_title,
@ -341,6 +351,13 @@ trait ErasableRequester<'a> {
message_id: MessageId,
) -> ErasedRequest<'a, ForwardMessage, Self::Err>;
fn forward_messages(
&self,
chat_id: Recipient,
from_chat_id: Recipient,
message_ids: Vec<MessageId>,
) -> ErasedRequest<'a, ForwardMessages, Self::Err>;
fn copy_message(
&self,
chat_id: Recipient,
@ -348,6 +365,13 @@ trait ErasableRequester<'a> {
message_id: MessageId,
) -> ErasedRequest<'a, CopyMessage, Self::Err>;
fn copy_messages(
&self,
chat_id: Recipient,
from_chat_id: Recipient,
message_ids: Vec<MessageId>,
) -> ErasedRequest<'a, CopyMessages, Self::Err>;
fn send_photo(
&self,
chat_id: Recipient,
@ -460,6 +484,12 @@ trait ErasableRequester<'a> {
action: ChatAction,
) -> ErasedRequest<'a, SendChatAction, Self::Err>;
fn set_message_reaction(
&self,
chat_id: Recipient,
message_id: MessageId,
) -> ErasedRequest<'a, SetMessageReaction, Self::Err>;
fn get_user_profile_photos(
&self,
user_id: UserId,
@ -641,7 +671,7 @@ trait ErasableRequester<'a> {
&self,
chat_id: Recipient,
name: String,
icon_color: u32,
icon_color: Rgb,
icon_custom_emoji_id: String,
) -> ErasedRequest<'a, CreateForumTopic, Self::Err>;
@ -711,11 +741,22 @@ trait ErasableRequester<'a> {
callback_query_id: String,
) -> ErasedRequest<'a, AnswerCallbackQuery, Self::Err>;
fn get_user_chat_boosts(
&self,
chat_id: Recipient,
user_id: UserId,
) -> ErasedRequest<'a, GetUserChatBoosts, Self::Err>;
fn set_my_commands(
&self,
commands: Vec<BotCommand>,
) -> ErasedRequest<'a, SetMyCommands, Self::Err>;
fn get_business_connection(
&self,
business_connection_id: BusinessConnectionId,
) -> ErasedRequest<'a, GetBusinessConnection, Self::Err>;
fn get_my_commands(&self) -> ErasedRequest<'a, GetMyCommands, Self::Err>;
fn set_my_name(&self) -> ErasedRequest<'a, SetMyName, Self::Err>;
@ -816,6 +857,12 @@ trait ErasableRequester<'a> {
message_id: MessageId,
) -> ErasedRequest<'a, DeleteMessage, Self::Err>;
fn delete_messages(
&self,
chat_id: Recipient,
message_ids: Vec<MessageId>,
) -> ErasedRequest<'a, DeleteMessages, Self::Err>;
fn send_sticker(
&self,
chat_id: Recipient,
@ -842,7 +889,6 @@ trait ErasableRequester<'a> {
name: String,
title: String,
stickers: Vec<InputSticker>,
sticker_format: StickerFormat,
) -> ErasedRequest<'a, CreateNewStickerSet, Self::Err>;
fn add_sticker_to_set(
@ -863,10 +909,19 @@ trait ErasableRequester<'a> {
sticker: String,
) -> ErasedRequest<'a, DeleteStickerFromSet, Self::Err>;
fn replace_sticker_in_set(
&self,
user_id: UserId,
name: String,
old_sticker: String,
sticker: InputSticker,
) -> ErasedRequest<'a, ReplaceStickerInSet, Self::Err>;
fn set_sticker_set_thumbnail(
&self,
name: String,
user_id: UserId,
format: StickerFormat,
) -> ErasedRequest<'a, SetStickerSetThumbnail, Self::Err>;
fn set_custom_emoji_sticker_set_thumbnail(
@ -1019,6 +1074,15 @@ where
Requester::forward_message(self, chat_id, from_chat_id, message_id).erase()
}
fn forward_messages(
&self,
chat_id: Recipient,
from_chat_id: Recipient,
message_ids: Vec<MessageId>,
) -> ErasedRequest<'a, ForwardMessages, Self::Err> {
Requester::forward_messages(self, chat_id, from_chat_id, message_ids).erase()
}
fn copy_message(
&self,
chat_id: Recipient,
@ -1028,6 +1092,15 @@ where
Requester::copy_message(self, chat_id, from_chat_id, message_id).erase()
}
fn copy_messages(
&self,
chat_id: Recipient,
from_chat_id: Recipient,
message_ids: Vec<MessageId>,
) -> ErasedRequest<'a, CopyMessages, Self::Err> {
Requester::copy_messages(self, chat_id, from_chat_id, message_ids).erase()
}
fn send_photo(
&self,
chat_id: Recipient,
@ -1178,6 +1251,14 @@ where
Requester::send_chat_action(self, chat_id, action).erase()
}
fn set_message_reaction(
&self,
chat_id: Recipient,
message_id: MessageId,
) -> ErasedRequest<'a, SetMessageReaction, Self::Err> {
Requester::set_message_reaction(self, chat_id, message_id).erase()
}
fn get_user_profile_photos(
&self,
user_id: UserId,
@ -1425,7 +1506,7 @@ where
&self,
chat_id: Recipient,
name: String,
icon_color: u32,
icon_color: Rgb,
icon_custom_emoji_id: String,
) -> ErasedRequest<'a, CreateForumTopic, Self::Err> {
Requester::create_forum_topic(self, chat_id, name, icon_color, icon_custom_emoji_id).erase()
@ -1521,6 +1602,14 @@ where
Requester::answer_callback_query(self, callback_query_id).erase()
}
fn get_user_chat_boosts(
&self,
chat_id: Recipient,
user_id: UserId,
) -> ErasedRequest<'a, GetUserChatBoosts, Self::Err> {
Requester::get_user_chat_boosts(self, chat_id, user_id).erase()
}
fn set_my_commands(
&self,
commands: Vec<BotCommand>,
@ -1528,6 +1617,13 @@ where
Requester::set_my_commands(self, commands).erase()
}
fn get_business_connection(
&self,
business_connection_id: BusinessConnectionId,
) -> ErasedRequest<'a, GetBusinessConnection, Self::Err> {
Requester::get_business_connection(self, business_connection_id).erase()
}
fn get_my_commands(&self) -> ErasedRequest<'a, GetMyCommands, Self::Err> {
Requester::get_my_commands(self).erase()
}
@ -1676,6 +1772,14 @@ where
Requester::delete_message(self, chat_id, message_id).erase()
}
fn delete_messages(
&self,
chat_id: Recipient,
message_ids: Vec<MessageId>,
) -> ErasedRequest<'a, DeleteMessages, Self::Err> {
Requester::delete_messages(self, chat_id, message_ids).erase()
}
fn send_sticker(
&self,
chat_id: Recipient,
@ -1710,10 +1814,8 @@ where
name: String,
title: String,
stickers: Vec<InputSticker>,
sticker_format: StickerFormat,
) -> ErasedRequest<'a, CreateNewStickerSet, Self::Err> {
Requester::create_new_sticker_set(self, user_id, name, title, stickers, sticker_format)
.erase()
Requester::create_new_sticker_set(self, user_id, name, title, stickers).erase()
}
fn add_sticker_to_set(
@ -1740,12 +1842,23 @@ where
Requester::delete_sticker_from_set(self, sticker).erase()
}
fn replace_sticker_in_set(
&self,
user_id: UserId,
name: String,
old_sticker: String,
sticker: InputSticker,
) -> ErasedRequest<'a, ReplaceStickerInSet, Self::Err> {
Requester::replace_sticker_in_set(self, user_id, name, old_sticker, sticker).erase()
}
fn set_sticker_set_thumbnail(
&self,
name: String,
user_id: UserId,
format: StickerFormat,
) -> ErasedRequest<'a, SetStickerSetThumbnail, Self::Err> {
Requester::set_sticker_set_thumbnail(self, name, user_id).erase()
Requester::set_sticker_set_thumbnail(self, name, user_id, format).erase()
}
fn set_custom_emoji_sticker_set_thumbnail(

View file

@ -185,6 +185,8 @@ where
delete_webhook,
get_webhook_info,
forward_message,
forward_messages,
copy_messages,
send_video_note,
send_location,
edit_message_live_location,
@ -195,6 +197,7 @@ where
send_contact,
send_dice,
send_chat_action,
set_message_reaction,
get_user_profile_photos,
get_file,
kick_chat_member,
@ -239,7 +242,9 @@ where
unhide_general_forum_topic,
unpin_all_general_forum_topic_messages,
answer_callback_query,
get_user_chat_boosts,
set_my_commands,
get_business_connection,
get_my_commands,
set_my_name,
get_my_name,
@ -256,6 +261,7 @@ where
edit_message_reply_markup_inline,
stop_poll,
delete_message,
delete_messages,
send_sticker,
get_sticker_set,
get_custom_emoji_stickers,
@ -264,6 +270,7 @@ where
add_sticker_to_set,
set_sticker_position_in_set,
delete_sticker_from_set,
replace_sticker_in_set,
set_sticker_set_thumbnail,
set_custom_emoji_sticker_set_thumbnail,
set_sticker_set_title,

View file

@ -19,6 +19,7 @@ use crate::{
/// Request returned by [`Throttling`](crate::adaptors::Throttle) methods.
#[must_use = "Requests are lazy and do nothing unless sent"]
#[derive(Clone)]
pub struct ThrottlingRequest<R: HasPayload> {
pub(super) request: Arc<R>,
pub(super) chat_id: fn(&R::Payload) -> ChatIdHash,

View file

@ -92,11 +92,14 @@ where
set_webhook,
delete_webhook,
get_webhook_info,
forward_messages,
copy_messages,
edit_message_live_location,
edit_message_live_location_inline,
stop_message_live_location,
stop_message_live_location_inline,
send_chat_action,
set_message_reaction,
get_user_profile_photos,
get_file,
kick_chat_member,
@ -141,7 +144,9 @@ where
unhide_general_forum_topic,
unpin_all_general_forum_topic_messages,
answer_callback_query,
get_user_chat_boosts,
set_my_commands,
get_business_connection,
get_my_commands,
set_my_name,
get_my_name,
@ -166,6 +171,7 @@ where
edit_message_reply_markup_inline,
stop_poll,
delete_message,
delete_messages,
get_sticker_set,
get_custom_emoji_stickers,
upload_sticker_file,
@ -173,6 +179,7 @@ where
add_sticker_to_set,
set_sticker_position_in_set,
delete_sticker_from_set,
replace_sticker_in_set,
set_sticker_set_thumbnail,
set_custom_emoji_sticker_set_thumbnail,
set_sticker_set_title,

View file

@ -123,7 +123,9 @@ where
delete_webhook,
get_webhook_info,
forward_message,
forward_messages,
copy_message,
copy_messages,
send_message,
send_photo,
send_audio,
@ -143,6 +145,7 @@ where
send_poll,
send_dice,
send_chat_action,
set_message_reaction,
get_user_profile_photos,
get_file,
kick_chat_member,
@ -187,7 +190,9 @@ where
unhide_general_forum_topic,
unpin_all_general_forum_topic_messages,
answer_callback_query,
get_user_chat_boosts,
set_my_commands,
get_business_connection,
get_my_commands,
set_my_name,
get_my_name,
@ -212,6 +217,7 @@ where
edit_message_reply_markup_inline,
stop_poll,
delete_message,
delete_messages,
send_sticker,
get_sticker_set,
get_custom_emoji_stickers,
@ -220,6 +226,7 @@ where
add_sticker_to_set,
set_sticker_position_in_set,
delete_sticker_from_set,
replace_sticker_in_set,
set_sticker_set_thumbnail,
set_custom_emoji_sticker_set_thumbnail,
set_sticker_set_title,
@ -243,6 +250,7 @@ where
}
#[must_use = "Requests are lazy and do nothing unless sent"]
#[derive(Clone)]
pub struct TraceRequest<R> {
inner: R,
settings: Settings,

View file

@ -5,8 +5,9 @@ use crate::{
prelude::Requester,
requests::{JsonRequest, MultipartRequest},
types::{
BotCommand, ChatId, ChatPermissions, InlineQueryResult, InputFile, InputMedia,
InputSticker, LabeledPrice, MessageId, Recipient, StickerFormat, ThreadId, UserId,
BotCommand, BusinessConnectionId, ChatId, ChatPermissions, InlineQueryResult, InputFile,
InputMedia, InputSticker, LabeledPrice, MessageId, Recipient, Rgb, StickerFormat, ThreadId,
UserId,
},
Bot,
};
@ -72,6 +73,24 @@ impl Requester for Bot {
)
}
type ForwardMessages = JsonRequest<payloads::ForwardMessages>;
fn forward_messages<C, F, M>(
&self,
chat_id: C,
from_chat_id: F,
message_ids: M,
) -> Self::ForwardMessages
where
C: Into<Recipient>,
F: Into<Recipient>,
M: IntoIterator<Item = MessageId>,
{
Self::ForwardMessages::new(
self.clone(),
payloads::ForwardMessages::new(chat_id, from_chat_id, message_ids),
)
}
type SendPhoto = MultipartRequest<payloads::SendPhoto>;
fn send_photo<C>(&self, chat_id: C, photo: InputFile) -> Self::SendPhoto
@ -291,6 +310,18 @@ impl Requester for Bot {
Self::SendChatAction::new(self.clone(), payloads::SendChatAction::new(chat_id, action))
}
type SetMessageReaction = JsonRequest<payloads::SetMessageReaction>;
fn set_message_reaction<C>(&self, chat_id: C, message_id: MessageId) -> Self::SetMessageReaction
where
C: Into<Recipient>,
{
Self::SetMessageReaction::new(
self.clone(),
payloads::SetMessageReaction::new(chat_id, message_id),
)
}
type GetUserProfilePhotos = JsonRequest<payloads::GetUserProfilePhotos>;
fn get_user_profile_photos(&self, user_id: UserId) -> Self::GetUserProfilePhotos {
@ -655,7 +686,7 @@ impl Requester for Bot {
&self,
chat_id: C,
name: N,
icon_color: u32,
icon_color: Rgb,
icon_custom_emoji_id: I,
) -> Self::CreateForumTopic
where
@ -830,6 +861,18 @@ impl Requester for Bot {
)
}
type GetUserChatBoosts = JsonRequest<payloads::GetUserChatBoosts>;
fn get_user_chat_boosts<C>(&self, chat_id: C, user_id: UserId) -> Self::GetUserChatBoosts
where
C: Into<Recipient>,
{
Self::GetUserChatBoosts::new(
self.clone(),
payloads::GetUserChatBoosts::new(chat_id, user_id),
)
}
type SetMyCommands = JsonRequest<payloads::SetMyCommands>;
fn set_my_commands<C>(&self, commands: C) -> Self::SetMyCommands
@ -839,6 +882,18 @@ impl Requester for Bot {
Self::SetMyCommands::new(self.clone(), payloads::SetMyCommands::new(commands))
}
type GetBusinessConnection = JsonRequest<payloads::GetBusinessConnection>;
fn get_business_connection(
&self,
business_connection_id: BusinessConnectionId,
) -> Self::GetBusinessConnection {
Self::GetBusinessConnection::new(
self.clone(),
payloads::GetBusinessConnection::new(business_connection_id),
)
}
type GetMyCommands = JsonRequest<payloads::GetMyCommands>;
fn get_my_commands(&self) -> Self::GetMyCommands {
@ -1086,6 +1141,15 @@ impl Requester for Bot {
Self::DeleteMessage::new(self.clone(), payloads::DeleteMessage::new(chat_id, message_id))
}
type DeleteMessages = JsonRequest<payloads::DeleteMessages>;
fn delete_messages<C, M>(&self, chat_id: C, message_ids: M) -> Self::DeleteMessages
where
C: Into<Recipient>,
M: IntoIterator<Item = MessageId>,
{
Self::DeleteMessages::new(self.clone(), payloads::DeleteMessages::new(chat_id, message_ids))
}
type SendSticker = MultipartRequest<payloads::SendSticker>;
fn send_sticker<C>(&self, chat_id: C, sticker: InputFile) -> Self::SendSticker
@ -1122,7 +1186,7 @@ impl Requester for Bot {
&self,
user_id: UserId,
sticker: InputFile,
sticker_format: crate::types::StickerFormat,
sticker_format: StickerFormat,
) -> Self::UploadStickerFile {
Self::UploadStickerFile::new(
self.clone(),
@ -1138,7 +1202,6 @@ impl Requester for Bot {
name: N,
title: T,
stickers: S,
sticker_format: StickerFormat,
) -> Self::CreateNewStickerSet
where
N: Into<String>,
@ -1147,7 +1210,7 @@ impl Requester for Bot {
{
Self::CreateNewStickerSet::new(
self.clone(),
payloads::CreateNewStickerSet::new(user_id, name, title, stickers, sticker_format),
payloads::CreateNewStickerSet::new(user_id, name, title, stickers),
)
}
@ -1193,15 +1256,44 @@ impl Requester for Bot {
Self::DeleteStickerFromSet::new(self.clone(), payloads::DeleteStickerFromSet::new(sticker))
}
type ReplaceStickerInSet = JsonRequest<payloads::ReplaceStickerInSet>;
fn replace_sticker_in_set<N, O>(
&self,
user_id: UserId,
name: N,
old_sticker: O,
sticker: InputSticker,
) -> Self::ReplaceStickerInSet
where
N: Into<String>,
O: Into<String>,
{
Self::ReplaceStickerInSet::new(
self.clone(),
payloads::ReplaceStickerInSet {
user_id,
name: name.into(),
old_sticker: old_sticker.into(),
sticker,
},
)
}
type SetStickerSetThumbnail = MultipartRequest<payloads::SetStickerSetThumbnail>;
fn set_sticker_set_thumbnail<N>(&self, name: N, user_id: UserId) -> Self::SetStickerSetThumbnail
fn set_sticker_set_thumbnail<N>(
&self,
name: N,
user_id: UserId,
format: StickerFormat,
) -> Self::SetStickerSetThumbnail
where
N: Into<String>,
{
Self::SetStickerSetThumbnail::new(
self.clone(),
payloads::SetStickerSetThumbnail::new(name, user_id),
payloads::SetStickerSetThumbnail::new(name, user_id, format),
)
}
@ -1465,6 +1557,24 @@ impl Requester for Bot {
)
}
type CopyMessages = JsonRequest<payloads::CopyMessages>;
fn copy_messages<C, F, M>(
&self,
chat_id: C,
from_chat_id: F,
message_ids: M,
) -> Self::CopyMessages
where
C: Into<Recipient>,
F: Into<Recipient>,
M: IntoIterator<Item = MessageId>,
{
Self::CopyMessages::new(
self.clone(),
payloads::CopyMessages::new(chat_id, from_chat_id, message_ids),
)
}
type UnpinAllChatMessages = JsonRequest<payloads::UnpinAllChatMessages>;
fn unpin_all_chat_messages<C>(&self, chat_id: C) -> Self::UnpinAllChatMessages

View file

@ -1,13 +1,13 @@
//! Core part of the [`teloxide`] library.
//!
//! This library provides tools for making requests to the [Telegram Bot API]
//! (Currently, version `6.9` is supported) with ease. The library is fully
//! (Currently, version `7.2` is supported) with ease. The library is fully
//! asynchronous and built using [`tokio`].
//!
//!```toml
//! teloxide-core = "0.9"
//! teloxide-core = "0.10.1"
//! ```
//! _Compiler support: requires rustc 1.70+_.
//! _Compiler support: requires rustc 1.80+_.
//!
//! ```
//! # async {

View file

@ -487,6 +487,16 @@ macro_rules! requester_forward {
$body!(forward_message this (chat_id: C, from_chat_id: F, message_id: MessageId))
}
};
(@method forward_messages $body:ident $ty:ident) => {
type ForwardMessages = $ty![ForwardMessages];
fn forward_messages<C, F, M>(&self, chat_id: C, from_chat_id: F, message_ids: M) -> Self::ForwardMessages where C: Into<Recipient>,
F: Into<Recipient>,
M: IntoIterator<Item = MessageId> {
let this = self;
$body!(forward_messages this (chat_id: C, from_chat_id: F, message_ids: M))
}
};
(@method copy_message $body:ident $ty:ident) => {
type CopyMessage = $ty![CopyMessage];
@ -496,6 +506,16 @@ macro_rules! requester_forward {
$body!(copy_message this (chat_id: C, from_chat_id: F, message_id: MessageId))
}
};
(@method copy_messages $body:ident $ty:ident) => {
type CopyMessages = $ty![CopyMessages];
fn copy_messages<C, F, M>(&self, chat_id: C, from_chat_id: F, message_ids: M) -> Self::CopyMessages where C: Into<Recipient>,
F: Into<Recipient>,
M: IntoIterator<Item = MessageId> {
let this = self;
$body!(copy_messages this (chat_id: C, from_chat_id: F, message_ids: M))
}
};
(@method send_photo $body:ident $ty:ident) => {
type SendPhoto = $ty![SendPhoto];
@ -647,6 +667,14 @@ macro_rules! requester_forward {
$body!(send_chat_action this (chat_id: C, action: ChatAction))
}
};
(@method set_message_reaction $body:ident $ty:ident) => {
type SetMessageReaction = $ty![SetMessageReaction];
fn set_message_reaction<C>(&self, chat_id: C, message_id: MessageId) -> Self::SetMessageReaction where C: Into<Recipient> {
let this = self;
$body!(set_message_reaction this (chat_id: C, message_id: MessageId))
}
};
(@method get_user_profile_photos $body:ident $ty:ident) => {
type GetUserProfilePhotos = $ty![GetUserProfilePhotos];
@ -921,11 +949,11 @@ macro_rules! requester_forward {
(@method create_forum_topic $body:ident $ty:ident) => {
type CreateForumTopic = $ty![CreateForumTopic];
fn create_forum_topic<C, N, I>(&self, chat_id: C, name: N, icon_color: u32, icon_custom_emoji_id: I) -> Self::CreateForumTopic where C: Into<Recipient>,
fn create_forum_topic<C, N, I>(&self, chat_id: C, name: N, icon_color: Rgb, icon_custom_emoji_id: I) -> Self::CreateForumTopic where C: Into<Recipient>,
N: Into<String>,
I: Into<String> {
let this = self;
$body!(create_forum_topic this (chat_id: C, name: N, icon_color: u32, icon_custom_emoji_id: I))
$body!(create_forum_topic this (chat_id: C, name: N, icon_color: Rgb, icon_custom_emoji_id: I))
}
};
(@method edit_forum_topic $body:ident $ty:ident) => {
@ -1025,6 +1053,14 @@ macro_rules! requester_forward {
$body!(answer_callback_query this (callback_query_id: C))
}
};
(@method get_user_chat_boosts $body:ident $ty:ident) => {
type GetUserChatBoosts = $ty![GetUserChatBoosts];
fn get_user_chat_boosts<C>(&self, chat_id: C, user_id: UserId) -> Self::GetUserChatBoosts where C: Into<Recipient> {
let this = self;
$body!(get_user_chat_boosts this (chat_id: C, user_id: UserId))
}
};
(@method set_my_commands $body:ident $ty:ident) => {
type SetMyCommands = $ty![SetMyCommands];
@ -1033,6 +1069,14 @@ macro_rules! requester_forward {
$body!(set_my_commands this (commands: C))
}
};
(@method get_business_connection $body:ident $ty:ident) => {
type GetBusinessConnection = $ty![GetBusinessConnection];
fn get_business_connection(&self, business_connection_id: BusinessConnectionId) -> Self::GetBusinessConnection {
let this = self;
$body!(get_business_connection this (business_connection_id: BusinessConnectionId))
}
};
(@method get_my_commands $body:ident $ty:ident) => {
type GetMyCommands = $ty![GetMyCommands];
@ -1228,6 +1272,15 @@ macro_rules! requester_forward {
$body!(delete_message this (chat_id: C, message_id: MessageId))
}
};
(@method delete_messages $body:ident $ty:ident) => {
type DeleteMessages = $ty![DeleteMessages];
fn delete_messages<C, M>(&self, chat_id: C, message_ids: M) -> Self::DeleteMessages where C: Into<Recipient>,
M: IntoIterator<Item = MessageId> {
let this = self;
$body!(delete_messages this (chat_id: C, message_ids: M))
}
};
(@method send_sticker $body:ident $ty:ident) => {
type SendSticker = $ty![SendSticker];
@ -1263,11 +1316,11 @@ macro_rules! requester_forward {
(@method create_new_sticker_set $body:ident $ty:ident) => {
type CreateNewStickerSet = $ty![CreateNewStickerSet];
fn create_new_sticker_set<N, T, S>(&self, user_id: UserId, name: N, title: T, stickers: S, sticker_format: StickerFormat) -> Self::CreateNewStickerSet where N: Into<String>,
fn create_new_sticker_set<N, T, S>(&self, user_id: UserId, name: N, title: T, stickers: S) -> Self::CreateNewStickerSet where N: Into<String>,
T: Into<String>,
S: IntoIterator<Item = InputSticker> {
let this = self;
$body!(create_new_sticker_set this (user_id: UserId, name: N, title: T, stickers: S, sticker_format: StickerFormat))
$body!(create_new_sticker_set this (user_id: UserId, name: N, title: T, stickers: S))
}
};
(@method add_sticker_to_set $body:ident $ty:ident) => {
@ -1294,12 +1347,21 @@ macro_rules! requester_forward {
$body!(delete_sticker_from_set this (sticker: S))
}
};
(@method replace_sticker_in_set $body:ident $ty:ident) => {
type ReplaceStickerInSet = $ty![ReplaceStickerInSet];
fn replace_sticker_in_set<N, O>(&self, user_id: UserId, name: N, old_sticker: O, sticker: InputSticker) -> Self::ReplaceStickerInSet where N: Into<String>,
O: Into<String> {
let this = self;
$body!(replace_sticker_in_set this (user_id: UserId, name: N, old_sticker: O, sticker: InputSticker))
}
};
(@method set_sticker_set_thumbnail $body:ident $ty:ident) => {
type SetStickerSetThumbnail = $ty![SetStickerSetThumbnail];
fn set_sticker_set_thumbnail<N>(&self, name: N, user_id: UserId) -> Self::SetStickerSetThumbnail where N: Into<String> {
fn set_sticker_set_thumbnail<N>(&self, name: N, user_id: UserId, format: StickerFormat) -> Self::SetStickerSetThumbnail where N: Into<String> {
let this = self;
$body!(set_sticker_set_thumbnail this (name: N, user_id: UserId))
$body!(set_sticker_set_thumbnail this (name: N, user_id: UserId, format: StickerFormat))
}
};
(@method set_custom_emoji_sticker_set_thumbnail $body:ident $ty:ident) => {
@ -1470,7 +1532,7 @@ fn codegen_requester_forward() {
convert_params.sort_unstable();
let prefixes: IndexMap<_, _> = convert_params
let mut prefixes: IndexMap<_, _> = convert_params
.iter()
.copied()
// Workaround to output the last type as the first letter
@ -1479,6 +1541,18 @@ fn codegen_requester_forward() {
.map(|(l, r)| (l, min_prefix(l, r)))
.collect();
// FIXME: This hard-coded value has been set to avoid conflicting generic
// parameter 'B' with impl<B> Requester... in all the adaptors and other places
//
// One fix could be to take full abbrevation for all the parameters instead of
// just the first character. Other fix is to change the generic parameter name
// in all the impl blocks to something like 'Z' because that is very less likely
// to conflict in future.
if prefixes.contains_key("business_connection_id") {
prefixes["business_connection_id"] = "BCI";
}
let prefixes = prefixes;
let args = m
.params
.iter()

View file

@ -28,6 +28,7 @@ mod close;
mod close_forum_topic;
mod close_general_forum_topic;
mod copy_message;
mod copy_messages;
mod create_chat_invite_link;
mod create_forum_topic;
mod create_invoice_link;
@ -37,6 +38,7 @@ mod delete_chat_photo;
mod delete_chat_sticker_set;
mod delete_forum_topic;
mod delete_message;
mod delete_messages;
mod delete_my_commands;
mod delete_sticker_from_set;
mod delete_sticker_set;
@ -56,6 +58,8 @@ mod edit_message_text;
mod edit_message_text_inline;
mod export_chat_invite_link;
mod forward_message;
mod forward_messages;
mod get_business_connection;
mod get_chat;
mod get_chat_administrators;
mod get_chat_member;
@ -74,6 +78,7 @@ mod get_my_name;
mod get_my_short_description;
mod get_sticker_set;
mod get_updates;
mod get_user_chat_boosts;
mod get_user_profile_photos;
mod get_webhook_info;
mod hide_general_forum_topic;
@ -84,6 +89,7 @@ mod pin_chat_message;
mod promote_chat_member;
mod reopen_forum_topic;
mod reopen_general_forum_topic;
mod replace_sticker_in_set;
mod restrict_chat_member;
mod revoke_chat_invite_link;
mod send_animation;
@ -114,6 +120,7 @@ mod set_chat_title;
mod set_custom_emoji_sticker_set_thumbnail;
mod set_game_score;
mod set_game_score_inline;
mod set_message_reaction;
mod set_my_commands;
mod set_my_default_administrator_rights;
mod set_my_description;
@ -152,6 +159,7 @@ pub use close::{Close, CloseSetters};
pub use close_forum_topic::{CloseForumTopic, CloseForumTopicSetters};
pub use close_general_forum_topic::{CloseGeneralForumTopic, CloseGeneralForumTopicSetters};
pub use copy_message::{CopyMessage, CopyMessageSetters};
pub use copy_messages::{CopyMessages, CopyMessagesSetters};
pub use create_chat_invite_link::{CreateChatInviteLink, CreateChatInviteLinkSetters};
pub use create_forum_topic::{CreateForumTopic, CreateForumTopicSetters};
pub use create_invoice_link::{CreateInvoiceLink, CreateInvoiceLinkSetters};
@ -161,6 +169,7 @@ pub use delete_chat_photo::{DeleteChatPhoto, DeleteChatPhotoSetters};
pub use delete_chat_sticker_set::{DeleteChatStickerSet, DeleteChatStickerSetSetters};
pub use delete_forum_topic::{DeleteForumTopic, DeleteForumTopicSetters};
pub use delete_message::{DeleteMessage, DeleteMessageSetters};
pub use delete_messages::{DeleteMessages, DeleteMessagesSetters};
pub use delete_my_commands::{DeleteMyCommands, DeleteMyCommandsSetters};
pub use delete_sticker_from_set::{DeleteStickerFromSet, DeleteStickerFromSetSetters};
pub use delete_sticker_set::{DeleteStickerSet, DeleteStickerSetSetters};
@ -184,6 +193,8 @@ pub use edit_message_text::{EditMessageText, EditMessageTextSetters};
pub use edit_message_text_inline::{EditMessageTextInline, EditMessageTextInlineSetters};
pub use export_chat_invite_link::{ExportChatInviteLink, ExportChatInviteLinkSetters};
pub use forward_message::{ForwardMessage, ForwardMessageSetters};
pub use forward_messages::{ForwardMessages, ForwardMessagesSetters};
pub use get_business_connection::{GetBusinessConnection, GetBusinessConnectionSetters};
pub use get_chat::{GetChat, GetChatSetters};
pub use get_chat_administrators::{GetChatAdministrators, GetChatAdministratorsSetters};
pub use get_chat_member::{GetChatMember, GetChatMemberSetters};
@ -206,6 +217,7 @@ pub use get_my_name::{GetMyName, GetMyNameSetters};
pub use get_my_short_description::{GetMyShortDescription, GetMyShortDescriptionSetters};
pub use get_sticker_set::{GetStickerSet, GetStickerSetSetters};
pub use get_updates::{GetUpdates, GetUpdatesSetters};
pub use get_user_chat_boosts::{GetUserChatBoosts, GetUserChatBoostsSetters};
pub use get_user_profile_photos::{GetUserProfilePhotos, GetUserProfilePhotosSetters};
pub use get_webhook_info::{GetWebhookInfo, GetWebhookInfoSetters};
pub use hide_general_forum_topic::{HideGeneralForumTopic, HideGeneralForumTopicSetters};
@ -216,6 +228,7 @@ pub use pin_chat_message::{PinChatMessage, PinChatMessageSetters};
pub use promote_chat_member::{PromoteChatMember, PromoteChatMemberSetters};
pub use reopen_forum_topic::{ReopenForumTopic, ReopenForumTopicSetters};
pub use reopen_general_forum_topic::{ReopenGeneralForumTopic, ReopenGeneralForumTopicSetters};
pub use replace_sticker_in_set::{ReplaceStickerInSet, ReplaceStickerInSetSetters};
pub use restrict_chat_member::{RestrictChatMember, RestrictChatMemberSetters};
pub use revoke_chat_invite_link::{RevokeChatInviteLink, RevokeChatInviteLinkSetters};
pub use send_animation::{SendAnimation, SendAnimationSetters};
@ -250,6 +263,7 @@ pub use set_custom_emoji_sticker_set_thumbnail::{
};
pub use set_game_score::{SetGameScore, SetGameScoreSetters};
pub use set_game_score_inline::{SetGameScoreInline, SetGameScoreInlineSetters};
pub use set_message_reaction::{SetMessageReaction, SetMessageReactionSetters};
pub use set_my_commands::{SetMyCommands, SetMyCommandsSetters};
pub use set_my_default_administrator_rights::{
SetMyDefaultAdministratorRights, SetMyDefaultAdministratorRightsSetters,

View file

@ -2,7 +2,9 @@
use serde::Serialize;
use crate::types::{MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId};
use crate::types::{
MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to copy messages of any kind. The method is analogous to the method forwardMessage, but the copied message doesn't have a link to the original message. Returns the [`MessageId`] of the sent message on success.
@ -36,12 +38,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -0,0 +1,35 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{MessageId, Recipient, ThreadId};
impl_payload! {
/// 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.
///
/// [`MessageId`]: crate::types::MessageId
/// [`ForwardMessages`]: crate::payloads::ForwardMessages
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub CopyMessages (CopyMessagesSetters) => Vec<MessageId> {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
pub chat_id: Recipient [into],
/// Unique identifier for the chat where the original message was sent (or channel username in the format `@channelusername`)
pub from_chat_id: Recipient [into],
/// Identifiers of 1-100 messages in the chat _from\_chat\_id_ to copy. The identifiers must be specified in a strictly increasing order.
pub message_ids: Vec<MessageId> [collect],
}
optional {
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Sends the message [silently]. Users will receive a notification with no sound.
///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// Pass _True_ to copy the messages without their captions
pub remove_caption: bool,
}
}
}

View file

@ -2,7 +2,7 @@
use serde::Serialize;
use crate::types::{ForumTopic, Recipient};
use crate::types::{ForumTopic, Recipient, Rgb};
impl_payload! {
/// Use this method to create a 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. Returns information about the created topic as a `ForumTopic` object.
@ -13,8 +13,10 @@ impl_payload! {
pub chat_id: Recipient [into],
/// Topic name, 1-128 characters
pub name: String [into],
/// Color of the topic icon in RGB format. Currently, must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB), 9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F)
pub icon_color: u32,
/// Color of the topic icon in RGB format. Currently, must be one of 7322096 (`0x6FB9F0`), 16766590 (`0xFFD67E`), 13338331 (`0xCB86DB`), 9367192 (`0x8EEE98`), 16749490 (`0xFF93B2`), or 16478047 (`0xFB6F5F`). To construct color from these values use [`Rgb::from_u32`]
///
/// [`Rgb::from_u32`]: crate::types::Rgb::from_u32
pub icon_color: Rgb,
/// Unique identifier of the custom emoji shown as the topic icon. Use `getForumTopicIconStickers` to get all allowed custom emoji identifiers.
pub icon_custom_emoji_id: String [into],
}

View file

@ -19,7 +19,10 @@ impl_payload! {
///
/// [Botfather]: https://t.me/botfather
pub provider_token: String [into],
/// Three-letter ISO 4217 currency code, see more on currencies
/// Three-letter ISO 4217 currency code, see [more on currencies]. Pass `XTR` for payments in [Telegram Stars].
///
/// [more on currencies]: https://core.telegram.org/bots/payments#supported-currencies
/// [Telegram Stars]: https://t.me/BotNews/90
pub currency: String [into],
/// Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
pub prices: Vec<LabeledPrice> [collect],

View file

@ -2,7 +2,7 @@
use serde::Serialize;
use crate::types::{InputSticker, StickerFormat, StickerType, True, UserId};
use crate::types::{InputSticker, StickerType, True, UserId};
impl_payload! {
/// Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus created. Returns True on success.
@ -17,8 +17,6 @@ impl_payload! {
pub title: String [into],
/// A JSON-serialized list of 1-50 initial stickers to be added to the sticker set
pub stickers: Vec<InputSticker> [collect],
/// Format of the sticker, must be one of “static”, “animated”, “video”
pub sticker_format: StickerFormat,
}
optional {
/// Type of stickers in the set, pass “regular”, “mask”, or “custom_emoji”. By default, a regular sticker set is created.

View file

@ -0,0 +1,20 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{MessageId, Recipient, True};
impl_payload! {
/// 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.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub DeleteMessages (DeleteMessagesSetters) => True {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`).
pub chat_id: Recipient [into],
/// Identifiers of 1-100 messages to delete. See [`DeleteMessage`] for limitations on which messages can be deleted
///
/// [`DeleteMessage`]: crate::payloads::DeleteMessage
pub message_ids: Vec<MessageId> [collect],
}
}
}

View file

@ -30,7 +30,7 @@ impl_payload! {
pub heading: u16,
/// For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified.
pub proximity_alert_radius: u32,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -27,7 +27,7 @@ impl_payload! {
pub heading: u16,
/// For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters. Must be between 1 and 100000 if specified.
pub proximity_alert_radius: u32,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,7 +2,10 @@
use serde::Serialize;
use crate::types::{InlineKeyboardMarkup, Message, MessageEntity, MessageId, ParseMode, Recipient};
use crate::types::{
InlineKeyboardMarkup, LinkPreviewOptions, Message, MessageEntity, MessageId, ParseMode,
Recipient,
};
impl_payload! {
/// Use this method to edit text and [games] messages. On success, the edited Message is returned.
@ -28,8 +31,8 @@ impl_payload! {
pub parse_mode: ParseMode,
/// List of special entities that appear in message text, which can be specified instead of _parse\_mode_
pub entities: Vec<MessageEntity> [collect],
/// Disables link previews for links in this message
pub disable_web_page_preview: bool,
/// Link preview generation options for the message
pub link_preview_options: LinkPreviewOptions,
/// A JSON-serialized object for an [inline keyboard].
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating

View file

@ -0,0 +1,32 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{MessageId, Recipient, ThreadId};
impl_payload! {
/// 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.
///
/// [`MessageId`]: crate::types::MessageId
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub ForwardMessages (ForwardMessagesSetters) => Vec<MessageId> {
required {
/// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
pub chat_id: Recipient [into],
/// Unique identifier for the chat where the original message was sent (or channel username in the format `@channelusername`)
pub from_chat_id: Recipient [into],
/// A JSON-serialized list of 1-100 identifiers of messages in the chat _from\_chat\_id_ to forward. The identifiers must be specified in a strictly increasing order.
pub message_ids: Vec<MessageId> [collect],
}
optional {
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Sends the message [silently]. Users will receive a notification with no sound.
///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
}
}
}

View file

@ -0,0 +1,16 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{BusinessConnection, BusinessConnectionId};
impl_payload! {
/// Use this method to get information about the connection of the bot with a business account. Returns a BusinessConnection object on success.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub GetBusinessConnection (GetBusinessConnectionSetters) => BusinessConnection {
required {
/// Unique identifier of the business connection
pub business_connection_id: BusinessConnectionId,
}
}
}

View file

@ -0,0 +1,20 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{Recipient, UserChatBoosts, UserId};
impl_payload! {
/// 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.
///
/// [`UserChatBoosts`]: crate::types::UserChatBoosts
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub GetUserChatBoosts (GetUserChatBoostsSetters) => UserChatBoosts {
required {
/// Unique identifier for the chat or username of the channel (in the format @channelusername)
pub chat_id: Recipient [into],
/// Unique identifier of the target user
pub user_id: UserId,
}
}
}

View file

@ -25,11 +25,11 @@ impl_payload! {
pub can_edit_messages: bool,
/// Pass True, if the administrator can delete messages of other users
pub can_delete_messages: bool,
/// Pass True, if the administrator can post stories in the channel, channels only
/// Pass True, if the administrator can post stories to the chat
pub can_post_stories: bool,
/// Pass True, if the administrator can edit stories posted by other users, channels only
/// Pass True, if the administrator can edit stories posted by other users
pub can_edit_stories: bool,
/// Pass True, if the administrator can delete stories posted by other users, channels only
/// Pass True, if the administrator can delete stories posted by other users
pub can_delete_stories: bool,
/// Pass True, if the administrator can manage video chats, supergroups only
pub can_manage_video_chats: bool,

View file

@ -0,0 +1,27 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{InputSticker, True, UserId};
impl_payload! {
@[multipart = sticker]
/// Use this method to replace an existing sticker in a sticker set with a new one. The method is equivalent to calling [DeleteStickerFromSet], then [AddStickerToSet], then [SetStickerPositionInSet]. Returns _True_ on success.
///
/// [DeleteStickerFromSet]: https://docs.rs/teloxide/latest/teloxide/payloads/struct.DeleteStickerFromSet.html
/// [AddStickerToSet]: https://docs.rs/teloxide/latest/teloxide/payloads/struct.AddStickerToSet.html
/// [SetStickerPositionInSet]: https://docs.rs/teloxide/latest/teloxide/payloads/struct.SetStickerPositionInSet.html
#[derive(Debug, Clone, Serialize)]
pub ReplaceStickerInSet (ReplaceStickerInSetSetters) => True {
required {
/// User identifier of the sticker set owner
pub user_id: UserId,
/// Sticker set name
pub name: String [into],
/// File identifier of the replaced sticker
pub old_sticker: String [into],
/// A JSON-serialized object with information about the added sticker. If exactly the same sticker had already been added to the set, then the set remains unchanged.
pub sticker: InputSticker,
}
}
}

View file

@ -3,7 +3,8 @@
use serde::Serialize;
use crate::types::{
InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup,
ReplyParameters, ThreadId,
};
impl_payload! {
@ -22,6 +23,8 @@ impl_payload! {
pub animation: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Duration of the animation in seconds
@ -50,12 +53,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -3,7 +3,8 @@
use serde::Serialize;
use crate::types::{
InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup,
ReplyParameters, ThreadId,
};
impl_payload! {
@ -25,6 +26,8 @@ impl_payload! {
pub audio: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Audio caption, 0-1024 characters after entities parsing
@ -51,12 +54,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,7 +2,7 @@
use serde::Serialize;
use crate::types::{ChatAction, Recipient, ThreadId, True};
use crate::types::{BusinessConnectionId, ChatAction, Recipient, ThreadId, True};
impl_payload! {
/// Use this method when you need to tell the user that something is happening on the bot's side. The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status). Returns True on success.
@ -30,6 +30,8 @@ impl_payload! {
pub action: ChatAction,
}
optional {
/// Unique identifier of the business connection on behalf of which the action will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread; supergroups only
pub message_thread_id: ThreadId,
}

View file

@ -2,7 +2,9 @@
use serde::Serialize;
use crate::types::{Message, MessageId, Recipient, ReplyMarkup, ThreadId};
use crate::types::{
BusinessConnectionId, Message, Recipient, ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to send phone contacts. On success, the sent [`Message`] is returned.
@ -19,6 +21,8 @@ impl_payload! {
pub first_name: String [into],
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Contact's last name
@ -33,12 +37,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,7 +2,9 @@
use serde::Serialize;
use crate::types::{DiceEmoji, Message, MessageId, Recipient, ReplyMarkup, ThreadId};
use crate::types::{
BusinessConnectionId, DiceEmoji, Message, Recipient, ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to send an animated emoji that will display a random value. On success, the sent [`Message`] is returned.
@ -15,6 +17,8 @@ impl_payload! {
pub chat_id: Recipient [into],
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Emoji on which the dice throw animation is based. Currently, must be one of “🎲”, “🎯”, “🏀”, “⚽”, “🎳”, or “🎰”. Dice can have values 1-6 for “🎲”, “🎯” and “🎳”, values 1-5 for “🏀” and “⚽”, and values 1-64 for “🎰”. Defaults to “🎲”
@ -25,12 +29,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -3,7 +3,8 @@
use serde::Serialize;
use crate::types::{
InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup,
ReplyParameters, ThreadId,
};
impl_payload! {
@ -22,6 +23,8 @@ impl_payload! {
pub document: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>. [More info on Sending Files »]
@ -44,12 +47,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,7 +2,7 @@
use serde::Serialize;
use crate::types::{ChatId, Message, MessageId, ReplyMarkup, ThreadId};
use crate::types::{BusinessConnectionId, ChatId, Message, ReplyMarkup, ReplyParameters, ThreadId};
impl_payload! {
/// Use this method to send a game. On success, the sent [`Message`] is returned.
@ -17,6 +17,8 @@ impl_payload! {
pub game_short_name: String [into],
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Sends the message [silently]. Users will receive a notification with no sound.
@ -25,12 +27,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// A JSON-serialized object for an [inline keyboard]. If empty, one 'Play game_title' button will be shown. If not empty, the first button must launch the game.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// A JSON-serialized object for an [inline keyboard]. If empty, one 'Play game_title' button will be shown. If not empty, the first button must launch the game. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
pub reply_markup: ReplyMarkup [into],

View file

@ -3,7 +3,9 @@
use serde::Serialize;
use url::Url;
use crate::types::{InlineKeyboardMarkup, LabeledPrice, Message, MessageId, Recipient, ThreadId};
use crate::types::{
InlineKeyboardMarkup, LabeledPrice, Message, Recipient, ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to send invoices. On success, the sent [`Message`] is returned.
@ -24,7 +26,10 @@ impl_payload! {
///
/// [Botfather]: https://t.me/botfather
pub provider_token: String [into],
/// Three-letter ISO 4217 currency code, see more on currencies
/// Three-letter ISO 4217 currency code, see [more on currencies]. Pass `XTR` for payments in [Telegram Stars].
///
/// [more on currencies]: https://core.telegram.org/bots/payments#supported-currencies
/// [Telegram Stars]: https://t.me/BotNews/90
pub currency: String [into],
/// Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
pub prices: Vec<LabeledPrice> [collect],
@ -70,11 +75,8 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// A JSON-serialized object for an [inline keyboard]. If empty, one 'Pay `total price`' button will be shown. If not empty, the first button must be a Pay button.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating

View file

@ -2,7 +2,9 @@
use serde::Serialize;
use crate::types::{Message, MessageId, Recipient, ReplyMarkup, ThreadId};
use crate::types::{
BusinessConnectionId, Message, Recipient, ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to send point on the map. On success, the sent [`Message`] is returned.
@ -19,6 +21,8 @@ impl_payload! {
pub longitude: f64,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// The radius of uncertainty for the location, measured in meters; 0-1500
@ -37,12 +41,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,7 +2,9 @@
use serde::Serialize;
use crate::types::{InputMedia, Message, MessageId, Recipient, ThreadId};
use crate::types::{
BusinessConnectionId, InputMedia, Message, Recipient, ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to send a group of photos, videos, documents or audios as an album. Documents and audio files can be only grouped in an album with messages of the same type. On success, an array of [`Message`]s that were sent is returned.
@ -26,6 +28,8 @@ impl_payload! {
pub media: Vec<InputMedia> [collect],
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Sends the message [silently]. Users will receive a notification with no sound.
@ -34,11 +38,8 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
}
}
}

View file

@ -3,7 +3,8 @@
use serde::Serialize;
use crate::types::{
Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, LinkPreviewOptions, Message, MessageEntity, ParseMode, Recipient,
ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
@ -19,6 +20,8 @@ impl_payload! {
pub text: String [into],
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Mode for parsing entities in the message text. See [formatting options] for more details.
@ -27,20 +30,17 @@ impl_payload! {
pub parse_mode: ParseMode,
/// List of special entities that appear in the message text, which can be specified instead of _parse\_mode_
pub entities: Vec<MessageEntity> [collect],
/// Disables link previews for links in this message
pub disable_web_page_preview: bool,
/// Link preview generation options for the message
pub link_preview_options: LinkPreviewOptions,
/// Sends the message [silently]. Users will receive a notification with no sound.
///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -3,7 +3,8 @@
use serde::Serialize;
use crate::types::{
InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup,
ReplyParameters, ThreadId,
};
impl_payload! {
@ -22,6 +23,8 @@ impl_payload! {
pub photo: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Photo caption (may also be used when resending photos by _file\_id_), 0-1024 characters after entities parsing
@ -40,12 +43,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -4,11 +4,12 @@ use chrono::{DateTime, Utc};
use serde::Serialize;
use crate::types::{
Message, MessageEntity, MessageId, ParseMode, PollType, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, Message, MessageEntity, ParseMode, PollType, Recipient, ReplyMarkup,
ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to send phone contacts. On success, the sent [`Message`] is returned.
/// Use this method to send a native poll. On success, the sent [`Message`] is returned.
///
/// [`Message`]: crate::types::Message
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
@ -22,6 +23,8 @@ impl_payload! {
pub options: Vec<String> [collect],
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// True, if the poll needs to be anonymous, defaults to True
@ -54,12 +57,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,11 +2,13 @@
use serde::Serialize;
use crate::types::{InputFile, Message, MessageId, Recipient, ReplyMarkup, ThreadId};
use crate::types::{
BusinessConnectionId, InputFile, Message, Recipient, ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
@[multipart = sticker]
/// Use this method to send static .WEBP or [animated] .TGS stickers. On success, the sent Message is returned.
/// Use this method to send static .WEBP, .TGS or .WEBM stickers. On success, the sent Message is returned.
///
/// [animated]: https://telegram.org/blog/animated-stickers
#[derive(Debug, Clone, Serialize)]
@ -20,6 +22,8 @@ impl_payload! {
pub sticker: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Emoji associated with the sticker; only for just uploaded stickers
@ -30,12 +34,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,7 +2,9 @@
use serde::Serialize;
use crate::types::{Message, MessageId, Recipient, ReplyMarkup, ThreadId};
use crate::types::{
BusinessConnectionId, Message, Recipient, ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
/// Use this method to send information about a venue. On success, the sent [`Message`] is returned.
@ -23,6 +25,8 @@ impl_payload! {
pub address: String [into],
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Foursquare identifier of the venue
@ -41,12 +45,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -3,7 +3,8 @@
use serde::Serialize;
use crate::types::{
InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup,
ReplyParameters, ThreadId,
};
impl_payload! {
@ -23,6 +24,8 @@ impl_payload! {
pub video: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Duration of the video in seconds
@ -53,12 +56,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -2,7 +2,9 @@
use serde::Serialize;
use crate::types::{InputFile, Message, MessageId, Recipient, ReplyMarkup, ThreadId};
use crate::types::{
BusinessConnectionId, InputFile, Message, Recipient, ReplyMarkup, ReplyParameters, ThreadId,
};
impl_payload! {
@[multipart = video_note, thumbnail]
@ -21,6 +23,8 @@ impl_payload! {
pub video_note: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Duration of the video in seconds
@ -37,12 +41,9 @@ impl_payload! {
pub disable_notification: bool,
/// Protects the contents of sent messages from forwarding and saving
pub protect_content: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -3,7 +3,8 @@
use serde::Serialize;
use crate::types::{
InputFile, Message, MessageEntity, MessageId, ParseMode, Recipient, ReplyMarkup, ThreadId,
BusinessConnectionId, InputFile, Message, MessageEntity, ParseMode, Recipient, ReplyMarkup,
ReplyParameters, ThreadId,
};
impl_payload! {
@ -24,6 +25,8 @@ impl_payload! {
pub voice: InputFile,
}
optional {
/// Unique identifier of the business connection on behalf of which the message will be sent
pub business_connection_id: BusinessConnectionId,
/// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
pub message_thread_id: ThreadId,
/// Voice message caption, 0-1024 characters after entities parsing
@ -40,12 +43,9 @@ impl_payload! {
///
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages
pub disable_notification: bool,
/// If the message is a reply, ID of the original message
#[serde(serialize_with = "crate::types::serialize_reply_to_message_id")]
pub reply_to_message_id: MessageId,
/// Pass _True_, if the message should be sent even if the specified replied-to message is not found
pub allow_sending_without_reply: bool,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Description of the message to reply to
pub reply_parameters: ReplyParameters,
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -0,0 +1,25 @@
//! Generated by `codegen_payloads`, do not edit by hand.
use serde::Serialize;
use crate::types::{MessageId, ReactionType, Recipient, True};
impl_payload! {
/// 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.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize)]
pub SetMessageReaction (SetMessageReactionSetters) => True {
required {
/// Unique identifier for the target chat or username of the target channel (in the format @channelusername)
pub chat_id: Recipient [into],
/// Identifier of the target message. If the message belongs to a media group, the reaction is set to the first non-deleted message in the group instead.
#[serde(flatten)]
pub message_id: MessageId,
}
optional {
/// New list of reaction types to set on the message. Currently, as non-premium users, bots can set up to one reaction per message. A custom emoji reaction can be used if it is either already present on the message or explicitly allowed by chat administrators.
pub reaction: Vec<ReactionType> [collect],
/// Pass True to set the reaction with a big animation
pub is_big: bool,
}
}
}

View file

@ -2,7 +2,7 @@
use serde::Serialize;
use crate::types::{InputFile, True, UserId};
use crate::types::{InputFile, StickerFormat, True, UserId};
impl_payload! {
@[multipart = thumbnail]
@ -14,6 +14,8 @@ impl_payload! {
pub name: String [into],
/// User identifier of sticker file owner
pub user_id: UserId,
/// Format of the thumbnail, must be one of "static" for a .WEBP or .PNG image, "animated" for a .TGS animation, or "video" for a WEBM video
pub format: StickerFormat,
}
optional {
/// A .WEBP or .PNG image with the thumbnail, must be up to 128 kilobytes in size and have a width and height of exactly 100px, or a .TGS animation with a thumbnail up to 32 kilobytes in size (see https://core.telegram.org/stickers#animated-sticker-requirements for animated sticker technical requirements), or a WEBM video with the thumbnail up to 32 kilobytes in size; see https://core.telegram.org/stickers#video-sticker-requirements for video sticker technical requirements. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Animated and video sticker set thumbnails can't be uploaded via HTTP URL. If omitted, then the thumbnail is dropped and the first sticker is used as the thumbnail.

View file

@ -6,31 +6,34 @@ pub use crate::payloads::{
AnswerPreCheckoutQuerySetters as _, AnswerShippingQuerySetters as _,
AnswerWebAppQuerySetters as _, ApproveChatJoinRequestSetters as _, BanChatMemberSetters as _,
BanChatSenderChatSetters as _, CloseForumTopicSetters as _, CloseGeneralForumTopicSetters as _,
CloseSetters as _, CopyMessageSetters as _, CreateChatInviteLinkSetters as _,
CreateForumTopicSetters as _, CreateInvoiceLinkSetters as _, CreateNewStickerSetSetters as _,
DeclineChatJoinRequestSetters as _, DeleteChatPhotoSetters as _,
DeleteChatStickerSetSetters as _, DeleteForumTopicSetters as _, DeleteMessageSetters as _,
DeleteMyCommandsSetters as _, DeleteStickerFromSetSetters as _, DeleteStickerSetSetters as _,
DeleteWebhookSetters as _, EditChatInviteLinkSetters as _, EditForumTopicSetters as _,
EditGeneralForumTopicSetters as _, EditMessageCaptionInlineSetters as _,
EditMessageCaptionSetters as _, EditMessageLiveLocationInlineSetters as _,
EditMessageLiveLocationSetters as _, EditMessageMediaInlineSetters as _,
EditMessageMediaSetters as _, EditMessageReplyMarkupInlineSetters as _,
EditMessageReplyMarkupSetters as _, EditMessageTextInlineSetters as _,
EditMessageTextSetters as _, ExportChatInviteLinkSetters as _, ForwardMessageSetters as _,
GetChatAdministratorsSetters as _, GetChatMemberCountSetters as _, GetChatMemberSetters as _,
GetChatMembersCountSetters as _, GetChatMenuButtonSetters as _, GetChatSetters as _,
GetCustomEmojiStickersSetters as _, GetFileSetters as _, GetForumTopicIconStickersSetters as _,
GetGameHighScoresSetters as _, GetMeSetters as _, GetMyCommandsSetters as _,
GetMyDefaultAdministratorRightsSetters as _, GetMyDescriptionSetters as _,
GetMyNameSetters as _, GetMyShortDescriptionSetters as _, GetStickerSetSetters as _,
GetUpdatesSetters as _, GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _,
CloseSetters as _, CopyMessageSetters as _, CopyMessagesSetters as _,
CreateChatInviteLinkSetters as _, CreateForumTopicSetters as _, CreateInvoiceLinkSetters as _,
CreateNewStickerSetSetters as _, DeclineChatJoinRequestSetters as _,
DeleteChatPhotoSetters as _, DeleteChatStickerSetSetters as _, DeleteForumTopicSetters as _,
DeleteMessageSetters as _, DeleteMessagesSetters as _, DeleteMyCommandsSetters as _,
DeleteStickerFromSetSetters as _, DeleteStickerSetSetters as _, DeleteWebhookSetters as _,
EditChatInviteLinkSetters as _, EditForumTopicSetters as _, EditGeneralForumTopicSetters as _,
EditMessageCaptionInlineSetters as _, EditMessageCaptionSetters as _,
EditMessageLiveLocationInlineSetters as _, EditMessageLiveLocationSetters as _,
EditMessageMediaInlineSetters as _, EditMessageMediaSetters as _,
EditMessageReplyMarkupInlineSetters as _, EditMessageReplyMarkupSetters as _,
EditMessageTextInlineSetters as _, EditMessageTextSetters as _,
ExportChatInviteLinkSetters as _, ForwardMessageSetters as _, ForwardMessagesSetters as _,
GetBusinessConnectionSetters as _, GetChatAdministratorsSetters as _,
GetChatMemberCountSetters as _, GetChatMemberSetters as _, GetChatMembersCountSetters as _,
GetChatMenuButtonSetters as _, GetChatSetters as _, GetCustomEmojiStickersSetters as _,
GetFileSetters as _, GetForumTopicIconStickersSetters as _, GetGameHighScoresSetters as _,
GetMeSetters as _, GetMyCommandsSetters as _, GetMyDefaultAdministratorRightsSetters as _,
GetMyDescriptionSetters as _, GetMyNameSetters as _, GetMyShortDescriptionSetters as _,
GetStickerSetSetters as _, GetUpdatesSetters as _, GetUserChatBoostsSetters as _,
GetUserProfilePhotosSetters as _, GetWebhookInfoSetters as _,
HideGeneralForumTopicSetters as _, KickChatMemberSetters as _, LeaveChatSetters as _,
LogOutSetters as _, PinChatMessageSetters as _, PromoteChatMemberSetters as _,
ReopenForumTopicSetters as _, ReopenGeneralForumTopicSetters as _,
RestrictChatMemberSetters as _, RevokeChatInviteLinkSetters as _, SendAnimationSetters as _,
SendAudioSetters as _, SendChatActionSetters as _, SendContactSetters as _,
SendDiceSetters as _, SendDocumentSetters as _, SendGameSetters as _, SendInvoiceSetters as _,
ReplaceStickerInSetSetters as _, RestrictChatMemberSetters as _,
RevokeChatInviteLinkSetters as _, SendAnimationSetters as _, SendAudioSetters as _,
SendChatActionSetters as _, SendContactSetters as _, SendDiceSetters as _,
SendDocumentSetters as _, SendGameSetters as _, SendInvoiceSetters as _,
SendLocationSetters as _, SendMediaGroupSetters as _, SendMessageSetters as _,
SendPhotoSetters as _, SendPollSetters as _, SendStickerSetters as _, SendVenueSetters as _,
SendVideoNoteSetters as _, SendVideoSetters as _, SendVoiceSetters as _,
@ -38,7 +41,7 @@ pub use crate::payloads::{
SetChatMenuButtonSetters as _, SetChatPermissionsSetters as _, SetChatPhotoSetters as _,
SetChatStickerSetSetters as _, SetChatTitleSetters as _,
SetCustomEmojiStickerSetThumbnailSetters as _, SetGameScoreInlineSetters as _,
SetGameScoreSetters as _, SetMyCommandsSetters as _,
SetGameScoreSetters as _, SetMessageReactionSetters as _, SetMyCommandsSetters as _,
SetMyDefaultAdministratorRightsSetters as _, SetMyDescriptionSetters as _,
SetMyNameSetters as _, SetMyShortDescriptionSetters as _, SetPassportDataErrorsSetters as _,
SetStickerEmojiListSetters as _, SetStickerKeywordsSetters as _,

View file

@ -21,7 +21,7 @@ impl_payload! {
pub message_id: MessageId,
}
optional {
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -17,7 +17,7 @@ impl_payload! {
pub inline_message_id: String [into],
}
optional {
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove reply keyboard or to force a reply from the user.
/// Additional interface options. A JSON-serialized object for an [inline keyboard], [custom reply keyboard], instructions to remove a reply keyboard or to force a reply from the user. Not supported for messages sent on behalf of a business account.
///
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards

View file

@ -6,10 +6,11 @@ use crate::types::{FileMeta, InputFile, StickerFormat, UserId};
impl_payload! {
@[multipart = sticker]
/// Use this method to upload a file with a sticker for later use in the [CreateNewStickerSet] and [AddStickerToSet] methods (the file can be used multiple times). Returns the uploaded [`File`] on success.
/// Use this method to upload a file with a sticker for later use in the [CreateNewStickerSet], [AddStickerToSet] or [ReplaceStickerInSet] methods (the file can be used multiple times). Returns the uploaded [`File`] on success.
///
/// [CreateNewStickerSet]: https://docs.rs/teloxide/latest/teloxide/payloads/struct.CreateNewStickerSet.html
/// [AddStickerToSet]: https://docs.rs/teloxide/latest/teloxide/payloads/struct.AddStickerToSet.html
/// [ReplaceStickerInSet]: https://docs.rs/teloxide/latest/teloxide/payloads/struct.ReplaceStickerInSet.html
/// [`File`]: crate::types::File
#[derive(Debug, Clone, Serialize)]
pub UploadStickerFile (UploadStickerFileSetters) => FileMeta {

View file

@ -203,6 +203,20 @@ pub trait Requester {
C: Into<Recipient>,
F: Into<Recipient>;
type ForwardMessages: Request<Payload = ForwardMessages, Err = Self::Err>;
/// For Telegram documentation see [`ForwardMessages`].
fn forward_messages<C, F, M>(
&self,
chat_id: C,
from_chat_id: F,
message_ids: M,
) -> Self::ForwardMessages
where
C: Into<Recipient>,
F: Into<Recipient>,
M: IntoIterator<Item = MessageId>;
type CopyMessage: Request<Payload = CopyMessage, Err = Self::Err>;
/// For Telegram documentation see [`CopyMessage`].
@ -216,6 +230,20 @@ pub trait Requester {
C: Into<Recipient>,
F: Into<Recipient>;
type CopyMessages: Request<Payload = CopyMessages, Err = Self::Err>;
/// For Telegram documentation see [`CopyMessages`].
fn copy_messages<C, F, M>(
&self,
chat_id: C,
from_chat_id: F,
message_ids: M,
) -> Self::CopyMessages
where
C: Into<Recipient>,
F: Into<Recipient>,
M: IntoIterator<Item = MessageId>;
type SendPhoto: Request<Payload = SendPhoto, Err = Self::Err>;
/// For Telegram documentation see [`SendPhoto`].
@ -385,6 +413,17 @@ pub trait Requester {
where
C: Into<Recipient>;
type SetMessageReaction: Request<Payload = SetMessageReaction, Err = Self::Err>;
/// For Telegram documentation see [`SetMessageReaction`].
fn set_message_reaction<C>(
&self,
chat_id: C,
message_id: MessageId,
) -> Self::SetMessageReaction
where
C: Into<Recipient>;
type GetUserProfilePhotos: Request<Payload = GetUserProfilePhotos, Err = Self::Err>;
/// For Telegram documentation see [`GetUserProfilePhotos`].
@ -663,7 +702,7 @@ pub trait Requester {
&self,
chat_id: C,
name: N,
icon_color: u32,
icon_color: Rgb,
icon_custom_emoji_id: I,
) -> Self::CreateForumTopic
where
@ -778,6 +817,13 @@ pub trait Requester {
where
C: Into<String>;
type GetUserChatBoosts: Request<Payload = GetUserChatBoosts, Err = Self::Err>;
/// For Telegram documentation see [`GetUserChatBoosts`].
fn get_user_chat_boosts<C>(&self, chat_id: C, user_id: UserId) -> Self::GetUserChatBoosts
where
C: Into<Recipient>;
type SetMyCommands: Request<Payload = SetMyCommands, Err = Self::Err>;
/// For Telegram documentation see [`SetMyCommands`].
@ -785,6 +831,14 @@ pub trait Requester {
where
C: IntoIterator<Item = BotCommand>;
type GetBusinessConnection: Request<Payload = GetBusinessConnection, Err = Self::Err>;
/// For Telegram documentation see [`GetBusinessConnection`].
fn get_business_connection(
&self,
business_connection_id: BusinessConnectionId,
) -> Self::GetBusinessConnection;
type GetMyCommands: Request<Payload = GetMyCommands, Err = Self::Err>;
/// For Telegram documentation see [`GetMyCommands`].
@ -977,6 +1031,14 @@ pub trait Requester {
where
C: Into<Recipient>;
type DeleteMessages: Request<Payload = DeleteMessages, Err = Self::Err>;
/// For Telegram documentation see [`DeleteMessages`].
fn delete_messages<C, M>(&self, chat_id: C, message_ids: M) -> Self::DeleteMessages
where
C: Into<Recipient>,
M: IntoIterator<Item = MessageId>;
type SendSticker: Request<Payload = SendSticker, Err = Self::Err>;
/// For Telegram documentation see [`SendSticker`].
@ -1017,7 +1079,6 @@ pub trait Requester {
name: N,
title: T,
stickers: S,
sticker_format: StickerFormat,
) -> Self::CreateNewStickerSet
where
N: Into<String>,
@ -1054,6 +1115,20 @@ pub trait Requester {
where
S: Into<String>;
type ReplaceStickerInSet: Request<Payload = ReplaceStickerInSet, Err = Self::Err>;
/// For Telegram documentation see [`ReplaceStickerInSet`].
fn replace_sticker_in_set<N, O>(
&self,
user_id: UserId,
name: N,
old_sticker: O,
sticker: InputSticker,
) -> Self::ReplaceStickerInSet
where
N: Into<String>,
O: Into<String>;
type SetStickerSetThumbnail: Request<Payload = SetStickerSetThumbnail, Err = Self::Err>;
/// For Telegram documentation see [`SetStickerSetThumbnail`].
@ -1061,6 +1136,7 @@ pub trait Requester {
&self,
name: N,
user_id: UserId,
format: StickerFormat,
) -> Self::SetStickerSetThumbnail
where
N: Into<String>;
@ -1249,7 +1325,9 @@ macro_rules! forward_all {
delete_webhook,
get_webhook_info,
forward_message,
forward_messages,
copy_message,
copy_messages,
send_message,
send_photo,
send_audio,
@ -1269,6 +1347,7 @@ macro_rules! forward_all {
send_poll,
send_dice,
send_chat_action,
set_message_reaction,
get_user_profile_photos,
get_file,
kick_chat_member,
@ -1313,7 +1392,9 @@ macro_rules! forward_all {
unhide_general_forum_topic,
unpin_all_general_forum_topic_messages,
answer_callback_query,
get_user_chat_boosts,
set_my_commands,
get_business_connection,
get_my_commands,
set_my_name,
get_my_name,
@ -1338,6 +1419,7 @@ macro_rules! forward_all {
edit_message_reply_markup_inline,
stop_poll,
delete_message,
delete_messages,
send_sticker,
get_sticker_set,
get_custom_emoji_stickers,
@ -1346,6 +1428,7 @@ macro_rules! forward_all {
add_sticker_to_set,
set_sticker_position_in_set,
delete_sticker_from_set,
replace_sticker_in_set,
set_sticker_set_thumbnail,
set_custom_emoji_sticker_set_thumbnail,
set_sticker_set_title,

View file

@ -90,7 +90,7 @@ mod tests {
types::{
ChatId, InputFile, InputMedia, InputMediaAnimation, InputMediaAudio,
InputMediaDocument, InputMediaPhoto, InputMediaVideo, InputSticker, MessageEntity,
MessageEntityKind, ParseMode, UserId,
MessageEntityKind, ParseMode, StickerFormat, UserId,
},
};
@ -157,6 +157,7 @@ mod tests {
emoji_list: vec!["✈️⚙️".to_owned()],
keywords: vec![],
mask_position: None,
format: StickerFormat::Static,
},
))
.unwrap()
@ -173,8 +174,7 @@ mod tests {
.caption_entities(entities())
.thumbnail(InputFile::read(
File::open("../../media/teloxide-core-logo.png").await.unwrap(),
))
.allow_sending_without_reply(true),
)),
)
.unwrap()
.await;

View file

@ -3,16 +3,29 @@
pub use allowed_update::*;
pub use animation::*;
pub use audio::*;
pub use birthdate::*;
pub use bot_command::*;
pub use bot_command_scope::*;
pub use bot_description::*;
pub use bot_name::*;
pub use bot_short_description::*;
pub use business_connection::*;
pub use business_connection_id::*;
pub use business_intro::*;
pub use business_location::*;
pub use business_messages_deleted::*;
pub use business_opening_hours::*;
pub use business_opening_hours_interval::*;
pub use callback_game::*;
pub use callback_query::*;
pub use chat::*;
pub use chat_action::*;
pub use chat_administrator_rights::*;
pub use chat_boost::*;
pub use chat_boost_added::*;
pub use chat_boost_removed::*;
pub use chat_boost_source::*;
pub use chat_boost_updated::*;
pub use chat_full_info::*;
pub use chat_invite_link::*;
pub use chat_join_request::*;
@ -30,6 +43,7 @@ pub use dice_emoji::*;
pub use document::*;
pub use encrypted_credentials::*;
pub use encrypted_passport_element::*;
pub use external_reply_info::*;
pub use file::*;
pub use force_reply::*;
pub use forum_topic::*;
@ -41,6 +55,11 @@ pub use game::*;
pub use game_high_score::*;
pub use general_forum_topic_hidden::*;
pub use general_forum_topic_unhidden::*;
pub use giveaway::*;
pub use giveaway_completed::*;
pub use giveaway_created::*;
pub use giveaway_winners::*;
pub use inaccessible_message::*;
pub use inline_keyboard_button::*;
pub use inline_keyboard_markup::*;
pub use inline_query::*;
@ -74,17 +93,23 @@ pub use invoice::*;
pub use keyboard_button::*;
pub use keyboard_button_poll_type::*;
pub use keyboard_button_request_chat::*;
pub use keyboard_button_request_user::*;
pub use keyboard_button_request_users::*;
pub use label_price::*;
pub use link_preview_options::*;
pub use location::*;
pub use login_url::*;
pub use mask_position::*;
pub use maybe_anonymous_user::*;
pub use maybe_inaccessible_message::*;
pub use me::*;
pub use menu_button::*;
pub use message::*;
pub use message_auto_delete_timer_changed::*;
pub use message_entity::*;
pub use message_id::*;
pub use message_origin::*;
pub use message_reaction_count_updated::*;
pub use message_reaction_updated::*;
pub use order_info::*;
pub use parse_mode::*;
pub use passport_data::*;
@ -96,27 +121,35 @@ pub use poll_answer::*;
pub use poll_type::*;
pub use pre_checkout_query::*;
pub use proximity_alert_triggered::*;
pub use reaction_type::*;
pub use reply_keyboard_markup::*;
pub use reply_keyboard_remove::*;
pub use reply_markup::*;
pub use reply_parameters::*;
pub use request_id::*;
pub use response_parameters::*;
pub use rgb::*;
pub use sent_web_app_message::*;
pub use shared_user::*;
pub use shipping_address::*;
pub use shipping_option::*;
pub use shipping_query::*;
pub use sticker::*;
pub use sticker_set::*;
pub use story::*;
pub use story_id::*;
pub use successful_payment::*;
pub use switch_inline_query_chosen_chat::*;
pub use target_message::*;
pub use text_quote::*;
pub use thread_id::*;
pub use unit_false::*;
pub use unit_true::*;
pub use update::*;
pub use user::*;
pub use user_chat_boosts::*;
pub use user_profile_photos::*;
pub use user_shared::*;
pub use users_shared::*;
pub use venue::*;
pub use video::*;
pub use video_chat_ended::*;
@ -133,16 +166,28 @@ pub use write_access_allowed::*;
mod allowed_update;
mod animation;
mod audio;
mod birthdate;
mod bot_command;
mod bot_command_scope;
mod bot_description;
mod bot_name;
mod bot_short_description;
mod business_connection;
mod business_connection_id;
mod business_intro;
mod business_location;
mod business_messages_deleted;
mod business_opening_hours;
mod business_opening_hours_interval;
mod callback_game;
mod callback_query;
mod chat;
mod chat_action;
mod chat_administrator_rights;
mod chat_boost;
mod chat_boost_removed;
mod chat_boost_source;
mod chat_boost_updated;
mod chat_full_info;
mod chat_invite_link;
mod chat_join_request;
@ -158,6 +203,7 @@ mod contact;
mod dice;
mod dice_emoji;
mod document;
mod external_reply_info;
mod file;
mod force_reply;
mod forum_topic;
@ -169,6 +215,11 @@ mod game;
mod game_high_score;
mod general_forum_topic_hidden;
mod general_forum_topic_unhidden;
mod giveaway;
mod giveaway_completed;
mod giveaway_created;
mod giveaway_winners;
mod inaccessible_message;
mod inline_keyboard_button;
mod inline_keyboard_markup;
mod inline_query_results_button;
@ -180,17 +231,23 @@ mod invoice;
mod keyboard_button;
mod keyboard_button_poll_type;
mod keyboard_button_request_chat;
mod keyboard_button_request_user;
mod keyboard_button_request_users;
mod label_price;
mod link_preview_options;
mod location;
mod login_url;
mod mask_position;
mod maybe_anonymous_user;
mod maybe_inaccessible_message;
mod me;
mod menu_button;
mod message;
mod message_auto_delete_timer_changed;
mod message_entity;
mod message_id;
mod message_origin;
mod message_reaction_count_updated;
mod message_reaction_updated;
mod order_info;
mod parse_mode;
mod photo_size;
@ -199,11 +256,16 @@ mod poll_answer;
mod poll_type;
mod pre_checkout_query;
mod proximity_alert_triggered;
mod reaction_type;
mod reply_keyboard_markup;
mod reply_keyboard_remove;
mod reply_markup;
mod reply_parameters;
mod request_id;
mod response_parameters;
mod rgb;
mod sent_web_app_message;
mod shared_user;
mod shipping_address;
mod shipping_option;
mod shipping_query;
@ -213,13 +275,15 @@ mod story;
mod successful_payment;
mod switch_inline_query_chosen_chat;
mod target_message;
mod text_quote;
mod thread_id;
mod unit_false;
mod unit_true;
mod update;
mod user;
mod user_chat_boosts;
mod user_profile_photos;
mod user_shared;
mod users_shared;
mod venue;
mod video;
mod video_chat_ended;
@ -233,6 +297,7 @@ mod web_app_info;
mod webhook_info;
mod write_access_allowed;
mod chat_boost_added;
mod inline_query;
mod inline_query_result;
mod inline_query_result_article;
@ -255,6 +320,7 @@ mod inline_query_result_photo;
mod inline_query_result_venue;
mod inline_query_result_video;
mod inline_query_result_voice;
mod story_id;
mod encrypted_credentials;
mod encrypted_passport_element;
@ -262,10 +328,9 @@ mod passport_data;
mod passport_element_error;
mod passport_file;
pub use non_telegram_types::{country_code::*, currency::*, until_date::*};
pub use non_telegram_types::{country_code::*, until_date::*};
mod non_telegram_types {
pub(super) mod country_code;
pub(super) mod currency;
pub(crate) mod mime;
pub(super) mod until_date;
}
@ -280,7 +345,11 @@ pub use recipient::*;
pub use seconds::*;
pub use user_id::*;
use serde::Serialize;
use serde_with::with_prefix;
// Deserialization prefix for giveaway_message_id field used in GiveawayWinners
// and ChatBoostSourceGiveaway
with_prefix!(prefix_giveaway_message_id "giveaway_");
/// Converts an `i64` timestamp to a `choro::DateTime`, producing serde error
/// for invalid timestamps
@ -403,6 +472,45 @@ pub(crate) mod option_url_from_string {
}
}
// Issue https://github.com/teloxide/teloxide/issues/1135
// Workaround to avoid flattening with serde-multipart requests (involving
// file-manipulations)
pub(crate) mod msg_id_as_int {
use crate::types::MessageId;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub(crate) fn serialize<S>(MessageId(id): &MessageId, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
id.serialize(serializer)
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<MessageId, D::Error>
where
D: Deserializer<'de>,
{
i32::deserialize(deserializer).map(MessageId)
}
#[test]
fn test() {
#[derive(Serialize, Deserialize)]
struct Struct {
#[serde(with = "crate::types::msg_id_as_int")]
message_id: MessageId,
}
{
let json = r#"{"message_id":123}"#;
let s: Struct = serde_json::from_str(json).unwrap();
assert_eq!(s.message_id, MessageId(123));
assert_eq!(serde_json::to_string(&s).unwrap(), json.to_owned());
}
}
}
pub(crate) mod option_msg_id_as_int {
use crate::types::MessageId;
@ -438,77 +546,3 @@ pub(crate) mod option_msg_id_as_int {
}
}
}
pub(crate) fn serialize_reply_to_message_id<S>(
this: &Option<MessageId>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
this.map(|MessageId(id)| id).serialize(serializer)
}
pub(crate) mod serde_rgb {
use serde::{de::Visitor, Deserializer, Serializer};
pub fn serialize<S: Serializer>(&this: &[u8; 3], s: S) -> Result<S::Ok, S::Error> {
s.serialize_u32(to_u32(this))
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<[u8; 3], D::Error> {
struct V;
impl Visitor<'_> for V {
type Value = [u8; 3];
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an integer represeting an RGB color")
}
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(from_u32(v))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u32(v.try_into().map_err(|_| E::custom("rgb value doesn't fit u32"))?)
}
}
d.deserialize_u32(V)
}
fn to_u32([r, g, b]: [u8; 3]) -> u32 {
u32::from_be_bytes([0, r, g, b])
}
fn from_u32(rgb: u32) -> [u8; 3] {
let [_, r, g, b] = rgb.to_be_bytes();
[r, g, b]
}
#[test]
fn bytes() {
assert_eq!(to_u32([0xAA, 0xBB, 0xCC]), 0x00AABBCC);
assert_eq!(from_u32(0x00AABBCC), [0xAA, 0xBB, 0xCC]);
}
#[test]
fn json() {
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
struct Struct {
#[serde(with = "self")]
color: [u8; 3],
}
let json = format!(r#"{{"color":{}}}"#, 0x00AABBCC);
let Struct { color } = serde_json::from_str(&json).unwrap();
assert_eq!(color, [0xAA, 0xBB, 0xCC])
}
}

View file

@ -7,6 +7,12 @@ pub enum AllowedUpdate {
EditedMessage,
ChannelPost,
EditedChannelPost,
BusinessConnection,
BusinessMessage,
EditedBusinessMessage,
DeletedBusinessMessages,
MessageReaction,
MessageReactionCount,
InlineQuery,
ChosenInlineResult,
CallbackQuery,
@ -17,4 +23,6 @@ pub enum AllowedUpdate {
MyChatMember,
ChatMember,
ChatJoinRequest,
ChatBoost,
RemovedChatBoost,
}

View file

@ -0,0 +1,15 @@
use serde::{Deserialize, Serialize};
/// Describes the birthdate of a user.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Birthdate {
/// Day of the user's birth; 1-31
pub day: u8,
/// Month of the user's birth; 1-12
pub month: u8,
/// Year of the user's birth
pub year: Option<u32>,
}

View file

@ -0,0 +1,29 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::types::{BusinessConnectionId, User, UserId};
/// Describes the connection of the bot with a business account.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct BusinessConnection {
/// Unique identifier of the business connection
pub id: BusinessConnectionId,
/// Business account user that created the business connection
pub user: User,
/// The user id of the private chat with the user who created the business
/// connection
pub user_chat_id: UserId,
/// Date the connection was established in Unix time
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub date: DateTime<Utc>,
/// `true`, if the bot can act on behalf of the business account in chats
/// that were active in the last 24 hours
pub can_reply: bool,
/// `true`, if the connection is alive
pub is_enabled: bool,
}

View file

@ -0,0 +1,25 @@
use serde::{Deserialize, Serialize};
/// A unique business connection identifier.
#[derive(Default, Clone, Debug, derive_more::Display, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct BusinessConnectionId(pub String);
#[cfg(test)]
mod tests {
use crate::types::BusinessConnectionId;
#[test]
fn business_connection_id_deser() {
let json = r#""abcd1234""#;
let bcid: BusinessConnectionId = serde_json::from_str(json).unwrap();
assert_eq!(bcid, BusinessConnectionId(String::from("abcd1234")));
}
#[test]
fn business_connection_id_ser() {
let bcid: BusinessConnectionId = BusinessConnectionId(String::from("abcd1234"));
let json = serde_json::to_string(&bcid).unwrap();
assert_eq!(json, r#""abcd1234""#);
}
}

View file

@ -0,0 +1,16 @@
use serde::{Deserialize, Serialize};
use crate::types::Sticker;
/// An introduction for a Business.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct BusinessIntro {
/// Title text of the business intro
pub title: Option<String>,
/// Message text of the business intro
pub message: Option<String>,
/// Sticker of the business intro
pub sticker: Option<Sticker>,
}

View file

@ -0,0 +1,13 @@
use serde::{Deserialize, Serialize};
use crate::types::Location;
/// Details about the location of a Business
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct BusinessLocation {
/// Address of the business.
pub address: String,
/// Location of the business.
pub location: Option<Location>,
}

View file

@ -0,0 +1,19 @@
use serde::{Deserialize, Serialize};
use crate::types::{BusinessConnectionId, Chat, MessageId};
/// This object is received when messages are deleted from a connected business
/// account.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct BusinessMessagesDeleted {
/// Unique identifier of the business connection.
pub business_connection_id: BusinessConnectionId,
/// Information about a chat in the business account. The bot may not have
/// access to the chat or the corresponding user.
pub chat: Chat,
/// The list of identifiers of deleted messages in the chat of the business
/// account.
pub message_ids: Vec<MessageId>,
}

View file

@ -0,0 +1,13 @@
use serde::{Deserialize, Serialize};
use crate::types::BusinessOpeningHoursInterval;
/// Details about the opening hours of a Business.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct BusinessOpeningHours {
/// Unique name of the time zone for which the opening hours are defined.
pub time_zone_name: String,
/// List of time intervals describing business opening hours.
pub opening_hours: Vec<BusinessOpeningHoursInterval>,
}

View file

@ -0,0 +1,15 @@
use serde::{Deserialize, Serialize};
/// Time intervals used to describe the opening hours of a Business.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct BusinessOpeningHoursInterval {
/// The minute's sequence number in a week, starting on Monday, marking the
/// start of the time interval during which the business is open;
/// 0 - 7 * 24* 60
pub opening_minute: u16,
/// The minute's sequence number in a week, starting on Monday, marking the
/// end of the time interval during which the business is open;
/// 0 - 8 * 24* 60
pub closing_minute: u16,
}

View file

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use crate::types::{Message, User};
use crate::types::{MaybeInaccessibleMessage, Message, User};
/// This object represents an incoming callback query from a callback button in
/// an [inline keyboard].
@ -24,10 +24,12 @@ pub struct CallbackQuery {
/// A sender.
pub from: User,
/// A 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.
pub message: Option<Message>,
/// Message sent by the bot with the callback button that originated the
/// query.
///
/// Note: if the message is too old, it will be
/// [`MaybeInaccessibleMessage::Inaccessible`].
pub message: Option<MaybeInaccessibleMessage>,
/// An identifier of the message sent via the bot in inline mode, that
/// originated the query.
@ -58,7 +60,15 @@ impl CallbackQuery {
use crate::util::flatten;
use std::iter::once;
once(&self.from).chain(flatten(self.message.as_ref().map(Message::mentioned_users)))
once(&self.from).chain(flatten(self.regular_message().map(Message::mentioned_users)))
}
#[must_use]
pub fn regular_message(&self) -> Option<&Message> {
self.message
.as_ref()
// If we can access the message
.and_then(|maybe| maybe.regular_message())
}
}

View file

@ -1,7 +1,8 @@
use serde::{Deserialize, Serialize};
use crate::types::{
ChatFullInfo, ChatId, ChatLocation, ChatPermissions, ChatPhoto, Message, Seconds, True, User,
Birthdate, BusinessIntro, BusinessLocation, BusinessOpeningHours, ChatFullInfo, ChatId,
ChatLocation, ChatPermissions, ChatPhoto, Message, ReactionType, Seconds, True, User,
};
/// This object represents a chat.
@ -21,6 +22,12 @@ pub struct Chat {
/// [`GetChat`]: crate::payloads::GetChat
pub photo: Option<ChatPhoto>,
/// List of available reactions allowed in the chat. If omitted, then all
/// emoji reactions are allowed. Returned only from [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub available_reactions: Option<Vec<ReactionType>>,
/// The most recent pinned message (by sending date). Returned only in
/// [`GetChat`].
///
@ -56,7 +63,7 @@ pub struct Chat {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ChatKind {
Public(ChatPublic),
Public(Box<ChatPublic>),
Private(ChatPrivate),
}
@ -108,13 +115,6 @@ pub struct ChatPrivate {
/// A last name of the other party in a private chat.
pub last_name: Option<String>,
/// Custom emoji identifier of emoji status of the other party in a private
/// chat. Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
// FIXME: CustomEmojiId
pub emoji_status_custom_emoji_id: Option<String>,
/// Bio of the other party in a private chat. Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
@ -133,6 +133,36 @@ pub struct ChatPrivate {
///
/// [`GetChat`]: crate::payloads::GetChat
pub has_restricted_voice_and_video_messages: Option<True>,
/// For private chats, the personal channel of the user. Returned only in
/// [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub personal_chat: Option<Box<Chat>>,
/// For private chats, the date of birth of the user. Returned only in
/// [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub birthdate: Option<Birthdate>,
/// For private chats with business accounts, the intro of the business.
/// Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub business_intro: Option<BusinessIntro>,
/// For private chats with business accounts, the location of the business.
/// Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub business_location: Option<BusinessLocation>,
/// For private chats with business accounts, the opening hours of the
/// business. Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub business_opening_hours: Option<BusinessOpeningHours>,
}
#[serde_with::skip_serializing_none]
@ -197,6 +227,13 @@ pub struct PublicChatSupergroup {
/// [`GetChat`]: crate::payloads::GetChat
pub can_set_sticker_set: Option<bool>,
/// For supergroups, the name of the group's custom emoji sticker set.
/// Custom emoji from this set can be used by all users and bots in the
/// group. Returned only from [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub custom_emoji_sticker_set_name: Option<String>,
/// A default chat member permissions, for groups and supergroups.
/// Returned only from [`GetChat`].
///
@ -209,6 +246,13 @@ pub struct PublicChatSupergroup {
/// [`GetChat`]: crate::payloads::GetChat
pub slow_mode_delay: Option<Seconds>,
/// For supergroups, the minimum number of boosts that a non-administrator
/// user needs to add in order to ignore slow mode and chat permissions.
/// Returned only from [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
pub unrestrict_boost_count: Option<u16>,
/// Unique identifier for the linked chat, i.e. the discussion group
/// identifier for a channel and vice versa. Returned only in [`GetChat`].
///
@ -242,20 +286,29 @@ impl Chat {
#[must_use]
pub fn is_group(&self) -> bool {
matches!(self.kind, ChatKind::Public(ChatPublic { kind: PublicChatKind::Group(_), .. }))
if let ChatKind::Public(chat_pub) = &self.kind {
matches!(**chat_pub, ChatPublic { kind: PublicChatKind::Group(_), .. })
} else {
false
}
}
#[must_use]
pub fn is_supergroup(&self) -> bool {
matches!(
self.kind,
ChatKind::Public(ChatPublic { kind: PublicChatKind::Supergroup(_), .. })
)
if let ChatKind::Public(chat_pub) = &self.kind {
matches!(**chat_pub, ChatPublic { kind: PublicChatKind::Supergroup(_), .. })
} else {
false
}
}
#[must_use]
pub fn is_channel(&self) -> bool {
matches!(self.kind, ChatKind::Public(ChatPublic { kind: PublicChatKind::Channel(_), .. }))
if let ChatKind::Public(chat_pub) = &self.kind {
matches!(**chat_pub, ChatPublic { kind: PublicChatKind::Channel(_), .. })
} else {
false
}
}
#[must_use]
@ -355,6 +408,22 @@ impl Chat {
None
}
/// For supergroups, the name of the group's custom emoji sticker set.
/// Custom emoji from this set can be used by all users and bots in the
/// group. Returned only from [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
#[must_use]
pub fn custom_emoji_sticker_set_name(&self) -> Option<&str> {
if let ChatKind::Public(this) = &self.kind {
if let PublicChatKind::Supergroup(this) = &this.kind {
return this.custom_emoji_sticker_set_name.as_deref();
}
}
None
}
/// The minimum allowed delay between consecutive messages sent by each
/// unpriviledged user. Returned only from [`GetChat`].
///
@ -370,6 +439,21 @@ impl Chat {
None
}
/// Unique identifier for the linked chat, i.e. the discussion group
/// identifier for a channel and vice versa. Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
#[must_use]
pub fn unrestrict_boost_count(&self) -> Option<u16> {
if let ChatKind::Public(this) = &self.kind {
if let PublicChatKind::Supergroup(this) = &this.kind {
return this.unrestrict_boost_count;
}
}
None
}
/// The location to which the supergroup is connected. Returned only in
/// [`GetChat`].
///
@ -518,7 +602,7 @@ impl Chat {
}
mod serde_helper {
use crate::types::True;
use crate::types::{Birthdate, BusinessIntro, BusinessLocation, BusinessOpeningHours, True};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
@ -539,7 +623,11 @@ mod serde_helper {
bio: Option<String>,
has_private_forwards: Option<True>,
has_restricted_voice_and_video_messages: Option<True>,
emoji_status_custom_emoji_id: Option<String>,
personal_chat: Option<Box<super::Chat>>,
birthdate: Option<Birthdate>,
business_intro: Option<BusinessIntro>,
business_location: Option<BusinessLocation>,
business_opening_hours: Option<BusinessOpeningHours>,
}
impl From<ChatPrivate> for super::ChatPrivate {
@ -552,7 +640,11 @@ mod serde_helper {
bio,
has_private_forwards,
has_restricted_voice_and_video_messages,
emoji_status_custom_emoji_id,
personal_chat,
birthdate,
business_intro,
business_location,
business_opening_hours,
}: ChatPrivate,
) -> Self {
Self {
@ -562,7 +654,11 @@ mod serde_helper {
bio,
has_private_forwards,
has_restricted_voice_and_video_messages,
emoji_status_custom_emoji_id,
personal_chat,
birthdate,
business_intro,
business_location,
business_opening_hours,
}
}
}
@ -576,7 +672,11 @@ mod serde_helper {
bio,
has_private_forwards,
has_restricted_voice_and_video_messages,
emoji_status_custom_emoji_id,
personal_chat,
birthdate,
business_intro,
business_location,
business_opening_hours,
}: super::ChatPrivate,
) -> Self {
Self {
@ -587,7 +687,11 @@ mod serde_helper {
bio,
has_private_forwards,
has_restricted_voice_and_video_messages,
emoji_status_custom_emoji_id,
personal_chat,
birthdate,
business_intro,
business_location,
business_opening_hours,
}
}
}
@ -603,7 +707,7 @@ mod tests {
fn channel_de() {
let expected = Chat {
id: ChatId(-1),
kind: ChatKind::Public(ChatPublic {
kind: ChatKind::Public(Box::new(ChatPublic {
title: None,
kind: PublicChatKind::Channel(PublicChatChannel {
username: Some("channel_name".into()),
@ -612,15 +716,29 @@ mod tests {
description: None,
invite_link: None,
has_protected_content: None,
}),
})),
photo: None,
available_reactions: Some(vec![ReactionType::Emoji { emoji: "🌭".to_owned() }]),
pinned_message: None,
message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
chat_full_info: ChatFullInfo { emoji_status_expiration_date: None },
chat_full_info: ChatFullInfo::default(),
};
let actual = from_str(r#"{"id":-1,"type":"channel","username":"channel_name"}"#).unwrap();
let actual = from_str(
r#"{
"id": -1,
"type": "channel",
"username": "channel_name",
"available_reactions": [
{
"type": "emoji",
"emoji": "🌭"
}
]
}"#,
)
.unwrap();
assert_eq!(expected, actual);
}
@ -636,17 +754,35 @@ mod tests {
bio: None,
has_private_forwards: None,
has_restricted_voice_and_video_messages: None,
emoji_status_custom_emoji_id: None
personal_chat: None,
birthdate: None,
business_intro: None,
business_location: None,
business_opening_hours: None,
}),
photo: None,
available_reactions: Some(vec![ReactionType::Emoji { emoji: "🌭".to_owned() }]),
pinned_message: None,
message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
chat_full_info: ChatFullInfo { emoji_status_expiration_date: None }
chat_full_info: ChatFullInfo::default()
},
from_str(r#"{"id":0,"type":"private","username":"username","first_name":"Anon"}"#)
.unwrap()
from_str(
r#"{
"id": 0,
"type": "private",
"username": "username",
"first_name": "Anon",
"available_reactions": [
{
"type": "emoji",
"emoji": "🌭"
}
]
}"#
)
.unwrap()
);
}
@ -661,14 +797,19 @@ mod tests {
bio: None,
has_private_forwards: None,
has_restricted_voice_and_video_messages: None,
emoji_status_custom_emoji_id: None,
personal_chat: None,
birthdate: None,
business_intro: None,
business_location: None,
business_opening_hours: None,
}),
photo: None,
available_reactions: None,
pinned_message: None,
message_auto_delete_time: None,
has_hidden_members: false,
has_aggressive_anti_spam_enabled: false,
chat_full_info: ChatFullInfo { emoji_status_expiration_date: None },
chat_full_info: ChatFullInfo::default(),
};
let json = to_string(&chat).unwrap();

View file

@ -47,16 +47,13 @@ pub struct ChatAdministratorRights {
/// supergroups only
pub can_pin_messages: Option<bool>,
/// `true`, if the administrator can post stories in the channel;
/// channels only
/// `true`, if the administrator can post stories to the chat
pub can_post_stories: Option<bool>,
/// `true`, if the administrator can edit stories posted by other users;
/// channels only
/// `true`, if the administrator can edit stories posted by other users
pub can_edit_stories: Option<bool>,
/// `true`, if the administrator can delete stories posted by other users;
/// channels only
/// `true`, if the administrator can delete stories posted by other users
pub can_delete_stories: Option<bool>,
/// `true`, if the user is allowed to create, rename, close, and reopen

View file

@ -0,0 +1,52 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::types::ChatBoostSource;
/// This object contains information about a chat boost.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatBoost {
/// Unique identifier of the boost.
pub boost_id: String,
/// Point in time (Unix timestamp) when the chat was boosted.
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub add_date: DateTime<Utc>,
/// Point in time (Unix timestamp) when the boost will automatically expire,
/// unless the booster's Telegram Premium subscription is prolonged.
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub expiration_date: DateTime<Utc>,
/// Source of the added boost.
pub source: ChatBoostSource,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"boost_id": "4506e1b7e866e33fcbde78fe1746ec3a",
"add_date": 1721399621,
"expiration_date": 1745088963,
"source": {
"source": "premium",
"user": {
"id": 1459074222,
"is_bot": false,
"first_name": "shadowchain",
"username": "shdwchn10",
"language_code": "en",
"is_premium": true
}
}
}
"#;
serde_json::from_str::<ChatBoost>(data).unwrap();
}
}

View file

@ -0,0 +1,24 @@
use serde::{Deserialize, Serialize};
/// This object represents a service message about a user boosting a chat.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatBoostAdded {
/// Number of boosts added by the user
pub boost_count: u16,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"boost_count": 4
}
"#;
serde_json::from_str::<ChatBoostAdded>(data).unwrap();
}
}

View file

@ -0,0 +1,55 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::types::{Chat, ChatBoostSource};
/// This object represents a boost removed from a chat.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatBoostRemoved {
/// Chat which was boosted
pub chat: Chat,
// FIXME: BoostId
/// Unique identifier of the boost
pub boost_id: String,
/// Point in time (Unix timestamp) when the boost was removed
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub remove_date: DateTime<Utc>,
/// Source of the removed boost
pub source: ChatBoostSource,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"chat": {
"id": -1002236736395,
"title": "Test",
"type": "channel"
},
"boost_id": "4506e1b7e866e33fcbde78fe1746ec3a",
"remove_date": 1745089963,
"source": {
"source": "premium",
"user": {
"id": 1459074222,
"is_bot": false,
"first_name": "shadowchain",
"username": "shdwchn10",
"language_code": "en",
"is_premium": true
}
}
}
"#;
serde_json::from_str::<ChatBoostRemoved>(data).unwrap();
}
}

View file

@ -0,0 +1,124 @@
use serde::{Deserialize, Serialize};
use crate::types::{MessageId, User};
/// This object describes the source of a chat boost.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "source")]
pub enum ChatBoostSource {
Premium(ChatBoostSourcePremium),
GiftCode(ChatBoostSourceGiftCode),
Giveaway(ChatBoostSourceGiveaway),
}
/// The boost was obtained by subscribing to Telegram Premium or by gifting a
/// Telegram Premium subscription to another user.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatBoostSourcePremium {
/// User that boosted the chat.
pub user: User,
}
/// 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 the
/// corresponding Telegram Premium subscription.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatBoostSourceGiftCode {
/// User for which the gift code was created.
pub user: User,
}
/// 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.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatBoostSourceGiveaway {
/// 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.
#[serde(flatten, with = "crate::types::prefix_giveaway_message_id")]
pub giveaway_message_id: MessageId,
/// User that won the prize in the giveaway if any.
pub user: Option<User>,
/// `true`, if the giveaway was completed, but there was no user to win the
/// prize.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub is_unclaimed: bool,
}
impl ChatBoostSource {
#[must_use]
pub fn user(&self) -> Option<&User> {
Some(match &self {
Self::Premium(premium) => &premium.user,
Self::GiftCode(gift_code) => &gift_code.user,
Self::Giveaway(giveaway) => return giveaway.user.as_ref(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize_premium() {
let data = r#"
{
"source": "premium",
"user": {
"id": 1459074222,
"is_bot": false,
"first_name": "shadowchain",
"username": "shdwchn10",
"language_code": "en",
"is_premium": true
}
}
"#;
serde_json::from_str::<ChatBoostSource>(data).unwrap();
}
#[test]
fn deserialize_gift_code() {
let data = r#"
{
"source": "gift_code",
"user": {
"id": 1459074222,
"is_bot": false,
"first_name": "shadowchain",
"username": "shdwchn10",
"language_code": "en",
"is_premium": false
}
}
"#;
serde_json::from_str::<ChatBoostSource>(data).unwrap();
}
#[test]
fn deserialize_giveaway() {
let data = r#"
{
"source": "giveaway",
"giveaway_message_id": 420,
"user": {
"id": 1459074222,
"is_bot": false,
"first_name": "shadowchain",
"username": "shdwchn10",
"language_code": "en",
"is_premium": false
}
}
"#;
serde_json::from_str::<ChatBoostSource>(data).unwrap();
}
}

View file

@ -0,0 +1,49 @@
use serde::{Deserialize, Serialize};
use crate::types::{Chat, ChatBoost};
/// This object represents a boost added to a chat or changed.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatBoostUpdated {
/// Chat which was boosted
pub chat: Chat,
/// Infomation about the chat boost
pub boost: ChatBoost,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"chat": {
"id": -1002236736395,
"title": "Test",
"type": "channel"
},
"boost": {
"boost_id": "4506e1b7e866e33fcbde78fe1746ec3a",
"add_date": 1721399621,
"expiration_date": 1745088963,
"source": {
"source": "premium",
"user": {
"id": 1459074222,
"is_bot": false,
"first_name": "shadowchain",
"username": "shdwchn10",
"language_code": "en",
"is_premium": true
}
}
}
}
"#;
serde_json::from_str::<ChatBoostUpdated>(data).unwrap();
}
}

View file

@ -4,12 +4,43 @@ use serde::{Deserialize, Serialize};
// TODO: in the TBA7.3 the Chat will be splitted into Chat and ChatInfo
// Currently it's just a container for the some fields of the Chat struct
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ChatFullInfo {
/// 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.
///
/// [accent colors]: https://core.telegram.org/bots/api#accent-colors
pub accent_color_id: Option<u8>,
/// Custom emoji identifier of the emoji chosen by the chat for the reply
/// header and link preview background
// FIXME: CustomEmojiId
pub background_custom_emoji_id: Option<String>,
/// Identifier of the accent color for the chat's profile background. See
/// [profile accent colors] for more details.
///
/// [profile accent colors]: https://core.telegram.org/bots/api#profile-accent-colors
pub profile_accent_color_id: Option<u8>,
/// Custom emoji identifier of the emoji chosen by the chat for its profile
/// background
// FIXME: CustomEmojiId
pub profile_background_custom_emoji_id: Option<String>,
/// Custom emoji identifier of emoji status of the other party in a private
/// chat. Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
// FIXME: CustomEmojiId
pub emoji_status_custom_emoji_id: Option<String>,
/// Expiration date of the emoji status of the chat or the other party in a
/// private chat, in Unix time, if any
#[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")]
pub emoji_status_expiration_date: Option<DateTime<Utc>>,
/// True, if new chat members will have access to old messages; available
/// only to chat administrators. Returned only in [`GetChat`].
///
/// [`GetChat`]: crate::payloads::GetChat
#[serde(default)]
pub has_visible_history: bool,
}
#[cfg(test)]
@ -18,18 +49,18 @@ mod tests {
#[test]
fn test_chat_full_info_de() {
assert_eq!(
serde_json::from_str::<ChatFullInfo>("{}").unwrap(),
ChatFullInfo { emoji_status_expiration_date: None }
);
assert_eq!(serde_json::from_str::<ChatFullInfo>("{}").unwrap(), ChatFullInfo::default());
assert_eq!(
serde_json::from_str::<ChatFullInfo>(
r#"{
"emoji_status_expiration_date": 1720708004
}"#
"emoji_status_expiration_date": 1720708004
}"#
)
.unwrap(),
ChatFullInfo { emoji_status_expiration_date: DateTime::from_timestamp(1720708004, 0) }
ChatFullInfo {
emoji_status_expiration_date: DateTime::from_timestamp(1720708004, 0),
..ChatFullInfo::default()
}
);
}
}

View file

@ -80,18 +80,15 @@ pub struct Administrator {
/// `true` if the administrator can delete messages of other users.
pub can_delete_messages: bool,
/// `true` if the administrator can post stories in the channel, channels
/// only.
/// `true` if the administrator can post stories to the chat.
#[serde(default)]
pub can_post_stories: bool,
/// `true` if the administrator can edit stories posted by other users,
/// channels only.
/// `true` if the administrator can edit stories posted by other users.
#[serde(default)]
pub can_edit_stories: bool,
/// `true` if the administrator can delete stories posted by other users,
/// channels only.
/// `true` if the administrator can delete stories posted by other users.
#[serde(default)]
pub can_delete_stories: bool,
@ -447,8 +444,7 @@ impl ChatMemberKind {
}
}
/// Returns `true` if the user can post stories in the channel, channels
/// only.
/// Returns `true` if the administrator can post stories to the chat.
///
/// I.e. returns `true` if the user
/// - is the owner of the chat (even if the chat is not a channel)
@ -467,8 +463,8 @@ impl ChatMemberKind {
}
}
/// Returns `true` if the user can edit stories posted by other users,
/// channels only.
/// Returns `true` if the administrator can edit stories posted by other
/// users.
///
/// I.e. returns `true` if the user
/// - is the owner of the chat (even if the chat is not a channel)
@ -487,8 +483,8 @@ impl ChatMemberKind {
}
}
/// Returns `true` if the user can delete stories posted by other users,
/// channels only.
/// Returns `true` if the administrator can delete stories posted by other
/// users.
///
/// I.e. returns `true` if the user
/// - is the owner of the chat

View file

@ -1,15 +1,25 @@
use serde::{Deserialize, Serialize};
use crate::types::ChatId;
use crate::types::{ChatId, PhotoSize, RequestId};
/// Information about the chat whose identifier was shared with the bot using a
/// Information about a chat that was shared with the bot using a
/// [`KeyboardButtonRequestChat`] button.
///
/// [`KeyboardButtonRequestChat`]: crate::types::KeyboardButtonRequestChat
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ChatShared {
/// Identifier of the request.
pub request_id: i32,
pub request_id: RequestId,
/// Identifier of the shared chat.
pub chat_id: ChatId,
/// Title of the chat, if it was requested.
pub title: Option<String>,
/// Username of the chat, if it was requested.
pub username: Option<String>,
/// Available sizes of the chat photo, if it was requested.
pub photo: Option<Vec<PhotoSize>>,
}

View file

@ -0,0 +1,62 @@
use serde::{Deserialize, Serialize};
use crate::types::{
Animation, Audio, Chat, Contact, Dice, Document, Game, Giveaway, GiveawayWinners, Invoice,
LinkPreviewOptions, Location, MessageId, MessageOrigin, PhotoSize, Poll, Sticker, Story, Venue,
Video, VideoNote, Voice,
};
/// This object contains information about a message that is being replied to,
/// which may come from another chat or forum topic.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ExternalReplyInfo {
/// Origin of the message replied to by the given message.
pub origin: MessageOrigin,
/// Chat the original message belongs to. Available only if the chat is a
/// supergroup or a channel.
pub chat: Option<Chat>,
/// Unique message identifier inside the original chat. Available only if
/// the original chat is a supergroup or a channel.
#[serde(with = "crate::types::option_msg_id_as_int")]
pub message_id: Option<MessageId>,
/// Options used for link preview generation for the original message, if it
/// is a text message.
pub link_preview_options: Option<LinkPreviewOptions>,
/// _true_, if the message media is covered by a spoiler animation.
#[serde(default)]
pub has_media_spoiler: bool,
#[serde(flatten)]
pub kind: ExternalReplyInfoKind,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ExternalReplyInfoKind {
// Note:
// - `Venue` must be in front of `Location`
// - `Animation` must be in front of `Document`
//
// This is needed so serde doesn't parse `Venue` as `Location` or `Animation` as `Document`
// (for backward compatability telegram duplicates some fields).
//
// See <https://github.com/teloxide/teloxide/issues/481>
Animation(Animation),
Audio(Audio),
Contact(Contact),
Dice(Dice),
Document(Document),
Game(Game),
Venue(Venue),
Location(Location),
Photo(Vec<PhotoSize>),
Poll(Poll),
Sticker(Sticker),
Story(Story),
Giveaway(Giveaway),
GiveawayWinners(GiveawayWinners),
Video(Video),
VideoNote(VideoNote),
Voice(Voice),
Invoice(Invoice),
}

View file

@ -29,7 +29,7 @@ pub struct ForceReply {
/// (has reply_to_message_id), sender of the original message.
///
/// [`Message`]: crate::types::Message
#[serde(skip_serializing_if = "std::ops::Not::not")]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub selective: bool,
}
@ -54,3 +54,20 @@ impl ForceReply {
Self { selective: true, ..self }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"force_reply": true,
"input_field_placeholder": "placeholder",
"selective": false
}
"#;
serde_json::from_str::<ForceReply>(data).unwrap();
}
}

View file

@ -1,7 +1,7 @@
use crate::types::ThreadId;
use serde::{Deserialize, Serialize};
use crate::types::{Rgb, ThreadId};
/// This object represents a forum topic.
///
/// [The official docs](https://core.telegram.org/bots/api#forumtopiccreated).
@ -16,9 +16,7 @@ pub struct ForumTopic {
pub name: String,
/// Color of the topic icon in RGB format.
// FIXME: use/add a specialized rgb color type?
#[serde(with = "crate::types::serde_rgb")]
pub icon_color: [u8; 3],
pub icon_color: Rgb,
/// Unique identifier of the custom emoji shown as the topic icon.
// FIXME: CustomEmojiId

View file

@ -1,5 +1,7 @@
use serde::{Deserialize, Serialize};
use crate::types::Rgb;
/// This object represents a service message about a new forum topic created in
/// the chat.
///
@ -11,9 +13,7 @@ pub struct ForumTopicCreated {
pub name: String,
/// Color of the topic icon in RGB format.
// FIXME: use/add a specialized rgb color type?
#[serde(with = "crate::types::serde_rgb")]
pub icon_color: [u8; 3],
pub icon_color: Rgb,
/// Unique identifier of the custom emoji shown as the topic icon.
// FIXME: CustomEmojiId
@ -22,7 +22,7 @@ pub struct ForumTopicCreated {
#[cfg(test)]
mod tests {
use crate::types::ForumTopicCreated;
use super::*;
#[test]
fn deserialization() {
@ -32,7 +32,7 @@ mod tests {
let event = serde_json::from_str::<ForumTopicCreated>(json).unwrap();
assert_eq!(event.name, "???");
assert_eq!(event.icon_color, [0x8E, 0xEE, 0x98]);
assert_eq!(event.icon_color, Rgb { r: 0x8E, g: 0xEE, b: 0x98 });
assert_eq!(event.icon_custom_emoji_id.as_deref(), Some("5312536423851630001"));
}
}

View file

@ -0,0 +1,70 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::types::{Chat, CountryCode};
/// This object represents a message about a scheduled giveaway.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Giveaway {
/// The list of chats which the user must join to participate in the
/// giveaway.
pub chats: Vec<Chat>,
/// Point in time (Unix timestamp) when winners of the giveaway will be
/// selected
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub winners_selection_date: DateTime<Utc>,
/// The number of users which are supposed to be selected as winners of the
/// giveaway
pub winner_count: u32,
/// `true`, if only users who join the chats after the giveaway started
/// should be eligible to win
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub only_new_members: bool,
/// `true`, if the list of giveaway winners will be visible to everyone
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_public_winners: bool,
/// Description of additional giveaway prize
pub prize_description: Option<String>,
/// A list of two-letter [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/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.
pub country_codes: Option<Vec<CountryCode>>,
/// The number of months the Telegram Premium subscription won from the
/// giveaway will be active for
pub premium_subscription_month_count: Option<u8>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"chats": [
{
"id": -1002236736395,
"title": "Test",
"type": "channel"
}
],
"winners_selection_date": 1721162701,
"winner_count": 1,
"has_public_winners": true,
"premium_subscription_month_count": 6
}
"#;
serde_json::from_str::<Giveaway>(data).unwrap();
}
}

View file

@ -0,0 +1,61 @@
use serde::{Deserialize, Serialize};
use crate::types::Message;
/// This object represents a service message about the completion of a giveaway
/// without public winners.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct GiveawayCompleted {
/// Number of winners in the giveaway
pub winner_count: u32,
/// Number of undistributed prizes
pub unclaimed_prize_count: Option<u32>,
/// Message with the giveaway that was completed, if it wasn't deleted
pub giveaway_message: Option<Box<Message>>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"winner_count": 0,
"unclaimed_prize_count": 1,
"giveaway_message": {
"message_id": 24,
"sender_chat": {
"id": -1002236736395,
"title": "Test",
"type": "channel"
},
"chat": {
"id": -1002236736395,
"title": "Test",
"type": "channel"
},
"date": 1721161230,
"giveaway": {
"chats": [
{
"id": -1002236736395,
"title": "Test",
"type": "channel"
}
],
"winners_selection_date": 1721162701,
"winner_count": 1,
"has_public_winners": true,
"premium_subscription_month_count": 6
}
}
}
"#;
serde_json::from_str::<GiveawayCompleted>(data).unwrap();
}
}

View file

@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};
/// This object represents a service message about the creation of a scheduled
/// giveaway. Currently holds no information.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct GiveawayCreated {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"{}"#;
serde_json::from_str::<GiveawayCreated>(data).unwrap();
}
}

View file

@ -0,0 +1,83 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::types::{Chat, MessageId, User};
/// This object represents a message about the completion of a giveaway with
/// public winners.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct GiveawayWinners {
/// The chat that created the giveaway
pub chat: Chat,
/// Identifier of the messsage with the giveaway in the chat
#[serde(flatten, with = "crate::types::prefix_giveaway_message_id")]
pub giveaway_message_id: MessageId,
/// Point in time (Unix timestamp) when winners of the giveaway were
/// selected
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub winners_selection_date: DateTime<Utc>,
/// Total number of winners in the giveaway
pub winner_count: u32,
/// List of up to 100 winners of the giveaway
pub winners: Vec<User>,
/// The number of other chats the user had to join in order to be eligible
/// for the giveaway
pub additional_chat_count: Option<u16>,
/// The number of months the Telegram Premium subscription won from the
/// giveaway will be active for
pub premium_subscription_month_count: Option<u8>,
/// Number of undistributed prizes
pub unclaimed_prize_count: Option<u32>,
/// `true`, if only users who had joined the chats after the giveaway
/// started were eligible to win
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub only_new_members: bool,
/// `true`, if the giveaway was canceled because the payment for it was
/// refunded
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub was_refunded: bool,
/// Description of additional giveaway prize
pub prize_description: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize() {
let data = r#"
{
"chat": {
"id": -1002236736395,
"title": "Test",
"type": "channel"
},
"giveaway_message_id": 27,
"winners_selection_date": 1721162701,
"premium_subscription_month_count": 6,
"winner_count": 1,
"winners": [
{
"id": 1459074222,
"is_bot": false,
"first_name": "shadowchain",
"username": "shdwchn10"
}
]
}
"#;
serde_json::from_str::<GiveawayWinners>(data).unwrap();
}
}

View file

@ -0,0 +1,14 @@
use serde::{Deserialize, Serialize};
use crate::types::{Chat, MessageId};
/// This object describes a message that was deleted or is otherwise
/// inaccessible to the bot.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct InaccessibleMessage {
/// Chat the message belonged to
pub chat: Chat,
/// Unique message identifier inside the chat
#[serde(flatten)]
pub message_id: MessageId,
}

View file

@ -266,7 +266,7 @@ mod tests {
InlineQueryResultGif, InlineQueryResultLocation, InlineQueryResultMpeg4Gif,
InlineQueryResultPhoto, InlineQueryResultVenue, InlineQueryResultVideo,
InlineQueryResultVoice, InputMessageContent, InputMessageContentLocation,
InputMessageContentText, Seconds,
InputMessageContentText, LinkPreviewOptions, Seconds,
};
use mime::Mime;
@ -303,13 +303,19 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
caption_entities: None,
});
let expected_json = r#"{"type":"audio","id":"id","audio_file_id":"audio_file_id","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"audio","id":"id","audio_file_id":"audio_file_id","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -351,15 +357,21 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
caption_entities: None,
performer: Some(String::from("performer")),
audio_duration: Some(Seconds::from_seconds(1)),
});
let expected_json = r#"{"type":"audio","id":"id","audio_url":"http://audio_url/","title":"title","caption":"caption","parse_mode":"HTML","performer":"performer","audio_duration":1,"reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"audio","id":"id","audio_url":"http://audio_url/","title":"title","caption":"caption","parse_mode":"HTML","performer":"performer","audio_duration":1,"reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -400,13 +412,19 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
caption_entities: None,
});
let expected_json = r#"{"type":"document","id":"id","title":"title","document_file_id":"document_file_id","description":"description","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"document","id":"id","title":"title","document_file_id":"document_file_id","description":"description","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -453,15 +471,21 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
thumbnail_url: Some(reqwest::Url::parse("http://thumb_url/").unwrap()),
thumbnail_width: Some(1),
thumbnail_height: Some(1),
});
let expected_json = r#"{"type":"document","id":"id","title":"title","caption":"caption","parse_mode":"HTML","document_url":"http://document_url/","mime_type":"application/pdf","description":"description","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let expected_json = r#"{"type":"document","id":"id","title":"title","caption":"caption","parse_mode":"HTML","document_url":"http://document_url/","mime_type":"application/pdf","description":"description","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -501,12 +525,18 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
});
let expected_json = r#"{"type":"gif","id":"id","gif_file_id":"gif_file_id","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"gif","id":"id","gif_file_id":"gif_file_id","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -556,12 +586,18 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
});
let expected_json = r#"{"type":"gif","id":"id","gif_url":"http://gif_url/","gif_width":1,"gif_height":1,"gif_duration":1,"thumbnail_url":"http://thumb_url/","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"gif","id":"id","gif_url":"http://gif_url/","gif_width":1,"gif_height":1,"gif_duration":1,"thumbnail_url":"http://thumb_url/","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -601,12 +637,18 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
});
let expected_json = r#"{"type":"mpeg4_gif","id":"id","mpeg4_file_id":"mpeg4_file_id","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"mpeg4_gif","id":"id","mpeg4_file_id":"mpeg4_file_id","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -656,12 +698,18 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
});
let expected_json = r#"{"type":"mpeg4_gif","id":"id","mpeg4_url":"http://mpeg4_url/","mpeg4_width":1,"mpeg4_height":1,"mpeg4_duration":1,"thumbnail_url":"http://thumb_url/","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"mpeg4_gif","id":"id","mpeg4_url":"http://mpeg4_url/","mpeg4_width":1,"mpeg4_height":1,"mpeg4_duration":1,"thumbnail_url":"http://thumb_url/","title":"title","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -703,12 +751,18 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
});
let expected_json = r#"{"type":"photo","id":"id","photo_file_id":"photo_file_id","title":"title","description":"description","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"photo","id":"id","photo_file_id":"photo_file_id","title":"title","description":"description","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -756,12 +810,18 @@ mod tests {
input_message_content: Some(InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
});
let expected_json = r#"{"type":"photo","id":"id","photo_url":"http://photo_url/","thumbnail_url":"http://thumb_url/","photo_width":1,"photo_height":1,"title":"title","description":"description","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"photo","id":"id","photo_url":"http://photo_url/","thumbnail_url":"http://thumb_url/","photo_width":1,"photo_height":1,"title":"title","description":"description","caption":"caption","parse_mode":"HTML","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -794,11 +854,17 @@ mod tests {
message_text: String::from("message_text"),
entities: None,
parse_mode: Some(ParseMode::MarkdownV2),
disable_web_page_preview: Some(true),
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
});
let expected_json = r#"{"type":"sticker","id":"id","sticker_file_id":"sticker_file_id","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","disable_web_page_preview":true}}"#;
let expected_json = r#"{"type":"sticker","id":"id","sticker_file_id":"sticker_file_id","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","parse_mode":"MarkdownV2","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -1028,8 +1094,14 @@ mod tests {
input_message_content: InputMessageContent::Text(InputMessageContentText {
message_text: String::from("message_text"),
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
parse_mode: None,
disable_web_page_preview: None,
}),
reply_markup: None,
url: None,
@ -1040,7 +1112,7 @@ mod tests {
thumbnail_height: None,
});
let expected_json = r#"{"type":"article","id":"id","title":"title","input_message_content":{"message_text":"message_text"}}"#;
let expected_json = r#"{"type":"article","id":"id","title":"title","input_message_content":{"message_text":"message_text","link_preview_options":{"is_disabled":true}}}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -1056,7 +1128,13 @@ mod tests {
message_text: String::from("message_text"),
entities: None,
parse_mode: None,
disable_web_page_preview: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
}),
reply_markup: Some(InlineKeyboardMarkup::default()),
url: Some(Url::parse("http://url/").unwrap()),
@ -1067,7 +1145,7 @@ mod tests {
thumbnail_height: Some(1),
});
let expected_json = r#"{"type":"article","id":"id","title":"title","input_message_content":{"message_text":"message_text"},"reply_markup":{"inline_keyboard":[]},"url":"http://url/","hide_url":true,"description":"description","thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let expected_json = r#"{"type":"article","id":"id","title":"title","input_message_content":{"message_text":"message_text","link_preview_options":{"is_disabled":true}},"reply_markup":{"inline_keyboard":[]},"url":"http://url/","hide_url":true,"description":"description","thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -1109,14 +1187,20 @@ mod tests {
message_text: String::from("message_text"),
entities: None,
parse_mode: None,
disable_web_page_preview: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
thumbnail_url: Some(Url::parse("http://thumb_url/").unwrap()),
thumbnail_width: Some(1),
thumbnail_height: Some(1),
});
let expected_json = r#"{"type":"contact","id":"id","phone_number":"phone_number","first_name":"first_name","last_name":"last_name","vcard":"vcard","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text"},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let expected_json = r#"{"type":"contact","id":"id","phone_number":"phone_number","first_name":"first_name","last_name":"last_name","vcard":"vcard","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","link_preview_options":{"is_disabled":true}},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -1195,14 +1279,20 @@ mod tests {
message_text: String::from("message_text"),
entities: None,
parse_mode: None,
disable_web_page_preview: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
thumbnail_url: Some(Url::parse("http://thumb_url/").unwrap()),
thumbnail_width: Some(1),
thumbnail_height: Some(1),
});
let expected_json = r#"{"type":"location","id":"id","latitude":1.0,"longitude":1.0,"title":"title","horizontal_accuracy":1.0,"live_period":1,"heading":1,"proximity_alert_radius":1,"reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text"},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let expected_json = r#"{"type":"location","id":"id","latitude":1.0,"longitude":1.0,"title":"title","horizontal_accuracy":1.0,"live_period":1,"heading":1,"proximity_alert_radius":1,"reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","link_preview_options":{"is_disabled":true}},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);
@ -1252,14 +1342,20 @@ mod tests {
message_text: String::from("message_text"),
entities: None,
parse_mode: None,
disable_web_page_preview: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
})),
thumbnail_url: Some(Url::parse("http://thumb_url/").unwrap()),
thumbnail_width: Some(1),
thumbnail_height: Some(1),
});
let expected_json = r#"{"type":"venue","id":"id","latitude":1.0,"longitude":1.0,"title":"title","address":"address","foursquare_id":"foursquare_id","foursquare_type":"foursquare_type","google_place_id":"google_place_id","google_place_type":"google_place_type","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text"},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let expected_json = r#"{"type":"venue","id":"id","latitude":1.0,"longitude":1.0,"title":"title","address":"address","foursquare_id":"foursquare_id","foursquare_type":"foursquare_type","google_place_id":"google_place_id","google_place_type":"google_place_type","reply_markup":{"inline_keyboard":[]},"input_message_content":{"message_text":"message_text","link_preview_options":{"is_disabled":true}},"thumbnail_url":"http://thumb_url/","thumbnail_width":1,"thumbnail_height":1}"#;
let actual_json = serde_json::to_string(&structure).unwrap();
assert_eq!(expected_json, actual_json);

View file

@ -43,7 +43,7 @@ pub struct InputMediaPhoto {
pub caption_entities: Option<Vec<MessageEntity>>,
/// Pass `true` if the photo needs to be covered with a spoiler animation.
#[serde(skip_serializing_if = "std::ops::Not::not")]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_spoiler: bool,
}
@ -131,7 +131,7 @@ pub struct InputMediaVideo {
pub supports_streaming: Option<bool>,
/// Pass `true` if the video needs to be covered with a spoiler animation.
#[serde(skip_serializing_if = "std::ops::Not::not")]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_spoiler: bool,
}
@ -254,7 +254,7 @@ pub struct InputMediaAnimation {
/// Pass `true` if the animation needs to be covered with a spoiler
/// animation.
#[serde(skip_serializing_if = "std::ops::Not::not")]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_spoiler: bool,
}

View file

@ -1,7 +1,7 @@
use reqwest::Url;
use serde::{Deserialize, Serialize};
use crate::types::{Currency, LabeledPrice, MessageEntity, ParseMode};
use crate::types::{LabeledPrice, LinkPreviewOptions, MessageEntity, ParseMode};
/// This object represents the content of a message to be sent as a result of an
/// inline query.
@ -36,8 +36,8 @@ pub struct InputMessageContentText {
/// specified instead of `parse_mode`.
pub entities: Option<Vec<MessageEntity>>,
/// Disables link previews for links in the sent message.
pub disable_web_page_preview: Option<bool>,
/// Link preview generation options for the message
pub link_preview_options: Option<LinkPreviewOptions>,
}
impl InputMessageContentText {
@ -48,8 +48,8 @@ impl InputMessageContentText {
Self {
message_text: message_text.into(),
parse_mode: None,
disable_web_page_preview: None,
entities: None,
link_preview_options: None,
}
}
@ -76,8 +76,8 @@ impl InputMessageContentText {
}
#[must_use]
pub fn disable_web_page_preview(mut self, val: bool) -> Self {
self.disable_web_page_preview = Some(val);
pub fn link_preview_options(mut self, val: LinkPreviewOptions) -> Self {
self.link_preview_options = Some(val);
self
}
}
@ -329,10 +329,12 @@ pub struct InputMessageContentInvoice {
/// [@Botfather]: https://t.me/Botfather
pub provider_token: String,
/// Three-letter ISO 4217 currency code, see [more on currencies]
/// Three-letter ISO 4217 currency code, see [more on currencies]. Pass
/// `XTR` for payments in [Telegram Stars].
///
/// [more on currencies]: https://core.telegram.org/bots/payments#supported-currencies
pub currency: Currency,
/// [Telegram Stars]: https://t.me/BotNews/90
pub currency: String,
/// Price breakdown, list of components (e.g. product price, tax, discount,
/// delivery cost, delivery tax, bonus, etc.)
@ -396,12 +398,12 @@ pub struct InputMessageContentInvoice {
}
impl InputMessageContentInvoice {
pub fn new<T, D, PA, PT, PR>(
pub fn new<T, D, PA, PT, C, PR>(
title: T,
description: D,
payload: PA,
provider_token: PT,
currency: Currency,
currency: C,
prices: PR,
) -> Self
where
@ -409,12 +411,14 @@ impl InputMessageContentInvoice {
D: Into<String>,
PA: Into<String>,
PT: Into<String>,
C: Into<String>,
PR: IntoIterator<Item = LabeledPrice>,
{
let title = title.into();
let description = description.into();
let payload = payload.into();
let provider_token = provider_token.into();
let currency = currency.into();
let prices = prices.into_iter().collect();
Self {
@ -474,8 +478,11 @@ impl InputMessageContentInvoice {
}
#[must_use]
pub fn currency(mut self, val: Currency) -> Self {
self.currency = val;
pub fn currency<T>(mut self, val: T) -> Self
where
T: Into<String>,
{
self.currency = val.into();
self
}
@ -583,12 +590,19 @@ mod tests {
#[test]
fn text_serialize() {
let expected_json = r#"{"message_text":"text"}"#;
let expected_json =
r#"{"message_text":"text","link_preview_options":{"is_disabled":true}}"#;
let text_content = InputMessageContent::Text(InputMessageContentText {
message_text: String::from("text"),
parse_mode: None,
disable_web_page_preview: None,
entities: None,
link_preview_options: Some(LinkPreviewOptions {
is_disabled: true,
url: None,
prefer_small_media: false,
prefer_large_media: false,
show_above_text: false,
}),
});
let actual_json = serde_json::to_string(&text_content).unwrap();

View file

@ -2,6 +2,8 @@ use serde::Serialize;
use crate::types::{InputFile, MaskPosition};
use super::StickerFormat;
/// This object describes a sticker to be added to a sticker set.
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Serialize)]
@ -16,6 +18,10 @@ pub struct InputSticker {
/// More information on Sending Files <https://core.telegram.org/bots/api#sending-files>
pub sticker: InputFile,
/// Format of the added sticker, must be one of "static" for a .WEBP or .PNG
/// image, "animated" for a .TGS animation, "video" for a WEBM video
pub format: StickerFormat,
/// List of 1-20 emoji associated with the sticker
pub emoji_list: Vec<String>,

View file

@ -16,7 +16,11 @@ pub struct Invoice {
/// invoice.
pub start_parameter: String,
/// Three-letter ISO 4217 currency code.
/// Three-letter ISO 4217 currency code, see [more on currencies]. Pass
/// `XTR` for payments in [Telegram Stars].
///
/// [more on currencies]: https://core.telegram.org/bots/payments#supported-currencies
/// [Telegram Stars]: https://t.me/BotNews/90
pub currency: String,
/// Total price in the smallest units of the currency (integer, **not**

View file

@ -1,7 +1,7 @@
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use crate::types::{
KeyboardButtonPollType, KeyboardButtonRequestChat, KeyboardButtonRequestUser, True, WebAppInfo,
KeyboardButtonPollType, KeyboardButtonRequestChat, KeyboardButtonRequestUsers, True, WebAppInfo,
};
/// This object represents one button of the reply keyboard.
@ -68,10 +68,10 @@ pub enum ButtonRequest {
/// [`chat_shared`]: crate::types::MessageKind::ChatShared
RequestChat(KeyboardButtonRequestChat),
/// If this variant is used, pressing the button will open a list of
/// suitable users. Tapping on any user will send their identifier to the
/// bot in a “user_shared” service message.
RequestUser(KeyboardButtonRequestUser),
/// If specified, pressing the button will open a list of suitable users.
/// Identifiers of selected users will be sent to the bot in a
/// “users_shared” service message. Available in private chats only.
RequestUsers(KeyboardButtonRequestUsers),
/// If this variant is used, the user will be asked to create a poll and
/// send it to the bot when the button is pressed.
@ -110,10 +110,10 @@ struct RawRequest {
chat: Option<KeyboardButtonRequestChat>,
/// If specified, pressing the button will open a list of suitable users.
/// Tapping on any user will send their identifier to the bot in a
/// “user_shared” service message. Available in private chats only.
#[serde(rename = "request_user")]
user: Option<KeyboardButtonRequestUser>,
/// Identifiers of selected users will be sent to the bot in a
/// “users_shared” service message. Available in private chats only.
#[serde(rename = "request_users")]
users: Option<KeyboardButtonRequestUsers>,
/// 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
@ -134,11 +134,11 @@ impl<'de> Deserialize<'de> for ButtonRequest {
{
let raw = RawRequest::deserialize(deserializer)?;
match raw {
RawRequest { contact, location, chat, user, poll, web_app }
RawRequest { contact, location, chat, users, poll, web_app }
if 1 < (contact.is_some() as u8
+ location.is_some() as u8
+ chat.is_some() as u8
+ user.is_some() as u8
+ users.is_some() as u8
+ poll.is_some() as u8
+ web_app.is_some() as u8) =>
{
@ -150,7 +150,7 @@ impl<'de> Deserialize<'de> for ButtonRequest {
RawRequest { contact: Some(True), .. } => Ok(Self::Contact),
RawRequest { location: Some(True), .. } => Ok(Self::Location),
RawRequest { chat: Some(request_chat), .. } => Ok(Self::RequestChat(request_chat)),
RawRequest { user: Some(request_user), .. } => Ok(Self::RequestUser(request_user)),
RawRequest { users: Some(request_users), .. } => Ok(Self::RequestUsers(request_users)),
RawRequest { poll: Some(poll_type), .. } => Ok(Self::Poll(poll_type)),
RawRequest { web_app: Some(web_app), .. } => Ok(Self::WebApp(web_app)),
@ -158,11 +158,11 @@ impl<'de> Deserialize<'de> for ButtonRequest {
contact: None,
location: None,
chat: None,
user: None,
users: None,
poll: None,
web_app: None,
} => Err(D::Error::custom(
"Either one of `request_contact`, `request_chat`, `request_user`, \
"Either one of `request_contact`, `request_chat`, `request_users`, \
`request_location`, `request_poll` and `web_app` fields is required",
)),
}
@ -178,7 +178,7 @@ impl Serialize for ButtonRequest {
contact: None,
location: None,
chat: None,
user: None,
users: None,
poll: None,
web_app: None,
};
@ -187,7 +187,7 @@ impl Serialize for ButtonRequest {
Self::Contact => raw.contact = Some(True),
Self::Location => raw.location = Some(True),
Self::RequestChat(request_chat) => raw.chat = Some(request_chat.clone()),
Self::RequestUser(request_user) => raw.user = Some(request_user.clone()),
Self::RequestUsers(request_users) => raw.users = Some(request_users.clone()),
Self::Poll(poll_type) => raw.poll = Some(poll_type.clone()),
Self::WebApp(web_app) => raw.web_app = Some(web_app.clone()),
};
@ -198,6 +198,8 @@ impl Serialize for ButtonRequest {
#[cfg(test)]
mod tests {
use crate::types::RequestId;
use super::*;
#[test]
@ -221,7 +223,10 @@ mod tests {
fn serialize_chat_request() {
let button = KeyboardButton {
text: String::from(""),
request: Some(ButtonRequest::RequestChat(KeyboardButtonRequestChat::new(0, false))),
request: Some(ButtonRequest::RequestChat(KeyboardButtonRequestChat::new(
RequestId(0),
false,
))),
};
let expected = r#"{"text":"","request_chat":{"request_id":0,"chat_is_channel":false}}"#;
let actual = serde_json::to_string(&button).unwrap();

View file

@ -1,10 +1,11 @@
use serde::{Deserialize, Serialize};
use crate::types::ChatAdministratorRights;
use crate::types::{ChatAdministratorRights, RequestId};
/// This object defines the criteria used to request a suitable chat. The
/// identifier of the selected chat will be shared with the bot when the
/// corresponding button is pressed. [More about requesting chats »]
/// This object defines the criteria used to request a suitable chat.
/// Information about the selected chat will be shared with the bot when the
/// corresponding button is pressed. The bot will be granted requested rights in
/// the chat if appropriate. [More about requesting chats »]
///
/// [More about requesting chats »]: https://core.telegram.org/bots/features#chat-and-user-selection
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
@ -14,7 +15,7 @@ pub struct KeyboardButtonRequestChat {
/// [`ChatShared`] object. Must be unique within the message.
///
/// [`ChatShared`]: crate::types::ChatShared
pub request_id: i32,
pub request_id: RequestId,
/// Pass `true` to request a channel chat, pass `false` to request a group
/// or a supergroup chat.
@ -53,11 +54,23 @@ pub struct KeyboardButtonRequestChat {
/// additional restrictions are applied.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub bot_is_member: bool,
/// Pass `true` to request the chat's title.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub request_title: bool,
/// Pass `true` to request the chat's username.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub request_username: bool,
/// Pass `true` to request the chat's photo.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub request_photo: bool,
}
impl KeyboardButtonRequestChat {
/// Creates a new [`KeyboardButtonRequestChat`].
pub fn new(request_id: i32, chat_is_channel: bool) -> Self {
pub fn new(request_id: RequestId, chat_is_channel: bool) -> Self {
Self {
request_id,
chat_is_channel,
@ -67,6 +80,9 @@ impl KeyboardButtonRequestChat {
user_administrator_rights: None,
bot_administrator_rights: None,
bot_is_member: false,
request_title: false,
request_username: false,
request_photo: false,
}
}
@ -111,4 +127,25 @@ impl KeyboardButtonRequestChat {
self.bot_is_member = value;
self
}
/// Setter for `request_title` field.
#[must_use]
pub fn request_title(mut self) -> Self {
self.request_title = true;
self
}
/// Setter for `request_username` field.
#[must_use]
pub fn request_username(mut self) -> Self {
self.request_username = true;
self
}
/// Setter for `request_photo` field.
#[must_use]
pub fn request_photo(mut self) -> Self {
self.request_photo = true;
self
}
}

View file

@ -1,44 +0,0 @@
use serde::{Deserialize, Serialize};
/// 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. More about requesting users »
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct KeyboardButtonRequestUser {
/// identifier of the request, which will be received back in the
/// [`UserShared`] object. Must be unique within the message.
///
/// [`UserShared`]: crate::types::UserShared
pub request_id: i32,
/// Pass `true` to request a bot, pass `false` to request a regular user. If
/// not specified, no additional restrictions are applied.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub user_is_bot: Option<bool>,
/// Pass `true` to request a premium user, pass `false` to request a
/// non-premium user. If not specified, no additional restrictions are
/// applied.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub user_is_premium: Option<bool>,
}
impl KeyboardButtonRequestUser {
/// Creates a new [`KeyboardButtonRequestUser`].
pub fn new(request_id: i32) -> Self {
Self { request_id, user_is_bot: None, user_is_premium: None }
}
/// Setter for `user_is_bot` field
pub fn user_is_bot(mut self, value: bool) -> Self {
self.user_is_bot = Some(value);
self
}
/// Setter for `user_is_premium` field
pub fn user_is_premium(mut self, value: bool) -> Self {
self.user_is_premium = Some(value);
self
}
}

View file

@ -0,0 +1,112 @@
use serde::{Deserialize, Serialize};
use crate::types::RequestId;
/// This object defines the criteria used to request a suitable users.
/// Information about the selected users will be shared with the bot when the
/// corresponding button is pressed. More about requesting users »
///
/// [More about requesting users »]: https://core.telegram.org/bots/features#chat-and-user-selection
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct KeyboardButtonRequestUsers {
/// Identifier of the request, which will be received back in the
/// [`UsersShared`] object. Must be unique within the message.
///
/// [`UsersShared`]: crate::types::UsersShared
pub request_id: RequestId,
/// Pass `true` to request a bot, pass `false` to request a regular user. If
/// not specified, no additional restrictions are applied.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub user_is_bot: Option<bool>,
/// Pass `true` to request a premium user, pass `false` to request a
/// non-premium user. If not specified, no additional restrictions are
/// applied.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub user_is_premium: Option<bool>,
/// The maximum number of users to be selected; 1-10. Defaults to 1.
#[serde(default = "one", skip_serializing_if = "is_one")]
pub max_quantity: u8,
/// Pass `true` to request the users' first and last names
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub request_name: bool,
/// Pass `true` to request the users' username
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub request_username: bool,
/// Pass `true` to request the users' photos
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub request_photo: bool,
}
impl KeyboardButtonRequestUsers {
/// Creates a new [`KeyboardButtonRequestUsers`].
pub fn new(request_id: RequestId) -> Self {
Self {
request_id,
user_is_bot: None,
user_is_premium: None,
max_quantity: 1,
request_name: false,
request_username: false,
request_photo: false,
}
}
/// Setter for `user_is_bot` field
#[must_use]
pub fn user_is_bot(mut self, value: bool) -> Self {
self.user_is_bot = Some(value);
self
}
/// Setter for `user_is_premium` field
#[must_use]
pub fn user_is_premium(mut self, value: bool) -> Self {
self.user_is_premium = Some(value);
self
}
/// Setter for `max_quantity` field, the value must be in the range 1..=10
#[must_use]
pub fn max_quantity(mut self, value: u8) -> Self {
assert!((1..=10).contains(&value));
self.max_quantity = value;
self
}
/// Setter for `request_name` field
#[must_use]
pub fn request_name(mut self) -> Self {
self.request_name = true;
self
}
/// Setter for `request_username` field
#[must_use]
pub fn request_username(mut self) -> Self {
self.request_username = true;
self
}
/// Setter for `request_photo` field
#[must_use]
pub fn request_photo(mut self) -> Self {
self.request_photo = true;
self
}
}
fn one() -> u8 {
1
}
fn is_one(value: &u8) -> bool {
*value == 1
}

Some files were not shown because too many files have changed in this diff Show more