use super::*;
use crate::{
event_loop::EventLoop,
types::{
callback, chat,
file::{id::AsFileId, File},
inline_message_id, inline_query,
input_file::*,
keyboard::inline,
message,
parameters::{CallbackAction, ImplicitChatId, Text, Updates},
passport, pre_checkout_query, shipping, user, LabeledPrice,
},
};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct Bot<C> {
pub(crate) token: Token,
pub(crate) client: Arc<crate::internal::Client<C>>,
}
impl Bot<connectors::Https> {
pub fn new(token: Token) -> Self {
Self {
token,
client: Arc::new(connectors::default()),
}
}
pub fn from_env(env_var: &'static str) -> Self {
Self::new(extract_token(env_var))
}
}
impl<C> Bot<C> {
pub fn event_loop(self) -> EventLoop<C> {
EventLoop::new(self)
}
pub fn add_sticker_to_set<'a>(
&'a self,
user_id: user::Id,
name: &'a str,
png_sticker: PngSticker<'a>,
emojis: &'a str,
) -> methods::AddStickerToSet<'a, C> {
methods::AddStickerToSet::new(
&self.client,
self.token.clone(),
user_id,
name,
png_sticker,
emojis,
)
}
pub(crate) fn answer_callback_query<'a>(
&'a self,
callback_query_id: callback::query::id::Ref<'a>,
action: CallbackAction<'a>,
) -> methods::AnswerCallbackQuery<'a, C> {
methods::AnswerCallbackQuery::new(
&self.client,
self.token.clone(),
callback_query_id,
action,
)
}
pub(crate) fn answer_inline_query<'a>(
&'a self,
inline_query_id: inline_query::id::Ref<'a>,
results: &'a [inline_query::Result<'a>],
) -> methods::AnswerInlineQuery<'a, C> {
methods::AnswerInlineQuery::new(
&self.client,
self.token.clone(),
inline_query_id,
results,
)
}
pub(crate) fn answer_pre_checkout_query<'a>(
&'a self,
pre_checkout_query_id: pre_checkout_query::id::Ref<'a>,
result: Result<(), &'a str>,
) -> methods::AnswerPreCheckoutQuery<'a, C> {
methods::AnswerPreCheckoutQuery::new(
&self.client,
self.token.clone(),
pre_checkout_query_id,
result,
)
}
pub(crate) fn answer_shipping_query<'a>(
&'a self,
shipping_query_id: shipping::query::id::Ref<'a>,
result: Result<&'a [shipping::Option<'a>], &'a str>,
) -> methods::AnswerShippingQuery<'a, C> {
methods::AnswerShippingQuery::new(
&self.client,
self.token.clone(),
shipping_query_id,
result,
)
}
pub fn create_new_sticker_set<'a>(
&'a self,
user_id: user::Id,
name: &'a str,
title: &'a str,
png_sticker: PngSticker<'a>,
emojis: &'a str,
) -> methods::CreateNewStickerSet<'a, C> {
methods::CreateNewStickerSet::new(
&self.client,
self.token.clone(),
user_id,
name,
title,
png_sticker,
emojis,
)
}
pub fn delete_chat_photo<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::DeleteChatPhoto<'a, C> {
methods::DeleteChatPhoto::new(&self.client, self.token.clone(), chat_id)
}
pub fn delete_chat_sticker_set<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::DeleteChatStickerSet<'a, C> {
methods::DeleteChatStickerSet::new(
&self.client,
self.token.clone(),
chat_id,
)
}
pub fn delete_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> methods::DeleteMessage<'a, C> {
methods::DeleteMessage::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
)
}
pub fn delete_sticker_from_set<'a>(
&'a self,
sticker: &'a str,
) -> methods::DeleteStickerFromSet<'a, C> {
methods::DeleteStickerFromSet::new(
&self.client,
self.token.clone(),
sticker,
)
}
pub(crate) fn delete_webhook(&self) -> methods::DeleteWebhook<'_, C> {
methods::DeleteWebhook::new(&self.client, self.token.clone())
}
pub fn edit_inline_caption<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
caption: impl Into<Text<'a>>,
) -> methods::EditInlineCaption<'a, C> {
methods::EditInlineCaption::new(
&self.client,
self.token.clone(),
inline_message_id,
caption,
)
}
pub fn edit_inline_location<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
position: (f64, f64),
) -> methods::EditInlineLocation<'a, C> {
methods::EditInlineLocation::new(
&self.client,
self.token.clone(),
inline_message_id,
position,
)
}
pub fn edit_inline_media<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
media: impl Into<EditableMedia<'a>>,
) -> methods::EditInlineMedia<'a, C> {
methods::EditInlineMedia::new(
&self.client,
self.token.clone(),
inline_message_id,
media,
)
}
pub fn edit_inline_reply_markup<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
reply_markup: inline::Keyboard<'a>,
) -> methods::EditInlineReplyMarkup<'a, C> {
methods::EditInlineReplyMarkup::new(
&self.client,
self.token.clone(),
inline_message_id,
reply_markup,
)
}
pub fn edit_inline_text<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
text: impl Into<Text<'a>>,
) -> methods::EditInlineText<'a, C> {
methods::EditInlineText::new(
&self.client,
self.token.clone(),
inline_message_id,
text,
)
}
pub fn edit_message_caption<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
caption: impl Into<Text<'a>>,
) -> methods::EditMessageCaption<'a, C> {
methods::EditMessageCaption::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
caption,
)
}
pub fn edit_message_location<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
position: (f64, f64),
) -> methods::EditMessageLocation<'a, C> {
methods::EditMessageLocation::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
position,
)
}
pub fn edit_message_media<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
media: impl Into<EditableMedia<'a>>,
) -> methods::EditMessageMedia<'a, C> {
methods::EditMessageMedia::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
media,
)
}
pub fn edit_message_reply_markup<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
reply_markup: inline::Keyboard<'a>,
) -> methods::EditMessageReplyMarkup<'a, C> {
methods::EditMessageReplyMarkup::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
reply_markup,
)
}
pub fn edit_message_text<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
text: impl Into<Text<'a>>,
) -> methods::EditMessageText<'a, C> {
methods::EditMessageText::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
text,
)
}
pub fn export_chat_invite_link<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::ExportChatInviteLink<'a, C> {
methods::ExportChatInviteLink::new(
&self.client,
self.token.clone(),
chat_id,
)
}
pub fn forward_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
from_chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> methods::ForwardMessage<'a, C> {
methods::ForwardMessage::new(
&self.client,
self.token.clone(),
chat_id,
from_chat_id,
message_id,
)
}
pub fn get_chat<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::GetChat<'a, C> {
methods::GetChat::new(&self.client, self.token.clone(), chat_id)
}
pub fn get_file<'a>(
&'a self,
file_id: &'a impl AsFileId,
) -> methods::GetFile<'a, C> {
methods::GetFile::new(&self.client, self.token.clone(), file_id)
}
pub fn get_inline_game_high_scores<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
user_id: user::Id,
) -> methods::GetInlineGameHighScores<'a, C> {
methods::GetInlineGameHighScores::new(
&self.client,
self.token.clone(),
inline_message_id,
user_id,
)
}
pub fn get_chat_administrators<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::GetChatAdministrators<'a, C> {
methods::GetChatAdministrators::new(
&self.client,
self.token.clone(),
chat_id,
)
}
pub fn get_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> methods::GetChatMember<'a, C> {
methods::GetChatMember::new(
&self.client,
self.token.clone(),
chat_id,
user_id,
)
}
pub fn get_chat_members_count<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::GetChatMembersCount<'a, C> {
methods::GetChatMembersCount::new(
&self.client,
self.token.clone(),
chat_id,
)
}
pub fn get_message_game_high_scores<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
user_id: user::Id,
) -> methods::GetMessageGameHighScores<'a, C> {
methods::GetMessageGameHighScores::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
user_id,
)
}
pub fn get_me(&self) -> methods::GetMe<'_, C> {
methods::GetMe::new(&self.client, self.token.clone())
}
pub fn get_sticker_set<'a>(
&'a self,
name: &'a str,
) -> methods::GetStickerSet<'a, C> {
methods::GetStickerSet::new(&self.client, self.token.clone(), name)
}
pub(crate) fn get_updates<'a>(
&'a self,
offset: Option<isize>,
limit: Option<u8>,
timeout: Option<u64>,
allowed_updates: Option<&'a [Updates]>,
) -> methods::GetUpdates<'a, C> {
methods::GetUpdates::new(
&self.client,
self.token.clone(),
offset,
limit,
timeout,
allowed_updates,
)
}
pub fn get_user_profile_photos(
&self,
user_id: user::Id,
) -> methods::GetUserProfilePhotos<'_, C> {
methods::GetUserProfilePhotos::new(
&self.client,
self.token.clone(),
user_id,
)
}
pub fn get_webhook_info(&self) -> methods::GetWebhookInfo<'_, C> {
methods::GetWebhookInfo::new(&self.client, self.token.clone())
}
pub fn kick_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> methods::KickChatMember<'a, C> {
methods::KickChatMember::new(
&self.client,
self.token.clone(),
chat_id,
user_id,
)
}
pub fn leave_chat<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::LeaveChat<'a, C> {
methods::LeaveChat::new(&self.client, self.token.clone(), chat_id)
}
pub fn pin_chat_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> methods::PinChatMessage<'a, C> {
methods::PinChatMessage::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
)
}
pub fn promote_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> methods::PromoteChatMember<'a, C> {
methods::PromoteChatMember::new(
&self.client,
self.token.clone(),
chat_id,
user_id,
)
}
pub fn restrict_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
permissions: chat::Permissions,
) -> methods::RestrictChatMember<'a, C> {
methods::RestrictChatMember::new(
&self.client,
self.token.clone(),
chat_id,
user_id,
permissions,
)
}
pub fn send_animation<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
animation: Animation<'a>,
) -> methods::SendAnimation<'a, C> {
methods::SendAnimation::new(
&self.client,
self.token.clone(),
chat_id,
animation,
)
}
pub fn send_audio<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
audio: Audio<'a>,
) -> methods::SendAudio<'a, C> {
methods::SendAudio::new(
&self.client,
self.token.clone(),
chat_id,
audio,
)
}
pub fn send_chat_action<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
action: chat::Action,
) -> methods::SendChatAction<'a, C> {
methods::SendChatAction::new(
&self.client,
self.token.clone(),
chat_id,
action,
)
}
pub fn send_contact<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
phone_number: &'a str,
first_name: &'a str,
) -> methods::SendContact<'a, C> {
methods::SendContact::new(
&self.client,
self.token.clone(),
chat_id,
phone_number,
first_name,
)
}
pub fn send_game<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
game_short_name: &'a str,
) -> methods::SendGame<'a, C> {
methods::SendGame::new(
&self.client,
self.token.clone(),
chat_id,
game_short_name,
)
}
pub fn send_document<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
document: Document<'a>,
) -> methods::SendDocument<'a, C> {
methods::SendDocument::new(
&self.client,
self.token.clone(),
chat_id,
document,
)
}
#[allow(clippy::too_many_arguments)]
pub fn send_invoice<'a>(
&'a self,
chat_id: impl Into<chat::Id>,
title: &'a str,
description: &'a str,
payload: &'a str,
provider_token: &'a str,
start_parameter: &'a str,
currency: &'a str,
prices: &'a [LabeledPrice<'a>],
) -> methods::SendInvoice<'a, C> {
methods::SendInvoice::new(
&self.client,
self.token.clone(),
chat_id,
title,
description,
payload,
provider_token,
start_parameter,
currency,
prices,
)
}
pub fn send_location<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
position: (f64, f64),
) -> methods::SendLocation<'a, C> {
methods::SendLocation::new(
&self.client,
self.token.clone(),
chat_id,
position,
)
}
pub fn send_media_group<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
media: &'a [GroupMedia<'a>],
) -> methods::SendMediaGroup<'a, C> {
methods::SendMediaGroup::new(
&self.client,
self.token.clone(),
chat_id,
media,
)
}
pub fn send_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
text: impl Into<Text<'a>>,
) -> methods::SendMessage<'a, C> {
methods::SendMessage::new(
&self.client,
self.token.clone(),
chat_id,
text,
)
}
pub fn send_photo<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
photo: Photo<'a>,
) -> methods::SendPhoto<'a, C> {
methods::SendPhoto::new(
&self.client,
self.token.clone(),
chat_id,
photo,
)
}
pub fn send_poll<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
question: &'a str,
options: &'a [&'a str],
) -> methods::SendPoll<'a, C> {
methods::SendPoll::new(
&self.client,
self.token.clone(),
chat_id,
question,
options,
)
}
pub fn send_sticker<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
sticker: Sticker<'a>,
) -> methods::SendSticker<'a, C> {
methods::SendSticker::new(
&self.client,
self.token.clone(),
chat_id,
sticker,
)
}
pub fn send_venue<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
position: (f64, f64),
title: &'a str,
address: &'a str,
) -> methods::SendVenue<'a, C> {
methods::SendVenue::new(
&self.client,
self.token.clone(),
chat_id,
position,
title,
address,
)
}
pub fn send_video_note<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
video_note: VideoNote<'a>,
) -> methods::SendVideoNote<'a, C> {
methods::SendVideoNote::new(
&self.client,
self.token.clone(),
chat_id,
video_note,
)
}
pub fn send_video<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
video: Video<'a>,
) -> methods::SendVideo<'a, C> {
methods::SendVideo::new(
&self.client,
self.token.clone(),
chat_id,
video,
)
}
pub fn send_voice<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
voice: Voice<'a>,
) -> methods::SendVoice<'a, C> {
methods::SendVoice::new(
&self.client,
self.token.clone(),
chat_id,
voice,
)
}
pub fn set_chat_description<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
description: &'a str,
) -> methods::SetChatDescription<'a, C> {
methods::SetChatDescription::new(
&self.client,
self.token.clone(),
chat_id,
description,
)
}
pub fn set_chat_permissions<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
permissions: chat::Permissions,
) -> methods::SetChatPermissions<'a, C> {
methods::SetChatPermissions::new(
&self.client,
self.token.clone(),
chat_id,
permissions,
)
}
pub fn set_chat_photo<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
photo: ChatPhoto<'a>,
) -> methods::SetChatPhoto<'a, C> {
methods::SetChatPhoto::new(
&self.client,
self.token.clone(),
chat_id,
photo,
)
}
pub fn set_chat_sticker_set<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
sticker_set_name: &'a str,
) -> methods::SetChatStickerSet<'a, C> {
methods::SetChatStickerSet::new(
&self.client,
self.token.clone(),
chat_id,
sticker_set_name,
)
}
pub fn set_chat_title<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
title: &'a str,
) -> methods::SetChatTitle<'a, C> {
methods::SetChatTitle::new(
&self.client,
self.token.clone(),
chat_id,
title,
)
}
pub fn set_inline_game_score<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
user_id: user::Id,
score: u32,
) -> methods::SetInlineGameScore<'a, C> {
methods::SetInlineGameScore::new(
&self.client,
self.token.clone(),
inline_message_id,
user_id,
score,
)
}
pub fn set_message_game_score<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
user_id: user::Id,
score: u32,
) -> methods::SetMessageGameScore<'a, C> {
methods::SetMessageGameScore::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
user_id,
score,
)
}
pub fn set_passport_data_errors<'a>(
&'a self,
user_id: user::Id,
errors: &'a [passport::element::Error<'a>],
) -> methods::SetPassportDataErrors<'a, C> {
methods::SetPassportDataErrors::new(
&self.client,
self.token.clone(),
user_id,
errors,
)
}
pub fn set_sticker_position_in_set<'a>(
&'a self,
sticker: &'a str,
position: u32,
) -> methods::SetStickerPositionInSet<'a, C> {
methods::SetStickerPositionInSet::new(
&self.client,
self.token.clone(),
sticker,
position,
)
}
pub(crate) fn set_webhook<'a>(
&'a self,
url: &'a str,
certificate: Option<&'a str>,
max_connections: Option<u8>,
allowed_updates: Option<&'a [Updates]>,
) -> methods::SetWebhook<'a, C> {
methods::SetWebhook::new(
&self.client,
self.token.clone(),
url,
certificate,
max_connections,
allowed_updates,
)
}
pub fn stop_inline_location<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
) -> methods::StopInlineLocation<'a, C> {
methods::StopInlineLocation::new(
&self.client,
self.token.clone(),
inline_message_id,
)
}
pub fn stop_message_location<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> methods::StopMessageLocation<'a, C> {
methods::StopMessageLocation::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
)
}
pub fn stop_poll<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> methods::StopPoll<'a, C> {
methods::StopPoll::new(
&self.client,
self.token.clone(),
chat_id,
message_id,
)
}
pub fn unban_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> methods::UnbanChatMember<'a, C> {
methods::UnbanChatMember::new(
&self.client,
self.token.clone(),
chat_id,
user_id,
)
}
pub fn unpin_chat_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> methods::UnpinChatMessage<'a, C> {
methods::UnpinChatMessage::new(
&self.client,
self.token.clone(),
chat_id,
)
}
pub fn upload_sticker_file<'a>(
&'a self,
user_id: user::Id,
png_sticker: &'a [u8],
) -> methods::UploadStickerFile<'a, C> {
methods::UploadStickerFile::new(
&self.client,
self.token.clone(),
user_id,
png_sticker,
)
}
}
impl<C> Bot<C>
where
C: hyper::client::connect::Connect + Sync + 'static,
C::Transport: 'static,
C::Future: 'static,
{
pub fn with_connector(token: Token, connector: C) -> Self {
Self {
token,
client: Arc::new(connectors::create_client(connector)),
}
}
pub fn from_env_with_connector(
env_var: &'static str,
connector: C,
) -> Self {
Self::with_connector(extract_token(env_var), connector)
}
pub fn download_file(
&self,
file: &File,
) -> impl Future<Item = Vec<u8>, Error = errors::Download> {
download_file(&self.client, &self.token, file)
}
}
#[macro_export]
macro_rules! bot {
($var:literal) => {{
let token = env!($var).to_string();
$crate::Bot::new($crate::Token::new(token))
}};
($var:literal,) => {
$crate::bot!($var)
};
($var:literal, $connector:expr) => {{
let token = env!($var).to_string();
$crate::Bot::with_connector($crate::Token::new(token), $connector)
}};
($var:literal, $connector:expr,) => {
$crate::bot!($var, $connector)
};
() => {
compile_error!(
"the macro must be invoked as `bot!(\"<VAR_NAME>\")` or \
`bot!(\"<VAR_NAME>\", connector)`"
)
};
($($x:tt)+) => {
$crate::bot!()
};
}
fn extract_token(env_var: &'static str) -> Token {
Token::new(std::env::var(env_var).unwrap_or_else(|_| {
panic!("\n[tbot] Bot's token in {} was not specified\n", env_var)
}))
}