mirror of
https://github.com/teloxide/teloxide.git
synced 2024-10-24 01:47:08 +02:00
commit
cf87d72852
25 changed files with 571 additions and 122 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -53,7 +53,7 @@ jobs:
|
|||
dialogue_bot,
|
||||
heroku_ping_pong_bot,
|
||||
ngrok_ping_pong_bot,
|
||||
ping_pong_bot,
|
||||
dices_bot,
|
||||
shared_state_bot,
|
||||
simple_commands_bot,
|
||||
]
|
||||
|
|
16
README.md
16
README.md
|
@ -15,7 +15,7 @@
|
|||
<img src="https://img.shields.io/badge/official%20chat-t.me%2Fteloxide-blueviolet">
|
||||
</a>
|
||||
<a href="https://core.telegram.org/bots/api">
|
||||
<img src="https://img.shields.io/badge/API coverage-Up to 0.4.6 (inclusively)-green.svg">
|
||||
<img src="https://img.shields.io/badge/API coverage-Up to 0.4.7 (inclusively)-green.svg">
|
||||
</a>
|
||||
|
||||
A full-featured framework that empowers you to easily build [Telegram bots](https://telegram.org/blog/bot-revolution) using the [`async`/`.await`](https://rust-lang.github.io/async-book/01_getting_started/01_chapter.html) syntax in [Rust](https://www.rust-lang.org/). It handles all the difficult stuff so you can focus only on your business logic.
|
||||
|
@ -25,7 +25,7 @@
|
|||
- [Highlights](https://github.com/teloxide/teloxide#highlights)
|
||||
- [Setting up your environment](https://github.com/teloxide/teloxide#setting-up-your-environment)
|
||||
- [API overview](https://github.com/teloxide/teloxide#api-overview)
|
||||
- [The ping-pong bot](https://github.com/teloxide/teloxide#the-ping-pong-bot)
|
||||
- [The dices bot](https://github.com/teloxide/teloxide#the-dices-bot)
|
||||
- [Commands](https://github.com/teloxide/teloxide#commands)
|
||||
- [Dialogues management](https://github.com/teloxide/teloxide#dialogues-management)
|
||||
- [Recommendations](https://github.com/teloxide/teloxide#recommendations)
|
||||
|
@ -88,24 +88,24 @@ futures = "0.3.5"
|
|||
|
||||
## API overview
|
||||
|
||||
### The ping-pong bot
|
||||
This bot has a single message handler, which answers "pong" to each incoming message:
|
||||
### The dices bot
|
||||
This bot throws a dice on each incoming message:
|
||||
|
||||
([Full](https://github.com/teloxide/teloxide/blob/master/examples/ping_pong_bot/src/main.rs))
|
||||
([Full](https://github.com/teloxide/teloxide/blob/master/examples/dices_bot/src/main.rs))
|
||||
```rust
|
||||
use teloxide::prelude::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
teloxide::enable_logging!();
|
||||
log::info!("Starting ping_pong_bot...");
|
||||
log::info!("Starting dices_bot...");
|
||||
|
||||
let bot = Bot::from_env();
|
||||
|
||||
Dispatcher::new(bot)
|
||||
.messages_handler(|rx: DispatcherHandlerRx<Message>| {
|
||||
rx.for_each(|message| async move {
|
||||
message.answer_str("pong").await.log_on_error().await;
|
||||
message.send_dice().send().await.log_on_error().await;
|
||||
})
|
||||
})
|
||||
.dispatch()
|
||||
|
@ -116,7 +116,7 @@ async fn main() {
|
|||
|
||||
<div align="center">
|
||||
<kbd>
|
||||
<img src=https://github.com/teloxide/teloxide/raw/master/media/PING_PONG_BOT.gif />
|
||||
<img src=https://github.com/teloxide/teloxide/raw/master/media/DICES_BOT.gif />
|
||||
</kbd>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Just enter the directory (for example, `cd dialogue_bot`) and execute `cargo run` to run an example. Don't forget to initialise the `TELOXIDE_TOKEN` environmental variable.
|
||||
| Bot | Description |
|
||||
|---|-----------|
|
||||
| [ping_pong_bot](ping_pong_bot) | Answers "pong" to each incoming message. |
|
||||
| [dices_bot](dices_bot) | This bot throws a dice on each incoming message. |
|
||||
| [ngrok_ping_pong_bot](ngrok_ping_pong_bot) | The ngrok version of ping-pong-bot that uses webhooks. |
|
||||
| [heroku_ping_pong_bot](heroku_ping_pong_bot) | The Heroku version of ping-pong-bot that uses webhooks. |
|
||||
| [simple_commands_bot](simple_commands_bot) | Shows how to deal with bot's commands. |
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "ping_pong_bot"
|
||||
name = "dices_bot"
|
||||
version = "0.1.0"
|
||||
authors = ["Temirkhan Myrzamadi <hirrolot@gmail.com>"]
|
||||
edition = "2018"
|
|
@ -1,4 +1,4 @@
|
|||
// This bot just answers "pong" to each incoming UpdateKind::Message.
|
||||
// This bot throws a dice on each incoming message.
|
||||
|
||||
use teloxide::prelude::*;
|
||||
|
||||
|
@ -9,14 +9,14 @@ async fn main() {
|
|||
|
||||
async fn run() {
|
||||
teloxide::enable_logging!();
|
||||
log::info!("Starting ping_pong_bot...");
|
||||
log::info!("Starting dices_bot...");
|
||||
|
||||
let bot = Bot::from_env();
|
||||
|
||||
Dispatcher::new(bot)
|
||||
.messages_handler(|rx: DispatcherHandlerRx<Message>| {
|
||||
rx.for_each(|message| async move {
|
||||
message.answer_str("pong").await.log_on_error().await;
|
||||
message.send_dice().send().await.log_on_error().await;
|
||||
})
|
||||
})
|
||||
.dispatch()
|
BIN
media/DICES_BOT.gif
Normal file
BIN
media/DICES_BOT.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 169 KiB |
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
106
src/bot/api.rs
106
src/bot/api.rs
|
@ -5,19 +5,19 @@ use crate::{
|
|||
DeleteMessage, DeleteStickerFromSet, DeleteWebhook, EditMessageCaption,
|
||||
EditMessageLiveLocation, EditMessageMedia, EditMessageReplyMarkup, EditMessageText,
|
||||
ExportChatInviteLink, ForwardMessage, GetChat, GetChatAdministrators, GetChatMember,
|
||||
GetChatMembersCount, GetFile, GetGameHighScores, GetMe, GetStickerSet, GetUpdates,
|
||||
GetUserProfilePhotos, GetWebhookInfo, KickChatMember, LeaveChat, PinChatMessage,
|
||||
PromoteChatMember, RestrictChatMember, SendAnimation, SendAudio, SendChatAction,
|
||||
SendChatActionKind, SendContact, SendDocument, SendGame, SendInvoice, SendLocation,
|
||||
SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendSticker, SendVenue, SendVideo,
|
||||
SendVideoNote, SendVoice, SetChatAdministratorCustomTitle, SetChatDescription,
|
||||
SetChatPermissions, SetChatPhoto, SetChatStickerSet, SetChatTitle, SetGameScore,
|
||||
SetStickerPositionInSet, SetWebhook, StopMessageLiveLocation, StopPoll, UnbanChatMember,
|
||||
UnpinChatMessage, UploadStickerFile,
|
||||
GetChatMembersCount, GetFile, GetGameHighScores, GetMe, GetMyCommands, GetStickerSet,
|
||||
GetUpdates, GetUserProfilePhotos, GetWebhookInfo, KickChatMember, LeaveChat,
|
||||
PinChatMessage, PromoteChatMember, RestrictChatMember, SendAnimation, SendAudio,
|
||||
SendChatAction, SendChatActionKind, SendContact, SendDice, SendDocument, SendGame,
|
||||
SendInvoice, SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendSticker,
|
||||
SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatAdministratorCustomTitle,
|
||||
SetChatDescription, SetChatPermissions, SetChatPhoto, SetChatStickerSet, SetChatTitle,
|
||||
SetGameScore, SetMyCommands, SetStickerPositionInSet, SetStickerSetThumb, SetWebhook,
|
||||
StopMessageLiveLocation, StopPoll, UnbanChatMember, UnpinChatMessage, UploadStickerFile,
|
||||
},
|
||||
types::{
|
||||
ChatId, ChatOrInlineMessage, ChatPermissions, InlineQueryResult, InputFile, InputMedia,
|
||||
LabeledPrice,
|
||||
BotCommand, ChatId, ChatOrInlineMessage, ChatPermissions, InlineQueryResult, InputFile,
|
||||
InputMedia, LabeledPrice, StickerType,
|
||||
},
|
||||
Bot,
|
||||
};
|
||||
|
@ -1198,25 +1198,12 @@ impl Bot {
|
|||
/// end in `_by_<bot username>`. `<bot_username>` is case insensitive. 1-64
|
||||
/// characters.
|
||||
/// - `title`: Sticker set title, 1-64 characters.
|
||||
/// - `png_sticker`: **Png** image with the sticker, must be up to 512
|
||||
/// kilobytes in size, dimensions must not exceed 512px, and either
|
||||
/// width or height must be exactly 512px.
|
||||
///
|
||||
/// Pass [`InputFile::File`] to send a file that exists on the Telegram
|
||||
/// servers (recommended), pass an [`InputFile::Url`] for Telegram to get a
|
||||
/// .webp file from the Internet, or upload a new one using
|
||||
/// [`InputFile::FileId`]. [More info on Sending Files »].
|
||||
/// - `emojis`: One or more emoji corresponding to the sticker.
|
||||
///
|
||||
/// [`InputFile::File`]: crate::types::InputFile::File
|
||||
/// [`InputFile::Url`]: crate::types::InputFile::Url
|
||||
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
|
||||
pub fn create_new_sticker_set<N, T, E>(
|
||||
&self,
|
||||
user_id: i32,
|
||||
name: N,
|
||||
title: T,
|
||||
png_sticker: InputFile,
|
||||
sticker_type: StickerType,
|
||||
emojis: E,
|
||||
) -> CreateNewStickerSet
|
||||
where
|
||||
|
@ -1224,7 +1211,7 @@ impl Bot {
|
|||
T: Into<String>,
|
||||
E: Into<String>,
|
||||
{
|
||||
CreateNewStickerSet::new(self.clone(), user_id, name, title, png_sticker, emojis)
|
||||
CreateNewStickerSet::new(self.clone(), user_id, name, title, sticker_type, emojis)
|
||||
}
|
||||
|
||||
/// Use this method to add a new sticker to a set created by the bot.
|
||||
|
@ -1234,31 +1221,19 @@ impl Bot {
|
|||
/// # Params
|
||||
/// - `user_id`: User identifier of sticker set owner.
|
||||
/// - `name`: Sticker set name.
|
||||
/// - `png_sticker`: **Png** image with the sticker, must be up to 512
|
||||
/// kilobytes in size, dimensions must not exceed 512px, and either
|
||||
/// width or height must be exactly 512px.
|
||||
///
|
||||
/// Pass [`InputFile::File`] to send a file that exists on the Telegram
|
||||
/// servers (recommended), pass an [`InputFile::Url`] for Telegram to get a
|
||||
/// .webp file from the Internet, or upload a new one using [`InputFile:
|
||||
/// :FileId`]. [More info on Sending Files »].
|
||||
/// - `emojis`: One or more emoji corresponding to the sticker.
|
||||
///
|
||||
/// [`InputFile::File`]: crate::types::InputFile::File
|
||||
/// [`InputFile::Url`]: crate::types::InputFile::Url
|
||||
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
|
||||
pub fn add_sticker_to_set<N, E>(
|
||||
&self,
|
||||
user_id: i32,
|
||||
name: N,
|
||||
png_sticker: InputFile,
|
||||
sticker_type: StickerType,
|
||||
emojis: E,
|
||||
) -> AddStickerToSet
|
||||
where
|
||||
N: Into<String>,
|
||||
E: Into<String>,
|
||||
{
|
||||
AddStickerToSet::new(self.clone(), user_id, name, png_sticker, emojis)
|
||||
AddStickerToSet::new(self.clone(), user_id, name, sticker_type, emojis)
|
||||
}
|
||||
|
||||
/// Use this method to move a sticker in a set created by the bot to a
|
||||
|
@ -1501,4 +1476,55 @@ impl Bot {
|
|||
{
|
||||
SetChatAdministratorCustomTitle::new(self.clone(), chat_id, user_id, custom_title)
|
||||
}
|
||||
|
||||
/// Use this method to send an animated emoji that will display a random
|
||||
/// value.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#senddice).
|
||||
///
|
||||
/// # Params
|
||||
/// - `chat_id`: Unique identifier for the target chat or username of the
|
||||
/// target channel (in the format `@channelusername`).
|
||||
pub fn send_dice<C>(&self, chat_id: C) -> SendDice
|
||||
where
|
||||
C: Into<ChatId>,
|
||||
{
|
||||
SendDice::new(self.clone(), chat_id)
|
||||
}
|
||||
|
||||
/// Use this method to get the current list of the bot's commands.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#getmycommands).
|
||||
pub fn get_my_commands(&self) -> GetMyCommands {
|
||||
GetMyCommands::new(self.clone())
|
||||
}
|
||||
|
||||
/// Use this method to change the list of the bot's commands.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#setmycommands).
|
||||
///
|
||||
/// # Params
|
||||
/// - `commands`: A JSON-serialized list of bot commands to be set as the
|
||||
/// list of the bot's commands. At most 100 commands can be specified.
|
||||
pub fn set_my_commands<C>(&self, commands: C) -> SetMyCommands
|
||||
where
|
||||
C: Into<Vec<BotCommand>>,
|
||||
{
|
||||
SetMyCommands::new(self.clone(), commands)
|
||||
}
|
||||
|
||||
/// Use this method to set the thumbnail of a sticker set. Animated
|
||||
/// thumbnails can be set for animated sticker sets only.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#setstickersetthumb).
|
||||
///
|
||||
/// # Params
|
||||
/// - `name`: Sticker set name.
|
||||
/// - `user_id`: User identifier of the sticker set owner.
|
||||
pub fn set_sticker_set_thumb<S>(&self, name: S, user_id: i32) -> SetStickerSetThumb
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
SetStickerSetThumb::new(self.clone(), name, user_id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,25 +30,24 @@
|
|||
//!
|
||||
//! Since they implement [`DispatcherHandler`] too.
|
||||
//!
|
||||
//! # The ping-pong bot
|
||||
//! This bot has a single handler of messages, which answers "pong" to each
|
||||
//! incoming message:
|
||||
//! # The dices bot
|
||||
//! This bot throws a dice on each incoming message:
|
||||
//!
|
||||
//! ([Full](https://github.com/teloxide/teloxide/blob/master/examples/ping_pong_bot/src/main.rs))
|
||||
//! ([Full](https://github.com/teloxide/teloxide/blob/master/examples/dices_bot/src/main.rs))
|
||||
//! ```no_run
|
||||
//! use teloxide::prelude::*;
|
||||
//!
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main_() {
|
||||
//! teloxide::enable_logging!();
|
||||
//! log::info!("Starting ping_pong_bot...");
|
||||
//! log::info!("Starting dices_bot...");
|
||||
//!
|
||||
//! let bot = Bot::from_env();
|
||||
//!
|
||||
//! Dispatcher::new(bot)
|
||||
//! .messages_handler(|rx: DispatcherHandlerRx<Message>| {
|
||||
//! rx.for_each(|message| async move {
|
||||
//! message.answer("pong").send().await.log_on_error().await;
|
||||
//! message.send_dice().send().await.log_on_error().await;
|
||||
//! })
|
||||
//! })
|
||||
//! .dispatch()
|
||||
|
@ -58,7 +57,7 @@
|
|||
//!
|
||||
//! <div align="center">
|
||||
//! <kbd>
|
||||
//! <img src=https://github.com/teloxide/teloxide/raw/master/media/PING_PONG_BOT.gif />
|
||||
//! <img src=https://github.com/teloxide/teloxide/raw/master/media/DICES_BOT.gif />
|
||||
//! </kbd>
|
||||
//! </div>
|
||||
//!
|
||||
|
|
|
@ -2,9 +2,9 @@ use crate::{
|
|||
dispatching::dialogue::GetChatId,
|
||||
requests::{
|
||||
DeleteMessage, EditMessageCaption, EditMessageText, ForwardMessage, PinChatMessage,
|
||||
Request, ResponseResult, SendAnimation, SendAudio, SendContact, SendDocument, SendLocation,
|
||||
SendMediaGroup, SendMessage, SendPhoto, SendSticker, SendVenue, SendVideo, SendVideoNote,
|
||||
SendVoice,
|
||||
Request, ResponseResult, SendAnimation, SendAudio, SendContact, SendDice, SendDocument,
|
||||
SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendSticker, SendVenue, SendVideo,
|
||||
SendVideoNote, SendVoice,
|
||||
},
|
||||
types::{ChatId, ChatOrInlineMessage, InputFile, InputMedia, Message},
|
||||
Bot,
|
||||
|
@ -153,4 +153,8 @@ impl UpdateWithCx<Message> {
|
|||
pub fn pin_message(&self) -> PinChatMessage {
|
||||
self.bot.pin_chat_message(self.update.chat.id, self.update.id)
|
||||
}
|
||||
|
||||
pub fn send_dice(&self) -> SendDice {
|
||||
self.bot.send_dice(self.update.chat.id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use crate::{
|
||||
net,
|
||||
requests::form_builder::FormBuilder,
|
||||
types::{InputFile, MaskPosition, True},
|
||||
types::{MaskPosition, True},
|
||||
Bot,
|
||||
};
|
||||
|
||||
use crate::requests::{RequestWithFile, ResponseResult};
|
||||
use crate::{
|
||||
requests::{RequestWithFile, ResponseResult},
|
||||
types::StickerType,
|
||||
};
|
||||
|
||||
/// Use this method to add a new sticker to a set created by the bot.
|
||||
///
|
||||
|
@ -15,7 +18,7 @@ pub struct AddStickerToSet {
|
|||
bot: Bot,
|
||||
user_id: i32,
|
||||
name: String,
|
||||
png_sticker: InputFile,
|
||||
sticker_type: StickerType,
|
||||
emojis: String,
|
||||
mask_position: Option<MaskPosition>,
|
||||
}
|
||||
|
@ -25,18 +28,22 @@ impl RequestWithFile for AddStickerToSet {
|
|||
type Output = True;
|
||||
|
||||
async fn send(&self) -> tokio::io::Result<ResponseResult<True>> {
|
||||
let builder =
|
||||
FormBuilder::new().add_text("user_id", &self.user_id).add_text("name", &self.name);
|
||||
|
||||
let builder = match &self.sticker_type {
|
||||
StickerType::Png(file) => builder.add_input_file("png_sticker", &file),
|
||||
StickerType::Tgs(file) => builder.add_input_file("tgs_sticker", &file),
|
||||
}
|
||||
.await?
|
||||
.add_text("emojis", &self.emojis)
|
||||
.add_text("mask_position", &self.mask_position);
|
||||
|
||||
Ok(net::request_multipart(
|
||||
self.bot.client(),
|
||||
self.bot.token(),
|
||||
"addStickerToSet",
|
||||
FormBuilder::new()
|
||||
.add_text("user_id", &self.user_id)
|
||||
.add_text("name", &self.name)
|
||||
.add_input_file("png_sticker", &self.png_sticker)
|
||||
.await?
|
||||
.add_text("emojis", &self.emojis)
|
||||
.add_text("mask_position", &self.mask_position)
|
||||
.build(),
|
||||
builder.build(),
|
||||
)
|
||||
.await)
|
||||
}
|
||||
|
@ -47,7 +54,7 @@ impl AddStickerToSet {
|
|||
bot: Bot,
|
||||
user_id: i32,
|
||||
name: N,
|
||||
png_sticker: InputFile,
|
||||
sticker_type: StickerType,
|
||||
emojis: E,
|
||||
) -> Self
|
||||
where
|
||||
|
@ -58,7 +65,7 @@ impl AddStickerToSet {
|
|||
bot,
|
||||
user_id,
|
||||
name: name.into(),
|
||||
png_sticker,
|
||||
sticker_type,
|
||||
emojis: emojis.into(),
|
||||
mask_position: None,
|
||||
}
|
||||
|
@ -79,20 +86,8 @@ impl AddStickerToSet {
|
|||
self
|
||||
}
|
||||
|
||||
/// **Png** image with the sticker, must be up to 512 kilobytes in size,
|
||||
/// dimensions must not exceed 512px, and either width or height must be
|
||||
/// exactly 512px.
|
||||
///
|
||||
/// Pass [`InputFile::File`] to send a file that exists on
|
||||
/// the Telegram servers (recommended), pass an [`InputFile::Url`] for
|
||||
/// Telegram to get a .webp file from the Internet, or upload a new one
|
||||
/// using [`InputFile::FileId`]. [More info on Sending Files »].
|
||||
///
|
||||
/// [`InputFile::File`]: crate::types::InputFile::File
|
||||
/// [`InputFile::Url`]: crate::types::InputFile::Url
|
||||
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
|
||||
pub fn png_sticker(mut self, val: InputFile) -> Self {
|
||||
self.png_sticker = val;
|
||||
pub fn sticker_type(mut self, val: StickerType) -> Self {
|
||||
self.sticker_type = val;
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
net,
|
||||
requests::{form_builder::FormBuilder, RequestWithFile, ResponseResult},
|
||||
types::{InputFile, MaskPosition, True},
|
||||
types::{MaskPosition, StickerType, True},
|
||||
Bot,
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@ pub struct CreateNewStickerSet {
|
|||
user_id: i32,
|
||||
name: String,
|
||||
title: String,
|
||||
png_sticker: InputFile,
|
||||
sticker_type: StickerType,
|
||||
emojis: String,
|
||||
contains_masks: Option<bool>,
|
||||
mask_position: Option<MaskPosition>,
|
||||
|
@ -26,20 +26,25 @@ impl RequestWithFile for CreateNewStickerSet {
|
|||
type Output = True;
|
||||
|
||||
async fn send(&self) -> tokio::io::Result<ResponseResult<True>> {
|
||||
let builder = FormBuilder::new()
|
||||
.add_text("user_id", &self.user_id)
|
||||
.add_text("name", &self.name)
|
||||
.add_text("title", &self.title);
|
||||
|
||||
let builder = match &self.sticker_type {
|
||||
StickerType::Png(file) => builder.add_input_file("png_sticker", &file),
|
||||
StickerType::Tgs(file) => builder.add_input_file("tgs_sticker", &file),
|
||||
}
|
||||
.await?
|
||||
.add_text("emojis", &self.emojis)
|
||||
.add_text("contains_masks", &self.contains_masks)
|
||||
.add_text("mask_position", &self.mask_position);
|
||||
|
||||
Ok(net::request_multipart(
|
||||
self.bot.client(),
|
||||
self.bot.token(),
|
||||
"createNewStickerSet",
|
||||
FormBuilder::new()
|
||||
.add_text("user_id", &self.user_id)
|
||||
.add_text("name", &self.name)
|
||||
.add_text("title", &self.title)
|
||||
.add_input_file("png_sticker", &self.png_sticker)
|
||||
.await?
|
||||
.add_text("emojis", &self.emojis)
|
||||
.add_text("contains_masks", &self.contains_masks)
|
||||
.add_text("mask_position", &self.mask_position)
|
||||
.build(),
|
||||
builder.build(),
|
||||
)
|
||||
.await)
|
||||
}
|
||||
|
@ -51,7 +56,7 @@ impl CreateNewStickerSet {
|
|||
user_id: i32,
|
||||
name: N,
|
||||
title: T,
|
||||
png_sticker: InputFile,
|
||||
sticker_type: StickerType,
|
||||
emojis: E,
|
||||
) -> Self
|
||||
where
|
||||
|
@ -64,7 +69,7 @@ impl CreateNewStickerSet {
|
|||
user_id,
|
||||
name: name.into(),
|
||||
title: title.into(),
|
||||
png_sticker,
|
||||
sticker_type,
|
||||
emojis: emojis.into(),
|
||||
contains_masks: None,
|
||||
mask_position: None,
|
||||
|
@ -100,20 +105,8 @@ impl CreateNewStickerSet {
|
|||
self
|
||||
}
|
||||
|
||||
/// **Png** image with the sticker, must be up to 512 kilobytes in size,
|
||||
/// dimensions must not exceed 512px, and either width or height must be
|
||||
/// exactly 512px.
|
||||
///
|
||||
/// Pass [`InputFile::File`] to send a file that exists on
|
||||
/// the Telegram servers (recommended), pass an [`InputFile::Url`] for
|
||||
/// Telegram to get a .webp file from the Internet, or upload a new one
|
||||
/// using [`InputFile::FileId`]. [More info on Sending Files »].
|
||||
///
|
||||
/// [`InputFile::File`]: crate::types::InputFile::File
|
||||
/// [`InputFile::Url`]: crate::types::InputFile::Url
|
||||
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
|
||||
pub fn png_sticker(mut self, val: InputFile) -> Self {
|
||||
self.png_sticker = val;
|
||||
pub fn sticker_type(mut self, val: StickerType) -> Self {
|
||||
self.sticker_type = val;
|
||||
self
|
||||
}
|
||||
|
||||
|
|
33
src/requests/all/get_my_commands.rs
Normal file
33
src/requests/all/get_my_commands.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
net,
|
||||
requests::{Request, ResponseResult},
|
||||
types::BotCommand,
|
||||
Bot,
|
||||
};
|
||||
|
||||
/// Use this method to get the current list of the bot's commands.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#getmycommands).
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct GetMyCommands {
|
||||
#[serde(skip_serializing)]
|
||||
bot: Bot,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Request for GetMyCommands {
|
||||
type Output = Vec<BotCommand>;
|
||||
|
||||
async fn send(&self) -> ResponseResult<Self::Output> {
|
||||
net::request_json(self.bot.client(), self.bot.token(), "getMyCommands", &self).await
|
||||
}
|
||||
}
|
||||
|
||||
impl GetMyCommands {
|
||||
pub(crate) fn new(bot: Bot) -> Self {
|
||||
Self { bot }
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ mod get_chat_members_count;
|
|||
mod get_file;
|
||||
mod get_game_high_scores;
|
||||
mod get_me;
|
||||
mod get_my_commands;
|
||||
mod get_sticker_set;
|
||||
mod get_updates;
|
||||
mod get_user_profile_photos;
|
||||
|
@ -36,6 +37,7 @@ mod send_animation;
|
|||
mod send_audio;
|
||||
mod send_chat_action;
|
||||
mod send_contact;
|
||||
mod send_dice;
|
||||
mod send_document;
|
||||
mod send_game;
|
||||
mod send_invoice;
|
||||
|
@ -56,7 +58,9 @@ mod set_chat_photo;
|
|||
mod set_chat_sticker_set;
|
||||
mod set_chat_title;
|
||||
mod set_game_score;
|
||||
mod set_my_commands;
|
||||
mod set_sticker_position_in_set;
|
||||
mod set_sticker_set_thumb;
|
||||
mod set_webhook;
|
||||
mod stop_message_live_location;
|
||||
mod stop_poll;
|
||||
|
@ -89,6 +93,7 @@ pub use get_chat_members_count::*;
|
|||
pub use get_file::*;
|
||||
pub use get_game_high_scores::*;
|
||||
pub use get_me::*;
|
||||
pub use get_my_commands::*;
|
||||
pub use get_sticker_set::*;
|
||||
pub use get_updates::*;
|
||||
pub use get_user_profile_photos::*;
|
||||
|
@ -102,6 +107,7 @@ pub use send_animation::*;
|
|||
pub use send_audio::*;
|
||||
pub use send_chat_action::*;
|
||||
pub use send_contact::*;
|
||||
pub use send_dice::*;
|
||||
pub use send_document::*;
|
||||
pub use send_game::*;
|
||||
pub use send_invoice::*;
|
||||
|
@ -122,7 +128,9 @@ pub use set_chat_photo::*;
|
|||
pub use set_chat_sticker_set::*;
|
||||
pub use set_chat_title::*;
|
||||
pub use set_game_score::*;
|
||||
pub use set_my_commands::*;
|
||||
pub use set_sticker_position_in_set::*;
|
||||
pub use set_sticker_set_thumb::*;
|
||||
pub use set_webhook::*;
|
||||
pub use std::pin::Pin;
|
||||
pub use stop_message_live_location::*;
|
||||
|
|
94
src/requests/all/send_dice.rs
Normal file
94
src/requests/all/send_dice.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
net,
|
||||
requests::{Request, ResponseResult},
|
||||
types::{ChatId, DiceEmoji, Message, ReplyMarkup},
|
||||
Bot,
|
||||
};
|
||||
|
||||
/// Use this method to send an animated emoji that will display a random value.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#senddice).
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SendDice {
|
||||
#[serde(skip_serializing)]
|
||||
bot: Bot,
|
||||
|
||||
chat_id: ChatId,
|
||||
#[serde(flatten)]
|
||||
emoji: Option<DiceEmoji>,
|
||||
disable_notification: Option<bool>,
|
||||
reply_to_message_id: Option<i32>,
|
||||
reply_markup: Option<ReplyMarkup>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Request for SendDice {
|
||||
type Output = Message;
|
||||
|
||||
async fn send(&self) -> ResponseResult<Message> {
|
||||
net::request_json(self.bot.client(), self.bot.token(), "sendDice", &self).await
|
||||
}
|
||||
}
|
||||
|
||||
impl SendDice {
|
||||
pub(crate) fn new<C>(bot: Bot, chat_id: C) -> Self
|
||||
where
|
||||
C: Into<ChatId>,
|
||||
{
|
||||
Self {
|
||||
bot,
|
||||
chat_id: chat_id.into(),
|
||||
emoji: None,
|
||||
disable_notification: None,
|
||||
reply_to_message_id: None,
|
||||
reply_markup: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Unique identifier for the target chat or username of the target channel
|
||||
/// (in the format `@channelusername`).
|
||||
pub fn chat_id<T>(mut self, value: T) -> Self
|
||||
where
|
||||
T: Into<ChatId>,
|
||||
{
|
||||
self.chat_id = value.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Emoji on which the dice throw animation is based.
|
||||
pub fn emoji(mut self, val: DiceEmoji) -> Self {
|
||||
self.emoji = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sends the message [silently]. Users will receive a notification with no
|
||||
/// sound.
|
||||
///
|
||||
/// [silently]: https://telegram.org/blog/channels-2-0#silent-messages
|
||||
pub fn disable_notification(mut self, value: bool) -> Self {
|
||||
self.disable_notification = Some(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// If the message is a reply, ID of the original message.
|
||||
pub fn reply_to_message_id(mut self, value: i32) -> Self {
|
||||
self.reply_to_message_id = Some(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// [inline keyboard]: https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating
|
||||
/// [custom reply keyboard]: https://core.telegram.org/bots#keyboards
|
||||
pub fn reply_markup(mut self, val: ReplyMarkup) -> Self {
|
||||
self.reply_markup = Some(val);
|
||||
self
|
||||
}
|
||||
}
|
50
src/requests/all/set_my_commands.rs
Normal file
50
src/requests/all/set_my_commands.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
net,
|
||||
requests::{Request, ResponseResult},
|
||||
types::{BotCommand, True},
|
||||
Bot,
|
||||
};
|
||||
|
||||
/// Use this method to change the list of the bot's commands.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#setmycommands).
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SetMyCommands {
|
||||
#[serde(skip_serializing)]
|
||||
bot: Bot,
|
||||
|
||||
commands: Vec<BotCommand>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Request for SetMyCommands {
|
||||
type Output = True;
|
||||
|
||||
async fn send(&self) -> ResponseResult<Self::Output> {
|
||||
net::request_json(self.bot.client(), self.bot.token(), "setMyCommands", &self).await
|
||||
}
|
||||
}
|
||||
|
||||
impl SetMyCommands {
|
||||
pub(crate) fn new<C>(bot: Bot, commands: C) -> Self
|
||||
where
|
||||
C: Into<Vec<BotCommand>>,
|
||||
{
|
||||
Self { bot, commands: commands.into() }
|
||||
}
|
||||
|
||||
/// A JSON-serialized list of bot commands to be set as the list of the
|
||||
/// bot's commands.
|
||||
///
|
||||
/// At most 100 commands can be specified.
|
||||
pub fn commands<C>(mut self, commands: C) -> Self
|
||||
where
|
||||
C: Into<Vec<BotCommand>>,
|
||||
{
|
||||
self.commands = commands.into();
|
||||
self
|
||||
}
|
||||
}
|
73
src/requests/all/set_sticker_set_thumb.rs
Normal file
73
src/requests/all/set_sticker_set_thumb.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
net,
|
||||
requests::{Request, ResponseResult},
|
||||
types::{InputFile, True},
|
||||
Bot,
|
||||
};
|
||||
|
||||
/// Use this method to set the thumbnail of a sticker set. Animated thumbnails
|
||||
/// can be set for animated sticker sets only.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#setstickersetthumb).
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SetStickerSetThumb {
|
||||
#[serde(skip_serializing)]
|
||||
bot: Bot,
|
||||
name: String,
|
||||
user_id: i32,
|
||||
thumb: Option<InputFile>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Request for SetStickerSetThumb {
|
||||
type Output = True;
|
||||
|
||||
async fn send(&self) -> ResponseResult<Self::Output> {
|
||||
net::request_json(self.bot.client(), self.bot.token(), "setStickerSetThumb", &self).await
|
||||
}
|
||||
}
|
||||
|
||||
impl SetStickerSetThumb {
|
||||
pub(crate) fn new<S>(bot: Bot, name: S, user_id: i32) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
Self { bot, name: name.into(), user_id, thumb: None }
|
||||
}
|
||||
|
||||
/// Sticker set name.
|
||||
pub fn name<T>(mut self, val: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
self.name = val.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// User identifier of the sticker set owner.
|
||||
pub fn user_id(mut self, val: i32) -> Self {
|
||||
self.user_id = val;
|
||||
self
|
||||
}
|
||||
|
||||
/// A PNG image with the thumbnail, must be up to 128 kilobytes in size and
|
||||
/// have width and height exactly 100px, or a TGS animation with the
|
||||
/// thumbnail up to 32 kilobytes in size; see https://core.telegram.org/animated_stickers#technical-requirements
|
||||
/// for animated sticker technical requirements.
|
||||
///
|
||||
/// Pass [`InputFile::FileId`] as a String to send a file that already
|
||||
/// exists on the Telegram servers, pass [`InputFile::Url`] for Telegram
|
||||
/// to get a file from the Internet, or upload a new one using
|
||||
/// multipart/form-data. More info on Sending Files ». Animated sticker
|
||||
/// set thumbnail can't be uploaded via HTTP URL.
|
||||
///
|
||||
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
|
||||
/// [`InputFile::Url]: crate::types::InputFile::Url
|
||||
pub fn thumb(mut self, val: InputFile) -> Self {
|
||||
self.thumb = Some(val);
|
||||
self
|
||||
}
|
||||
}
|
42
src/types/bot_command.rs
Normal file
42
src/types/bot_command.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// This object represents a bot command.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#botcommand).
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct BotCommand {
|
||||
/// Text of the command, 1-32 characters.
|
||||
///
|
||||
/// Can contain only lowercase English letters, digits and underscores.
|
||||
pub command: String,
|
||||
|
||||
/// Description of the command, 3-256 characters.
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
impl BotCommand {
|
||||
pub fn new<S1, S2>(command: S1, description: S2) -> Self
|
||||
where
|
||||
S1: Into<String>,
|
||||
S2: Into<String>,
|
||||
{
|
||||
Self { command: command.into(), description: description.into() }
|
||||
}
|
||||
|
||||
pub fn command<S>(mut self, val: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.command = val.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn description<S>(mut self, val: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.description = val.into();
|
||||
self
|
||||
}
|
||||
}
|
38
src/types/dice.rs
Normal file
38
src/types/dice.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::types::DiceEmoji;
|
||||
|
||||
/// This object represents an animated emoji that displays a random value.
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct Dice {
|
||||
/// Emoji on which the dice throw animation is based.
|
||||
emoji: DiceEmoji,
|
||||
|
||||
/// Value of the dice.
|
||||
///
|
||||
/// 1-6 for [`DiceEmoji::Dice`] and [`DiceEmoji::Darts`], 1-5 for
|
||||
/// [`DiceEmoji::Basketball`].
|
||||
///
|
||||
/// [`DiceEmoji::Dice`]: crate::types::DiceEmoji::Dice
|
||||
/// [`DiceEmoji::Darts`]:crate::types::DiceEmoji::Darts
|
||||
/// [`DiceEmoji::Basketball`]:crate::types::DiceEmoji::Basketball
|
||||
value: i32,
|
||||
}
|
||||
|
||||
impl Dice {
|
||||
pub fn new(emoji: DiceEmoji, value: i32) -> Self {
|
||||
Self { emoji, value }
|
||||
}
|
||||
|
||||
pub fn emoji(mut self, val: DiceEmoji) -> Self {
|
||||
self.emoji = val;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn value<S>(mut self, val: i32) -> Self {
|
||||
self.value = val;
|
||||
self
|
||||
}
|
||||
}
|
16
src/types/dice_emoji.rs
Normal file
16
src/types/dice_emoji.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||
pub enum DiceEmoji {
|
||||
/// Values from 1-6. Defaults to this variant.
|
||||
#[serde(rename = "🎲")]
|
||||
Dice,
|
||||
|
||||
/// Values from 1-6.
|
||||
#[serde(rename = "🎯")]
|
||||
Darts,
|
||||
|
||||
/// Values from 1-5.
|
||||
#[serde(rename = "🏀")]
|
||||
Basketball,
|
||||
}
|
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::types::{
|
||||
chat::{ChatKind, PublicChatKind},
|
||||
Animation, Audio, Chat, ChatPublic, Contact, Document, Game, InlineKeyboardMarkup, Invoice,
|
||||
Location, MessageEntity, PassportData, PhotoSize, Poll, PublicChatChannel,
|
||||
Animation, Audio, Chat, ChatPublic, Contact, Dice, Document, Game, InlineKeyboardMarkup,
|
||||
Invoice, Location, MessageEntity, PassportData, PhotoSize, Poll, PublicChatChannel,
|
||||
PublicChatSupergroup, Sticker, SuccessfulPayment, True, User, Venue, Video, VideoNote, Voice,
|
||||
};
|
||||
|
||||
|
@ -74,6 +74,7 @@ pub enum MessageKind {
|
|||
SuccessfulPayment(MessageSuccessfulPayment),
|
||||
ConnectedWebsite(MessageConnectedWebsite),
|
||||
PassportData(MessagePassportData),
|
||||
Dice(MessageDice),
|
||||
}
|
||||
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
|
@ -1048,6 +1049,13 @@ impl MediaVenue {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct MessageDice {
|
||||
/// Message is a dice with random value from 1 to 6.
|
||||
dice: Dice,
|
||||
}
|
||||
|
||||
mod getters {
|
||||
use std::ops::Deref;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
pub use allowed_update::*;
|
||||
pub use animation::*;
|
||||
pub use audio::*;
|
||||
pub use bot_command::*;
|
||||
pub use callback_game::*;
|
||||
pub use callback_query::*;
|
||||
pub use chat::*;
|
||||
|
@ -14,6 +15,8 @@ pub use chat_permissions::*;
|
|||
pub use chat_photo::*;
|
||||
pub use chosen_inline_result::*;
|
||||
pub use contact::*;
|
||||
pub use dice::*;
|
||||
pub use dice_emoji::*;
|
||||
pub use document::*;
|
||||
pub use encrypted_credentials::*;
|
||||
pub use encrypted_passport_element::*;
|
||||
|
@ -78,6 +81,7 @@ pub use shipping_option::*;
|
|||
pub use shipping_query::*;
|
||||
pub use sticker::*;
|
||||
pub use sticker_set::*;
|
||||
pub use sticker_type::*;
|
||||
pub use successful_payment::*;
|
||||
pub use unit_false::*;
|
||||
pub use unit_true::*;
|
||||
|
@ -93,6 +97,7 @@ pub use webhook_info::*;
|
|||
mod allowed_update;
|
||||
mod animation;
|
||||
mod audio;
|
||||
mod bot_command;
|
||||
mod callback_game;
|
||||
mod callback_query;
|
||||
mod chat;
|
||||
|
@ -104,6 +109,8 @@ mod chat_permissions;
|
|||
mod chat_photo;
|
||||
mod chosen_inline_result;
|
||||
mod contact;
|
||||
mod dice;
|
||||
mod dice_emoji;
|
||||
mod document;
|
||||
mod file;
|
||||
mod force_reply;
|
||||
|
@ -141,6 +148,7 @@ mod shipping_option;
|
|||
mod shipping_query;
|
||||
mod sticker;
|
||||
mod sticker_set;
|
||||
mod sticker_type;
|
||||
mod successful_payment;
|
||||
mod unit_false;
|
||||
mod unit_true;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::types::Sticker;
|
||||
use crate::types::{PhotoSize, Sticker};
|
||||
|
||||
/// This object represents a sticker set.
|
||||
///
|
||||
|
@ -24,6 +24,9 @@ pub struct StickerSet {
|
|||
|
||||
/// List of all set stickers.
|
||||
pub stickers: Vec<Sticker>,
|
||||
|
||||
/// Sticker set thumbnail in the .WEBP or .TGS format.
|
||||
thumb: Option<PhotoSize>,
|
||||
}
|
||||
|
||||
impl StickerSet {
|
||||
|
@ -45,6 +48,7 @@ impl StickerSet {
|
|||
is_animated,
|
||||
contains_masks,
|
||||
stickers: stickers.into(),
|
||||
thumb: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
26
src/types/sticker_type.rs
Normal file
26
src/types/sticker_type.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::types::InputFile;
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub enum StickerType {
|
||||
/// PNG image with the sticker, must be up to 512 kilobytes in size,
|
||||
/// dimensions must not exceed 512px, and either width or height must be
|
||||
/// exactly 512px.
|
||||
///
|
||||
/// Pass [`InputFile::File`] to send a file that exists on
|
||||
/// the Telegram servers (recommended), pass an [`InputFile::Url`] for
|
||||
/// Telegram to get a .webp file from the Internet, or upload a new one
|
||||
/// using [`InputFile::FileId`]. [More info on Sending Files »].
|
||||
///
|
||||
/// [`InputFile::File`]: crate::types::InputFile::File
|
||||
/// [`InputFile::Url`]: crate::types::InputFile::Url
|
||||
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
|
||||
///
|
||||
/// [More info on Sending Files »]: https://core.telegram.org/bots/api#sending-files
|
||||
Png(InputFile),
|
||||
|
||||
/// TGS animation with the sticker, uploaded using multipart/form-data.
|
||||
///
|
||||
/// See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements
|
||||
Tgs(InputFile),
|
||||
}
|
|
@ -285,4 +285,36 @@ mod test {
|
|||
|
||||
serde_json::from_str::<Update>(json).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dice_works() {
|
||||
let json = r#"
|
||||
{
|
||||
"message": {
|
||||
"chat": {
|
||||
"id": -1001276785818,
|
||||
"title": "bla bla bla chat",
|
||||
"type": "supergroup",
|
||||
"username": "teloxide_dev"
|
||||
},
|
||||
"date": 1596014550,
|
||||
"dice": {
|
||||
"emoji": "🎲",
|
||||
"value": 2
|
||||
},
|
||||
"from": {
|
||||
"first_name": "Hirrolot",
|
||||
"id": 408258968,
|
||||
"is_bot": false,
|
||||
"language_code": "en",
|
||||
"username": "hirrolot"
|
||||
},
|
||||
"message_id": 35410
|
||||
},
|
||||
"update_id": 573255266
|
||||
}
|
||||
"#;
|
||||
|
||||
serde_json::from_str::<Update>(json).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue