#![allow(clippy::wildcard_imports)]
use crate::{
connectors::{self, Client},
download_file, errors,
event_loop::EventLoop,
internal::Sealed,
methods::*,
state::StatefulEventLoop,
types::{
callback, chat,
file::{id::AsFileId, File},
inline_message_id, inline_query,
input_file::{
Animation, Audio, ChatPhoto, Document, EditableMedia, GroupMedia,
Photo, Sticker, StickerForStickerSet, StickerSetThumb, Video,
VideoNote, Voice,
},
keyboard::inline,
message,
parameters::{
Any, BotCommand, CallbackAction, ImplicitChatId, Text, UpdateKind,
},
passport, pre_checkout_query, shipping, user, LabeledPrice,
},
Token,
};
use hyper_proxy::Proxy;
use std::sync::Arc;
#[derive(Debug, Clone)]
#[must_use]
pub struct Bot {
pub(crate) token: Token,
pub(crate) client: Arc<Client>,
}
impl Bot {
pub fn new(token: String) -> Self {
Self {
token: Token::new(token),
client: Arc::new(Client::https()),
}
}
pub fn with_proxy(token: String, proxy: Proxy) -> Self {
Self {
token: Token::new(token),
client: Arc::new(connectors::Client::proxy(proxy)),
}
}
pub fn from_env_with_proxy(env_var: &'static str, proxy: Proxy) -> Self {
Self::with_proxy(extract_token(env_var), proxy)
}
pub async fn download_file(
&self,
file: &File,
) -> Result<Vec<u8>, errors::Download> {
download_file(&self.client, self.token.as_ref(), file).await
}
pub fn from_env(env_var: &'static str) -> Self {
Self::new(extract_token(env_var))
}
pub fn event_loop(self) -> EventLoop {
EventLoop::new(self)
}
pub fn stateful_event_loop<S>(self, state: S) -> StatefulEventLoop<S>
where
S: Send + Sync + 'static,
{
StatefulEventLoop::new(EventLoop::new(self), state)
}
pub fn add_sticker_to_set<'a>(
&'a self,
user_id: user::Id,
name: &'a str,
png_sticker: impl Into<StickerForStickerSet<'a>>,
emojis: &'a str,
) -> AddStickerToSet<'a> {
AddStickerToSet::new(
&self.client,
self.token.as_ref(),
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>,
) -> AnswerCallbackQuery<'a> {
AnswerCallbackQuery::new(
&self.client,
self.token.as_ref(),
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>],
) -> AnswerInlineQuery<'a> {
AnswerInlineQuery::new(
&self.client,
self.token.as_ref(),
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>,
) -> AnswerPreCheckoutQuery<'a> {
AnswerPreCheckoutQuery::new(
&self.client,
self.token.as_ref(),
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>,
) -> AnswerShippingQuery<'a> {
AnswerShippingQuery::new(
&self.client,
self.token.as_ref(),
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: impl Into<StickerForStickerSet<'a>>,
emojis: &'a str,
) -> CreateNewStickerSet<'a> {
CreateNewStickerSet::new(
&self.client,
self.token.as_ref(),
user_id,
name,
title,
png_sticker,
emojis,
)
}
pub fn delete_chat_photo<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> DeleteChatPhoto<'a> {
DeleteChatPhoto::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn delete_chat_sticker_set<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> DeleteChatStickerSet<'a> {
DeleteChatStickerSet::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn delete_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> DeleteMessage<'a> {
DeleteMessage::new(
&self.client,
self.token.as_ref(),
chat_id,
message_id,
)
}
pub fn delete_sticker_from_set<'a>(
&'a self,
sticker: &'a str,
) -> DeleteStickerFromSet<'a> {
DeleteStickerFromSet::new(&self.client, self.token.as_ref(), sticker)
}
pub(crate) fn delete_webhook(&self) -> DeleteWebhook<'_> {
DeleteWebhook::new(&self.client, self.token.as_ref())
}
pub fn edit_inline_caption<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
caption: impl Into<Text<'a>>,
) -> EditInlineCaption<'a> {
EditInlineCaption::new(
&self.client,
self.token.as_ref(),
inline_message_id,
caption,
)
}
pub fn edit_inline_location<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
position: (f64, f64),
) -> EditInlineLocation<'a> {
EditInlineLocation::new(
&self.client,
self.token.as_ref(),
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>>,
) -> EditInlineMedia<'a> {
EditInlineMedia::new(
&self.client,
self.token.as_ref(),
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>,
) -> EditInlineReplyMarkup<'a> {
EditInlineReplyMarkup::new(
&self.client,
self.token.as_ref(),
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>>,
) -> EditInlineText<'a> {
EditInlineText::new(
&self.client,
self.token.as_ref(),
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>>,
) -> EditMessageCaption<'a> {
EditMessageCaption::new(
&self.client,
self.token.as_ref(),
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),
) -> EditMessageLocation<'a> {
EditMessageLocation::new(
&self.client,
self.token.as_ref(),
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>>,
) -> EditMessageMedia<'a> {
EditMessageMedia::new(
&self.client,
self.token.as_ref(),
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>,
) -> EditMessageReplyMarkup<'a> {
EditMessageReplyMarkup::new(
&self.client,
self.token.as_ref(),
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>>,
) -> EditMessageText<'a> {
EditMessageText::new(
&self.client,
self.token.as_ref(),
chat_id,
message_id,
text,
)
}
pub fn export_chat_invite_link<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> ExportChatInviteLink<'a> {
ExportChatInviteLink::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn forward_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
from_chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> ForwardMessage<'a> {
ForwardMessage::new(
&self.client,
self.token.as_ref(),
chat_id,
from_chat_id,
message_id,
)
}
pub fn get_chat<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> GetChat<'a> {
GetChat::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn get_file<'a>(&'a self, file_id: &'a impl AsFileId) -> GetFile<'a> {
GetFile::new(&self.client, self.token.as_ref(), file_id)
}
pub fn get_inline_game_high_scores<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
user_id: user::Id,
) -> GetInlineGameHighScores<'a> {
GetInlineGameHighScores::new(
&self.client,
self.token.as_ref(),
inline_message_id,
user_id,
)
}
pub fn get_chat_administrators<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> GetChatAdministrators<'a> {
GetChatAdministrators::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn get_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> GetChatMember<'a> {
GetChatMember::new(&self.client, self.token.as_ref(), chat_id, user_id)
}
pub fn get_chat_members_count<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> GetChatMembersCount<'a> {
GetChatMembersCount::new(&self.client, self.token.as_ref(), 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,
) -> GetMessageGameHighScores<'a> {
GetMessageGameHighScores::new(
&self.client,
self.token.as_ref(),
chat_id,
message_id,
user_id,
)
}
pub fn get_me(&self) -> GetMe<'_> {
GetMe::new(&self.client, self.token.as_ref())
}
pub fn get_my_commands(&self) -> GetMyCommands<'_> {
GetMyCommands::new(&self.client, self.token.as_ref())
}
pub fn get_sticker_set<'a>(&'a self, name: &'a str) -> GetStickerSet<'a> {
GetStickerSet::new(&self.client, self.token.as_ref(), name)
}
pub(crate) fn get_updates<'a>(
&'a self,
offset: Option<isize>,
limit: Option<u8>,
timeout: Option<u64>,
allowed_updates: Option<&'a [UpdateKind]>,
) -> GetUpdates<'a> {
GetUpdates::new(
&self.client,
self.token.as_ref(),
offset,
limit,
timeout,
allowed_updates,
)
}
pub fn get_user_profile_photos(
&self,
user_id: user::Id,
) -> GetUserProfilePhotos<'_> {
GetUserProfilePhotos::new(&self.client, self.token.as_ref(), user_id)
}
pub fn get_webhook_info(&self) -> GetWebhookInfo<'_> {
GetWebhookInfo::new(&self.client, self.token.as_ref())
}
pub fn kick_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> KickChatMember<'a> {
KickChatMember::new(&self.client, self.token.as_ref(), chat_id, user_id)
}
pub fn leave_chat<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> LeaveChat<'a> {
LeaveChat::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn pin_chat_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> PinChatMessage<'a> {
PinChatMessage::new(
&self.client,
self.token.as_ref(),
chat_id,
message_id,
)
}
pub fn promote_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> PromoteChatMember<'a> {
PromoteChatMember::new(
&self.client,
self.token.as_ref(),
chat_id,
user_id,
)
}
pub fn restrict_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
permissions: chat::Permissions,
) -> RestrictChatMember<'a> {
RestrictChatMember::new(
&self.client,
self.token.as_ref(),
chat_id,
user_id,
permissions,
)
}
pub fn send_animation<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
animation: Animation<'a>,
) -> SendAnimation<'a> {
SendAnimation::new(
&self.client,
self.token.as_ref(),
chat_id,
animation,
)
}
pub fn send_audio<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
audio: Audio<'a>,
) -> SendAudio<'a> {
SendAudio::new(&self.client, self.token.as_ref(), chat_id, audio)
}
pub fn send_chat_action<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
action: chat::Action,
) -> SendChatAction<'a> {
SendChatAction::new(&self.client, self.token.as_ref(), chat_id, action)
}
pub fn send_contact<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
phone_number: &'a str,
first_name: &'a str,
) -> SendContact<'a> {
SendContact::new(
&self.client,
self.token.as_ref(),
chat_id,
phone_number,
first_name,
)
}
pub fn send_game<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
game_short_name: &'a str,
) -> SendGame<'a> {
SendGame::new(
&self.client,
self.token.as_ref(),
chat_id,
game_short_name,
)
}
pub fn send_dice<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> SendDice<'a> {
SendDice::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn send_document<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
document: Document<'a>,
) -> SendDocument<'a> {
SendDocument::new(&self.client, self.token.as_ref(), 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>],
) -> SendInvoice<'a> {
SendInvoice::new(
&self.client,
self.token.as_ref(),
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),
) -> SendLocation<'a> {
SendLocation::new(&self.client, self.token.as_ref(), chat_id, position)
}
pub fn send_media_group<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
media: &'a [GroupMedia<'a>],
) -> SendMediaGroup<'a> {
SendMediaGroup::new(&self.client, self.token.as_ref(), chat_id, media)
}
pub fn send_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
text: impl Into<Text<'a>>,
) -> SendMessage<'a> {
SendMessage::new(&self.client, self.token.as_ref(), chat_id, text)
}
pub fn send_photo<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
photo: Photo<'a>,
) -> SendPhoto<'a> {
SendPhoto::new(&self.client, self.token.as_ref(), chat_id, photo)
}
pub fn send_poll<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
poll: &'a Any<'a>,
) -> SendPoll<'a> {
SendPoll::new(&self.client, self.token.as_ref(), chat_id, poll)
}
pub fn send_sticker<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
sticker: Sticker<'a>,
) -> SendSticker<'a> {
SendSticker::new(&self.client, self.token.as_ref(), chat_id, sticker)
}
pub fn send_venue<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
position: (f64, f64),
title: &'a str,
address: &'a str,
) -> SendVenue<'a> {
SendVenue::new(
&self.client,
self.token.as_ref(),
chat_id,
position,
title,
address,
)
}
pub fn send_video_note<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
video_note: VideoNote<'a>,
) -> SendVideoNote<'a> {
SendVideoNote::new(
&self.client,
self.token.as_ref(),
chat_id,
video_note,
)
}
pub fn send_video<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
video: Video<'a>,
) -> SendVideo<'a> {
SendVideo::new(&self.client, self.token.as_ref(), chat_id, video)
}
pub fn send_voice<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
voice: Voice<'a>,
) -> SendVoice<'a> {
SendVoice::new(&self.client, self.token.as_ref(), chat_id, voice)
}
pub fn set_chat_administrator_custom_title<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
custom_title: &'a str,
) -> SetChatAdministratorCustomTitle<'a> {
SetChatAdministratorCustomTitle::new(
&self.client,
self.token.as_ref(),
chat_id,
user_id,
custom_title,
)
}
pub fn set_chat_description<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
description: &'a str,
) -> SetChatDescription<'a> {
SetChatDescription::new(
&self.client,
self.token.as_ref(),
chat_id,
description,
)
}
pub fn set_chat_permissions<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
permissions: chat::Permissions,
) -> SetChatPermissions<'a> {
SetChatPermissions::new(
&self.client,
self.token.as_ref(),
chat_id,
permissions,
)
}
pub fn set_chat_photo<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
photo: ChatPhoto<'a>,
) -> SetChatPhoto<'a> {
SetChatPhoto::new(&self.client, self.token.as_ref(), chat_id, photo)
}
pub fn set_chat_sticker_set<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
sticker_set_name: &'a str,
) -> SetChatStickerSet<'a> {
SetChatStickerSet::new(
&self.client,
self.token.as_ref(),
chat_id,
sticker_set_name,
)
}
pub fn set_chat_title<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
title: &'a str,
) -> SetChatTitle<'a> {
SetChatTitle::new(&self.client, self.token.as_ref(), 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,
) -> SetInlineGameScore<'a> {
SetInlineGameScore::new(
&self.client,
self.token.as_ref(),
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,
) -> SetMessageGameScore<'a> {
SetMessageGameScore::new(
&self.client,
self.token.as_ref(),
chat_id,
message_id,
user_id,
score,
)
}
pub fn set_my_commands<'a>(
&'a self,
commands: &'a [BotCommand<'a>],
) -> SetMyCommands<'a> {
SetMyCommands::new(&self.client, self.token.as_ref(), commands)
}
pub fn set_passport_data_errors<'a>(
&'a self,
user_id: user::Id,
errors: &'a [passport::element::Error<'a>],
) -> SetPassportDataErrors<'a> {
SetPassportDataErrors::new(
&self.client,
self.token.as_ref(),
user_id,
errors,
)
}
pub fn set_sticker_position_in_set<'a>(
&'a self,
sticker: &'a str,
position: u32,
) -> SetStickerPositionInSet<'a> {
SetStickerPositionInSet::new(
&self.client,
self.token.as_ref(),
sticker,
position,
)
}
pub fn set_sticker_set_thumb<'a>(
&'a self,
user_id: user::Id,
name: &'a str,
thumb: Option<&'a StickerSetThumb<'a>>,
) -> SetStickerSetThumb<'a> {
SetStickerSetThumb::new(
&self.client,
self.token.as_ref(),
user_id,
name,
thumb,
)
}
pub(crate) fn set_webhook<'a>(
&'a self,
url: &'a str,
certificate: Option<&'a str>,
max_connections: Option<u8>,
allowed_updates: Option<&'a [UpdateKind]>,
) -> SetWebhook<'a> {
SetWebhook::new(
&self.client,
self.token.as_ref(),
url,
certificate,
max_connections,
allowed_updates,
)
}
pub fn stop_inline_location<'a>(
&'a self,
inline_message_id: inline_message_id::Ref<'a>,
) -> StopInlineLocation<'a> {
StopInlineLocation::new(
&self.client,
self.token.as_ref(),
inline_message_id,
)
}
pub fn stop_message_location<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> StopMessageLocation<'a> {
StopMessageLocation::new(
&self.client,
self.token.as_ref(),
chat_id,
message_id,
)
}
pub fn stop_poll<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
message_id: message::Id,
) -> StopPoll<'a> {
StopPoll::new(&self.client, self.token.as_ref(), chat_id, message_id)
}
pub fn unban_chat_member<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
user_id: user::Id,
) -> UnbanChatMember<'a> {
UnbanChatMember::new(
&self.client,
self.token.as_ref(),
chat_id,
user_id,
)
}
pub fn unpin_chat_message<'a>(
&'a self,
chat_id: impl ImplicitChatId<'a>,
) -> UnpinChatMessage<'a> {
UnpinChatMessage::new(&self.client, self.token.as_ref(), chat_id)
}
pub fn upload_sticker_file<'a>(
&'a self,
user_id: user::Id,
png_sticker: &'a [u8],
) -> UploadStickerFile<'a> {
UploadStickerFile::new(
&self.client,
self.token.as_ref(),
user_id,
png_sticker,
)
}
}
#[macro_export]
macro_rules! from_env {
($var:literal) => {{
let token = env!($var).to_string();
$crate::Bot::new(token)
}};
($var:literal,) => {
$crate::from_env!($var)
};
($var:literal, $proxy:expr) => {{
let token = env!($var).to_string();
$crate::Bot::with_proxy(token, $proxy)
}};
($var:literal, $proxy:expr,) => {
$crate::from_env!($var, $proxy)
};
() => {
compile_error!(
"the macro must be invoked as `from_env!(\"<VAR_NAME>\")` or \
`from_env!(\"<VAR_NAME>\", proxy)`"
)
};
($($x:tt)+) => {
$crate::from_env!()
};
}
impl Sealed for Bot {}
fn extract_token(env_var: &'static str) -> String {
std::env::var(env_var).unwrap_or_else(|_| {
panic!("\n[tbot] Bot's token in {} was not specified\n", env_var)
})
}
#[cfg(test)]
mod tests {
use crate::proxy::{Intercept, Proxy};
#[test]
fn macro_compiles() {
const PROXY: &str = "http://127.0.0.1:8080";
let _ = from_env!("BOT_TOKEN");
let _ = from_env!("BOT_TOKEN",);
let proxy = Proxy::new(Intercept::All, PROXY.parse().unwrap());
let _ = from_env!("BOT_TOKEN", proxy);
let proxy = Proxy::new(Intercept::All, PROXY.parse().unwrap());
let _ = from_env!("BOT_TOKEN", proxy,);
}
}