use super::support::{callback_query_id, reply_chat_id, serialize_request_value};
use super::*;
fn text_send_request(
chat_id: impl Into<ChatId>,
text: impl Into<String>,
) -> Result<SendMessageRequest> {
SendMessageRequest::new(chat_id, text)
}
fn reply_text_request(update: &Update, text: impl Into<String>) -> Result<SendMessageRequest> {
let chat_id = reply_chat_id(update)?;
text_send_request(chat_id, text)
}
fn photo_send_request(chat_id: impl Into<ChatId>, photo: impl Into<String>) -> SendPhotoRequest {
SendPhotoRequest::new(chat_id, photo)
}
fn reply_photo_request(update: &Update, photo: impl Into<String>) -> Result<SendPhotoRequest> {
let chat_id = reply_chat_id(update)?;
Ok(photo_send_request(chat_id, photo))
}
fn document_send_request(
chat_id: impl Into<ChatId>,
document: impl Into<String>,
) -> SendDocumentRequest {
SendDocumentRequest::new(chat_id, document)
}
fn reply_document_request(
update: &Update,
document: impl Into<String>,
) -> Result<SendDocumentRequest> {
let chat_id = reply_chat_id(update)?;
Ok(document_send_request(chat_id, document))
}
fn video_send_request(chat_id: impl Into<ChatId>, video: impl Into<String>) -> SendVideoRequest {
SendVideoRequest::new(chat_id, video)
}
fn reply_video_request(update: &Update, video: impl Into<String>) -> Result<SendVideoRequest> {
let chat_id = reply_chat_id(update)?;
Ok(video_send_request(chat_id, video))
}
fn audio_send_request(chat_id: impl Into<ChatId>, audio: impl Into<String>) -> SendAudioRequest {
SendAudioRequest::new(chat_id, audio)
}
fn reply_audio_request(update: &Update, audio: impl Into<String>) -> Result<SendAudioRequest> {
let chat_id = reply_chat_id(update)?;
Ok(audio_send_request(chat_id, audio))
}
fn animation_send_request(
chat_id: impl Into<ChatId>,
animation: impl Into<String>,
) -> SendAnimationRequest {
SendAnimationRequest::new(chat_id, animation)
}
fn reply_animation_request(
update: &Update,
animation: impl Into<String>,
) -> Result<SendAnimationRequest> {
let chat_id = reply_chat_id(update)?;
Ok(animation_send_request(chat_id, animation))
}
fn voice_send_request(chat_id: impl Into<ChatId>, voice: impl Into<String>) -> SendVoiceRequest {
SendVoiceRequest::new(chat_id, voice)
}
fn reply_voice_request(update: &Update, voice: impl Into<String>) -> Result<SendVoiceRequest> {
let chat_id = reply_chat_id(update)?;
Ok(voice_send_request(chat_id, voice))
}
fn sticker_send_request(
chat_id: impl Into<ChatId>,
sticker: impl Into<String>,
) -> SendStickerRequest {
SendStickerRequest::new(chat_id, sticker)
}
fn reply_sticker_request(
update: &Update,
sticker: impl Into<String>,
) -> Result<SendStickerRequest> {
let chat_id = reply_chat_id(update)?;
Ok(sticker_send_request(chat_id, sticker))
}
fn media_group_send_request<I, M>(
chat_id: impl Into<ChatId>,
media: I,
) -> Result<SendMediaGroupRequest>
where
I: IntoIterator<Item = M>,
M: Into<InputMedia>,
{
SendMediaGroupRequest::new(chat_id, media.into_iter().map(Into::into).collect())
}
fn reply_media_group_request<I, M>(update: &Update, media: I) -> Result<SendMediaGroupRequest>
where
I: IntoIterator<Item = M>,
M: Into<InputMedia>,
{
let chat_id = reply_chat_id(update)?;
media_group_send_request(chat_id, media)
}
fn callback_answer_request(
callback_query_id: impl Into<String>,
text: Option<String>,
) -> AnswerCallbackQueryRequest {
AnswerCallbackQueryRequest {
callback_query_id: callback_query_id.into(),
text,
show_alert: None,
url: None,
cache_time: None,
}
}
macro_rules! impl_common_callback_answer_builder_methods {
($builder:ident, $request_ty:ty) => {
impl $builder {
pub fn text(mut self, text: impl Into<String>) -> Self {
self.request.text = Some(text.into());
self
}
pub fn text_optional(mut self, text: Option<String>) -> Self {
self.request.text = text;
self
}
pub fn show_alert(mut self, enabled: bool) -> Self {
self.request.show_alert = enabled.then_some(true);
self
}
pub fn url(mut self, url: impl Into<String>) -> Self {
self.request.url = Some(url.into());
self
}
pub fn cache_time(mut self, cache_time: u32) -> Self {
self.request.cache_time = Some(cache_time);
self
}
pub fn into_request(self) -> $request_ty {
self.request
}
}
};
}
macro_rules! impl_common_media_builder_methods {
($builder:ident, $request_ty:ty) => {
impl $builder {
pub fn caption(mut self, caption: impl Into<String>) -> Self {
self.request.caption = Some(caption.into());
self
}
pub fn parse_mode(mut self, parse_mode: ParseMode) -> Self {
self.request.parse_mode = Some(parse_mode);
self
}
pub fn reply_markup(mut self, reply_markup: impl Into<ReplyMarkup>) -> Self {
self.request.reply_markup = Some(reply_markup.into());
self
}
pub fn reply_parameters(mut self, reply_parameters: ReplyParameters) -> Self {
self.request.reply_parameters = Some(reply_parameters);
self
}
pub fn reply_to_message(mut self, message_id: MessageId) -> Self {
self.request.reply_parameters = Some(ReplyParameters::new(message_id));
self
}
pub fn message_thread_id(mut self, message_thread_id: i64) -> Self {
self.request.message_thread_id = Some(message_thread_id);
self
}
pub fn disable_notification(mut self, enabled: bool) -> Self {
self.request.disable_notification = enabled.then_some(true);
self
}
pub fn protect_content(mut self, enabled: bool) -> Self {
self.request.protect_content = enabled.then_some(true);
self
}
pub fn into_request(self) -> $request_ty {
self.request
}
}
};
}
macro_rules! impl_common_media_group_builder_methods {
($builder:ident, $request_ty:ty) => {
impl $builder {
pub fn add_media(mut self, media: impl Into<InputMedia>) -> Self {
self.request.media.push(media.into());
self
}
pub fn reply_parameters(mut self, reply_parameters: ReplyParameters) -> Self {
self.request.reply_parameters = Some(reply_parameters);
self
}
pub fn reply_to_message(mut self, message_id: MessageId) -> Self {
self.request.reply_parameters = Some(ReplyParameters::new(message_id));
self
}
pub fn message_thread_id(mut self, message_thread_id: i64) -> Self {
self.request.message_thread_id = Some(message_thread_id);
self
}
pub fn disable_notification(mut self, enabled: bool) -> Self {
self.request.disable_notification = enabled.then_some(true);
self
}
pub fn protect_content(mut self, enabled: bool) -> Self {
self.request.protect_content = enabled.then_some(true);
self
}
pub fn into_request(self) -> $request_ty {
self.request
}
}
};
}
macro_rules! impl_common_sticker_builder_methods {
($builder:ident, $request_ty:ty) => {
impl $builder {
pub fn emoji(mut self, emoji: impl Into<String>) -> Self {
self.request.emoji = Some(emoji.into());
self
}
pub fn reply_markup(mut self, reply_markup: impl Into<ReplyMarkup>) -> Result<Self> {
self.request.reply_markup = Some(serialize_request_value(reply_markup.into())?);
Ok(self)
}
pub fn reply_parameters(mut self, reply_parameters: ReplyParameters) -> Result<Self> {
self.request.reply_parameters = Some(serialize_request_value(reply_parameters)?);
Ok(self)
}
pub fn reply_to_message(mut self, message_id: MessageId) -> Result<Self> {
self.request.reply_parameters =
Some(serialize_request_value(ReplyParameters::new(message_id))?);
Ok(self)
}
pub fn message_thread_id(mut self, message_thread_id: i64) -> Self {
self.request.message_thread_id = Some(message_thread_id);
self
}
pub fn disable_notification(mut self, enabled: bool) -> Self {
self.request.disable_notification = enabled.then_some(true);
self
}
pub fn protect_content(mut self, enabled: bool) -> Self {
self.request.protect_content = enabled.then_some(true);
self
}
pub fn into_request(self) -> $request_ty {
self.request
}
}
};
}
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await` or `.into_request()` to finish the callback answer"]
pub struct CallbackAnswerBuilder {
client: Client,
request: AnswerCallbackQueryRequest,
}
#[cfg(feature = "_async")]
impl CallbackAnswerBuilder {
fn new(client: Client, request: AnswerCallbackQueryRequest) -> Self {
Self { client, request }
}
pub async fn send(self) -> Result<bool> {
self.client
.updates()
.answer_callback_query(&self.request)
.await
}
}
#[cfg(feature = "_async")]
impl_common_callback_answer_builder_methods!(CallbackAnswerBuilder, AnswerCallbackQueryRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await` or `.into_request()` to finish the message send"]
pub struct TextSendBuilder {
client: Client,
request: SendMessageRequest,
}
#[cfg(feature = "_async")]
impl TextSendBuilder {
fn new(client: Client, request: SendMessageRequest) -> Self {
Self { client, request }
}
pub fn parse_mode(mut self, parse_mode: ParseMode) -> Self {
self.request = self.request.parse_mode(parse_mode);
self
}
pub fn reply_markup(mut self, reply_markup: impl Into<ReplyMarkup>) -> Self {
self.request = self.request.reply_markup(reply_markup);
self
}
pub fn reply_parameters(mut self, reply_parameters: ReplyParameters) -> Self {
self.request = self.request.reply_parameters(reply_parameters);
self
}
pub fn reply_to_message(mut self, message_id: MessageId) -> Self {
self.request = self.request.reply_to_message(message_id);
self
}
pub fn message_thread_id(mut self, message_thread_id: i64) -> Self {
self.request.message_thread_id = Some(message_thread_id);
self
}
pub fn disable_notification(mut self, enabled: bool) -> Self {
self.request.disable_notification = enabled.then_some(true);
self
}
pub fn protect_content(mut self, enabled: bool) -> Self {
self.request.protect_content = enabled.then_some(true);
self
}
pub fn link_preview_options(mut self, link_preview_options: LinkPreviewOptions) -> Self {
self.request = self.request.link_preview_options(link_preview_options);
self
}
pub fn disable_link_preview(mut self) -> Self {
self.request = self.request.disable_link_preview();
self
}
pub fn into_request(self) -> SendMessageRequest {
self.request
}
pub async fn send(self) -> Result<Message> {
self.client.messages().send_message(&self.request).await
}
}
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct PhotoSendBuilder {
client: Client,
request: SendPhotoRequest,
}
#[cfg(feature = "_async")]
impl PhotoSendBuilder {
fn new(client: Client, request: SendPhotoRequest) -> Self {
Self { client, request }
}
pub fn has_spoiler(mut self, enabled: bool) -> Self {
self.request.has_spoiler = enabled.then_some(true);
self
}
pub async fn send(self) -> Result<Message> {
self.client.messages().send_photo(&self.request).await
}
pub async fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_photo_upload(&self.request, file)
.await
}
}
#[cfg(feature = "_async")]
impl_common_media_builder_methods!(PhotoSendBuilder, SendPhotoRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct DocumentSendBuilder {
client: Client,
request: SendDocumentRequest,
}
#[cfg(feature = "_async")]
impl DocumentSendBuilder {
fn new(client: Client, request: SendDocumentRequest) -> Self {
Self { client, request }
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub fn disable_content_type_detection(mut self, enabled: bool) -> Self {
self.request.disable_content_type_detection = enabled.then_some(true);
self
}
pub async fn send(self) -> Result<Message> {
self.client.messages().send_document(&self.request).await
}
pub async fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_document_upload(&self.request, file)
.await
}
}
#[cfg(feature = "_async")]
impl_common_media_builder_methods!(DocumentSendBuilder, SendDocumentRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct VideoSendBuilder {
client: Client,
request: SendVideoRequest,
}
#[cfg(feature = "_async")]
impl VideoSendBuilder {
fn new(client: Client, request: SendVideoRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub fn width(mut self, width: u32) -> Self {
self.request.width = Some(width);
self
}
pub fn height(mut self, height: u32) -> Self {
self.request.height = Some(height);
self
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub fn supports_streaming(mut self, enabled: bool) -> Self {
self.request.supports_streaming = enabled.then_some(true);
self
}
pub fn has_spoiler(mut self, enabled: bool) -> Self {
self.request.has_spoiler = enabled.then_some(true);
self
}
pub async fn send(self) -> Result<Message> {
self.client.messages().send_video(&self.request).await
}
pub async fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_video_upload(&self.request, file)
.await
}
}
#[cfg(feature = "_async")]
impl_common_media_builder_methods!(VideoSendBuilder, SendVideoRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct AudioSendBuilder {
client: Client,
request: SendAudioRequest,
}
#[cfg(feature = "_async")]
impl AudioSendBuilder {
fn new(client: Client, request: SendAudioRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub fn performer(mut self, performer: impl Into<String>) -> Self {
self.request.performer = Some(performer.into());
self
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.request.title = Some(title.into());
self
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub async fn send(self) -> Result<Message> {
self.client.messages().send_audio(&self.request).await
}
pub async fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_audio_upload(&self.request, file)
.await
}
}
#[cfg(feature = "_async")]
impl_common_media_builder_methods!(AudioSendBuilder, SendAudioRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct AnimationSendBuilder {
client: Client,
request: SendAnimationRequest,
}
#[cfg(feature = "_async")]
impl AnimationSendBuilder {
fn new(client: Client, request: SendAnimationRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub fn width(mut self, width: u32) -> Self {
self.request.width = Some(width);
self
}
pub fn height(mut self, height: u32) -> Self {
self.request.height = Some(height);
self
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub fn has_spoiler(mut self, enabled: bool) -> Self {
self.request.has_spoiler = enabled.then_some(true);
self
}
pub async fn send(self) -> Result<Message> {
self.client.messages().send_animation(&self.request).await
}
pub async fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_animation_upload(&self.request, file)
.await
}
}
#[cfg(feature = "_async")]
impl_common_media_builder_methods!(AnimationSendBuilder, SendAnimationRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct VoiceSendBuilder {
client: Client,
request: SendVoiceRequest,
}
#[cfg(feature = "_async")]
impl VoiceSendBuilder {
fn new(client: Client, request: SendVoiceRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub async fn send(self) -> Result<Message> {
self.client.messages().send_voice(&self.request).await
}
pub async fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_voice_upload(&self.request, file)
.await
}
}
#[cfg(feature = "_async")]
impl_common_media_builder_methods!(VoiceSendBuilder, SendVoiceRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct StickerSendBuilder {
client: Client,
request: SendStickerRequest,
}
#[cfg(feature = "_async")]
impl StickerSendBuilder {
fn new(client: Client, request: SendStickerRequest) -> Self {
Self { client, request }
}
pub async fn send(self) -> Result<Message> {
self.client.stickers().send_sticker(&self.request).await
}
pub async fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.stickers()
.send_sticker_upload(&self.request, file)
.await
}
}
#[cfg(feature = "_async")]
impl_common_sticker_builder_methods!(StickerSendBuilder, SendStickerRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
#[must_use = "call `.send().await` or `.into_request()` to finish the send"]
pub struct MediaGroupSendBuilder {
client: Client,
request: SendMediaGroupRequest,
}
#[cfg(feature = "_async")]
impl MediaGroupSendBuilder {
fn new(client: Client, request: SendMediaGroupRequest) -> Self {
Self { client, request }
}
pub async fn send(self) -> Result<Vec<Message>> {
self.client.messages().send_media_group(&self.request).await
}
}
#[cfg(feature = "_async")]
impl_common_media_group_builder_methods!(MediaGroupSendBuilder, SendMediaGroupRequest);
#[cfg(feature = "_async")]
#[derive(Clone)]
pub struct AppApi {
client: Client,
}
#[cfg(feature = "_async")]
impl AppApi {
pub(crate) fn new(client: Client) -> Self {
Self { client }
}
pub fn moderation(&self) -> ModerationApi {
ModerationApi::new(self.client.clone())
}
pub fn membership(&self) -> MembershipApi {
MembershipApi::new(self.client.clone())
}
pub fn web_app(&self) -> WebAppApi {
WebAppApi::new(self.client.clone())
}
pub fn callback_answer(&self, callback_query_id: impl Into<String>) -> CallbackAnswerBuilder {
let request = callback_answer_request(callback_query_id, None);
CallbackAnswerBuilder::new(self.client.clone(), request)
}
pub fn callback_answer_from_update(&self, update: &Update) -> Result<CallbackAnswerBuilder> {
let Some(callback_query_id) = callback_query_id(update) else {
return Err(super::support::invalid_request(
"update does not contain callback query for answerCallbackQuery",
));
};
Ok(self.callback_answer(callback_query_id))
}
pub fn text(
&self,
chat_id: impl Into<ChatId>,
text: impl Into<String>,
) -> Result<TextSendBuilder> {
let request = text_send_request(chat_id, text)?;
Ok(TextSendBuilder::new(self.client.clone(), request))
}
pub fn reply(&self, update: &Update, text: impl Into<String>) -> Result<TextSendBuilder> {
let request = reply_text_request(update, text)?;
Ok(TextSendBuilder::new(self.client.clone(), request))
}
pub fn photo(&self, chat_id: impl Into<ChatId>, photo: impl Into<String>) -> PhotoSendBuilder {
let request = photo_send_request(chat_id, photo);
PhotoSendBuilder::new(self.client.clone(), request)
}
pub fn reply_photo(
&self,
update: &Update,
photo: impl Into<String>,
) -> Result<PhotoSendBuilder> {
let request = reply_photo_request(update, photo)?;
Ok(PhotoSendBuilder::new(self.client.clone(), request))
}
pub fn document(
&self,
chat_id: impl Into<ChatId>,
document: impl Into<String>,
) -> DocumentSendBuilder {
let request = document_send_request(chat_id, document);
DocumentSendBuilder::new(self.client.clone(), request)
}
pub fn reply_document(
&self,
update: &Update,
document: impl Into<String>,
) -> Result<DocumentSendBuilder> {
let request = reply_document_request(update, document)?;
Ok(DocumentSendBuilder::new(self.client.clone(), request))
}
pub fn video(&self, chat_id: impl Into<ChatId>, video: impl Into<String>) -> VideoSendBuilder {
let request = video_send_request(chat_id, video);
VideoSendBuilder::new(self.client.clone(), request)
}
pub fn reply_video(
&self,
update: &Update,
video: impl Into<String>,
) -> Result<VideoSendBuilder> {
let request = reply_video_request(update, video)?;
Ok(VideoSendBuilder::new(self.client.clone(), request))
}
pub fn audio(&self, chat_id: impl Into<ChatId>, audio: impl Into<String>) -> AudioSendBuilder {
let request = audio_send_request(chat_id, audio);
AudioSendBuilder::new(self.client.clone(), request)
}
pub fn reply_audio(
&self,
update: &Update,
audio: impl Into<String>,
) -> Result<AudioSendBuilder> {
let request = reply_audio_request(update, audio)?;
Ok(AudioSendBuilder::new(self.client.clone(), request))
}
pub fn animation(
&self,
chat_id: impl Into<ChatId>,
animation: impl Into<String>,
) -> AnimationSendBuilder {
let request = animation_send_request(chat_id, animation);
AnimationSendBuilder::new(self.client.clone(), request)
}
pub fn reply_animation(
&self,
update: &Update,
animation: impl Into<String>,
) -> Result<AnimationSendBuilder> {
let request = reply_animation_request(update, animation)?;
Ok(AnimationSendBuilder::new(self.client.clone(), request))
}
pub fn voice(&self, chat_id: impl Into<ChatId>, voice: impl Into<String>) -> VoiceSendBuilder {
let request = voice_send_request(chat_id, voice);
VoiceSendBuilder::new(self.client.clone(), request)
}
pub fn reply_voice(
&self,
update: &Update,
voice: impl Into<String>,
) -> Result<VoiceSendBuilder> {
let request = reply_voice_request(update, voice)?;
Ok(VoiceSendBuilder::new(self.client.clone(), request))
}
pub fn sticker(
&self,
chat_id: impl Into<ChatId>,
sticker: impl Into<String>,
) -> StickerSendBuilder {
let request = sticker_send_request(chat_id, sticker);
StickerSendBuilder::new(self.client.clone(), request)
}
pub fn reply_sticker(
&self,
update: &Update,
sticker: impl Into<String>,
) -> Result<StickerSendBuilder> {
let request = reply_sticker_request(update, sticker)?;
Ok(StickerSendBuilder::new(self.client.clone(), request))
}
pub fn media_group<I, M>(
&self,
chat_id: impl Into<ChatId>,
media: I,
) -> Result<MediaGroupSendBuilder>
where
I: IntoIterator<Item = M>,
M: Into<InputMedia>,
{
let request = media_group_send_request(chat_id, media)?;
Ok(MediaGroupSendBuilder::new(self.client.clone(), request))
}
pub fn reply_media_group<I, M>(
&self,
update: &Update,
media: I,
) -> Result<MediaGroupSendBuilder>
where
I: IntoIterator<Item = M>,
M: Into<InputMedia>,
{
let request = reply_media_group_request(update, media)?;
Ok(MediaGroupSendBuilder::new(self.client.clone(), request))
}
pub async fn send_text(
&self,
chat_id: impl Into<ChatId>,
text: impl Into<String>,
) -> Result<Message> {
self.text(chat_id, text)?.send().await
}
pub async fn reply_text(&self, update: &Update, text: impl Into<String>) -> Result<Message> {
self.reply(update, text)?.send().await
}
pub async fn answer_callback(
&self,
callback_query_id: impl Into<String>,
text: Option<String>,
) -> Result<bool> {
self.callback_answer(callback_query_id)
.text_optional(text)
.send()
.await
}
pub async fn answer_callback_from_update(
&self,
update: &Update,
text: Option<String>,
) -> Result<bool> {
self.callback_answer_from_update(update)?
.text_optional(text)
.send()
.await
}
}
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()` or `.into_request()` to finish the callback answer"]
pub struct BlockingCallbackAnswerBuilder {
client: BlockingClient,
request: AnswerCallbackQueryRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingCallbackAnswerBuilder {
fn new(client: BlockingClient, request: AnswerCallbackQueryRequest) -> Self {
Self { client, request }
}
pub fn send(self) -> Result<bool> {
self.client.updates().answer_callback_query(&self.request)
}
}
#[cfg(feature = "_blocking")]
impl_common_callback_answer_builder_methods!(
BlockingCallbackAnswerBuilder,
AnswerCallbackQueryRequest
);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()` or `.into_request()` to finish the message send"]
pub struct BlockingTextSendBuilder {
client: BlockingClient,
request: SendMessageRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingTextSendBuilder {
fn new(client: BlockingClient, request: SendMessageRequest) -> Self {
Self { client, request }
}
pub fn parse_mode(mut self, parse_mode: ParseMode) -> Self {
self.request = self.request.parse_mode(parse_mode);
self
}
pub fn reply_markup(mut self, reply_markup: impl Into<ReplyMarkup>) -> Self {
self.request = self.request.reply_markup(reply_markup);
self
}
pub fn reply_parameters(mut self, reply_parameters: ReplyParameters) -> Self {
self.request = self.request.reply_parameters(reply_parameters);
self
}
pub fn reply_to_message(mut self, message_id: MessageId) -> Self {
self.request = self.request.reply_to_message(message_id);
self
}
pub fn message_thread_id(mut self, message_thread_id: i64) -> Self {
self.request.message_thread_id = Some(message_thread_id);
self
}
pub fn disable_notification(mut self, enabled: bool) -> Self {
self.request.disable_notification = enabled.then_some(true);
self
}
pub fn protect_content(mut self, enabled: bool) -> Self {
self.request.protect_content = enabled.then_some(true);
self
}
pub fn link_preview_options(mut self, link_preview_options: LinkPreviewOptions) -> Self {
self.request = self.request.link_preview_options(link_preview_options);
self
}
pub fn disable_link_preview(mut self) -> Self {
self.request = self.request.disable_link_preview();
self
}
pub fn into_request(self) -> SendMessageRequest {
self.request
}
pub fn send(self) -> Result<Message> {
self.client.messages().send_message(&self.request)
}
}
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct BlockingPhotoSendBuilder {
client: BlockingClient,
request: SendPhotoRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingPhotoSendBuilder {
fn new(client: BlockingClient, request: SendPhotoRequest) -> Self {
Self { client, request }
}
pub fn has_spoiler(mut self, enabled: bool) -> Self {
self.request.has_spoiler = enabled.then_some(true);
self
}
pub fn send(self) -> Result<Message> {
self.client.messages().send_photo(&self.request)
}
pub fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_photo_upload(&self.request, file)
}
}
#[cfg(feature = "_blocking")]
impl_common_media_builder_methods!(BlockingPhotoSendBuilder, SendPhotoRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct BlockingDocumentSendBuilder {
client: BlockingClient,
request: SendDocumentRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingDocumentSendBuilder {
fn new(client: BlockingClient, request: SendDocumentRequest) -> Self {
Self { client, request }
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub fn disable_content_type_detection(mut self, enabled: bool) -> Self {
self.request.disable_content_type_detection = enabled.then_some(true);
self
}
pub fn send(self) -> Result<Message> {
self.client.messages().send_document(&self.request)
}
pub fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_document_upload(&self.request, file)
}
}
#[cfg(feature = "_blocking")]
impl_common_media_builder_methods!(BlockingDocumentSendBuilder, SendDocumentRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct BlockingVideoSendBuilder {
client: BlockingClient,
request: SendVideoRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingVideoSendBuilder {
fn new(client: BlockingClient, request: SendVideoRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub fn width(mut self, width: u32) -> Self {
self.request.width = Some(width);
self
}
pub fn height(mut self, height: u32) -> Self {
self.request.height = Some(height);
self
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub fn supports_streaming(mut self, enabled: bool) -> Self {
self.request.supports_streaming = enabled.then_some(true);
self
}
pub fn has_spoiler(mut self, enabled: bool) -> Self {
self.request.has_spoiler = enabled.then_some(true);
self
}
pub fn send(self) -> Result<Message> {
self.client.messages().send_video(&self.request)
}
pub fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_video_upload(&self.request, file)
}
}
#[cfg(feature = "_blocking")]
impl_common_media_builder_methods!(BlockingVideoSendBuilder, SendVideoRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct BlockingAudioSendBuilder {
client: BlockingClient,
request: SendAudioRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingAudioSendBuilder {
fn new(client: BlockingClient, request: SendAudioRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub fn performer(mut self, performer: impl Into<String>) -> Self {
self.request.performer = Some(performer.into());
self
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.request.title = Some(title.into());
self
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub fn send(self) -> Result<Message> {
self.client.messages().send_audio(&self.request)
}
pub fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_audio_upload(&self.request, file)
}
}
#[cfg(feature = "_blocking")]
impl_common_media_builder_methods!(BlockingAudioSendBuilder, SendAudioRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct BlockingAnimationSendBuilder {
client: BlockingClient,
request: SendAnimationRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingAnimationSendBuilder {
fn new(client: BlockingClient, request: SendAnimationRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub fn width(mut self, width: u32) -> Self {
self.request.width = Some(width);
self
}
pub fn height(mut self, height: u32) -> Self {
self.request.height = Some(height);
self
}
pub fn thumbnail(mut self, thumbnail: impl Into<String>) -> Self {
self.request.thumbnail = Some(thumbnail.into());
self
}
pub fn has_spoiler(mut self, enabled: bool) -> Self {
self.request.has_spoiler = enabled.then_some(true);
self
}
pub fn send(self) -> Result<Message> {
self.client.messages().send_animation(&self.request)
}
pub fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_animation_upload(&self.request, file)
}
}
#[cfg(feature = "_blocking")]
impl_common_media_builder_methods!(BlockingAnimationSendBuilder, SendAnimationRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct BlockingVoiceSendBuilder {
client: BlockingClient,
request: SendVoiceRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingVoiceSendBuilder {
fn new(client: BlockingClient, request: SendVoiceRequest) -> Self {
Self { client, request }
}
pub fn duration(mut self, duration: u32) -> Self {
self.request.duration = Some(duration);
self
}
pub fn send(self) -> Result<Message> {
self.client.messages().send_voice(&self.request)
}
pub fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.messages()
.send_voice_upload(&self.request, file)
}
}
#[cfg(feature = "_blocking")]
impl_common_media_builder_methods!(BlockingVoiceSendBuilder, SendVoiceRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()`, `.send_upload(...)`, or `.into_request()` to finish the send"]
pub struct BlockingStickerSendBuilder {
client: BlockingClient,
request: SendStickerRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingStickerSendBuilder {
fn new(client: BlockingClient, request: SendStickerRequest) -> Self {
Self { client, request }
}
pub fn send(self) -> Result<Message> {
self.client.stickers().send_sticker(&self.request)
}
pub fn send_upload(self, file: &UploadFile) -> Result<Message> {
self.client
.stickers()
.send_sticker_upload(&self.request, file)
}
}
#[cfg(feature = "_blocking")]
impl_common_sticker_builder_methods!(BlockingStickerSendBuilder, SendStickerRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
#[must_use = "call `.send()` or `.into_request()` to finish the send"]
pub struct BlockingMediaGroupSendBuilder {
client: BlockingClient,
request: SendMediaGroupRequest,
}
#[cfg(feature = "_blocking")]
impl BlockingMediaGroupSendBuilder {
fn new(client: BlockingClient, request: SendMediaGroupRequest) -> Self {
Self { client, request }
}
pub fn send(self) -> Result<Vec<Message>> {
self.client.messages().send_media_group(&self.request)
}
}
#[cfg(feature = "_blocking")]
impl_common_media_group_builder_methods!(BlockingMediaGroupSendBuilder, SendMediaGroupRequest);
#[cfg(feature = "_blocking")]
#[derive(Clone)]
pub struct BlockingAppApi {
client: BlockingClient,
}
#[cfg(feature = "_blocking")]
impl BlockingAppApi {
pub(crate) fn new(client: BlockingClient) -> Self {
Self { client }
}
pub fn moderation(&self) -> BlockingModerationApi {
BlockingModerationApi::new(self.client.clone())
}
pub fn membership(&self) -> BlockingMembershipApi {
BlockingMembershipApi::new(self.client.clone())
}
pub fn web_app(&self) -> BlockingWebAppApi {
BlockingWebAppApi::new(self.client.clone())
}
pub fn callback_answer(
&self,
callback_query_id: impl Into<String>,
) -> BlockingCallbackAnswerBuilder {
let request = callback_answer_request(callback_query_id, None);
BlockingCallbackAnswerBuilder::new(self.client.clone(), request)
}
pub fn callback_answer_from_update(
&self,
update: &Update,
) -> Result<BlockingCallbackAnswerBuilder> {
let Some(callback_query_id) = callback_query_id(update) else {
return Err(super::support::invalid_request(
"update does not contain callback query for answerCallbackQuery",
));
};
Ok(self.callback_answer(callback_query_id))
}
pub fn text(
&self,
chat_id: impl Into<ChatId>,
text: impl Into<String>,
) -> Result<BlockingTextSendBuilder> {
let request = text_send_request(chat_id, text)?;
Ok(BlockingTextSendBuilder::new(self.client.clone(), request))
}
pub fn reply(
&self,
update: &Update,
text: impl Into<String>,
) -> Result<BlockingTextSendBuilder> {
let request = reply_text_request(update, text)?;
Ok(BlockingTextSendBuilder::new(self.client.clone(), request))
}
pub fn photo(
&self,
chat_id: impl Into<ChatId>,
photo: impl Into<String>,
) -> BlockingPhotoSendBuilder {
let request = photo_send_request(chat_id, photo);
BlockingPhotoSendBuilder::new(self.client.clone(), request)
}
pub fn reply_photo(
&self,
update: &Update,
photo: impl Into<String>,
) -> Result<BlockingPhotoSendBuilder> {
let request = reply_photo_request(update, photo)?;
Ok(BlockingPhotoSendBuilder::new(self.client.clone(), request))
}
pub fn document(
&self,
chat_id: impl Into<ChatId>,
document: impl Into<String>,
) -> BlockingDocumentSendBuilder {
let request = document_send_request(chat_id, document);
BlockingDocumentSendBuilder::new(self.client.clone(), request)
}
pub fn reply_document(
&self,
update: &Update,
document: impl Into<String>,
) -> Result<BlockingDocumentSendBuilder> {
let request = reply_document_request(update, document)?;
Ok(BlockingDocumentSendBuilder::new(
self.client.clone(),
request,
))
}
pub fn video(
&self,
chat_id: impl Into<ChatId>,
video: impl Into<String>,
) -> BlockingVideoSendBuilder {
let request = video_send_request(chat_id, video);
BlockingVideoSendBuilder::new(self.client.clone(), request)
}
pub fn reply_video(
&self,
update: &Update,
video: impl Into<String>,
) -> Result<BlockingVideoSendBuilder> {
let request = reply_video_request(update, video)?;
Ok(BlockingVideoSendBuilder::new(self.client.clone(), request))
}
pub fn audio(
&self,
chat_id: impl Into<ChatId>,
audio: impl Into<String>,
) -> BlockingAudioSendBuilder {
let request = audio_send_request(chat_id, audio);
BlockingAudioSendBuilder::new(self.client.clone(), request)
}
pub fn reply_audio(
&self,
update: &Update,
audio: impl Into<String>,
) -> Result<BlockingAudioSendBuilder> {
let request = reply_audio_request(update, audio)?;
Ok(BlockingAudioSendBuilder::new(self.client.clone(), request))
}
pub fn animation(
&self,
chat_id: impl Into<ChatId>,
animation: impl Into<String>,
) -> BlockingAnimationSendBuilder {
let request = animation_send_request(chat_id, animation);
BlockingAnimationSendBuilder::new(self.client.clone(), request)
}
pub fn reply_animation(
&self,
update: &Update,
animation: impl Into<String>,
) -> Result<BlockingAnimationSendBuilder> {
let request = reply_animation_request(update, animation)?;
Ok(BlockingAnimationSendBuilder::new(
self.client.clone(),
request,
))
}
pub fn voice(
&self,
chat_id: impl Into<ChatId>,
voice: impl Into<String>,
) -> BlockingVoiceSendBuilder {
let request = voice_send_request(chat_id, voice);
BlockingVoiceSendBuilder::new(self.client.clone(), request)
}
pub fn reply_voice(
&self,
update: &Update,
voice: impl Into<String>,
) -> Result<BlockingVoiceSendBuilder> {
let request = reply_voice_request(update, voice)?;
Ok(BlockingVoiceSendBuilder::new(self.client.clone(), request))
}
pub fn sticker(
&self,
chat_id: impl Into<ChatId>,
sticker: impl Into<String>,
) -> BlockingStickerSendBuilder {
let request = sticker_send_request(chat_id, sticker);
BlockingStickerSendBuilder::new(self.client.clone(), request)
}
pub fn reply_sticker(
&self,
update: &Update,
sticker: impl Into<String>,
) -> Result<BlockingStickerSendBuilder> {
let request = reply_sticker_request(update, sticker)?;
Ok(BlockingStickerSendBuilder::new(
self.client.clone(),
request,
))
}
pub fn media_group<I, M>(
&self,
chat_id: impl Into<ChatId>,
media: I,
) -> Result<BlockingMediaGroupSendBuilder>
where
I: IntoIterator<Item = M>,
M: Into<InputMedia>,
{
let request = media_group_send_request(chat_id, media)?;
Ok(BlockingMediaGroupSendBuilder::new(
self.client.clone(),
request,
))
}
pub fn reply_media_group<I, M>(
&self,
update: &Update,
media: I,
) -> Result<BlockingMediaGroupSendBuilder>
where
I: IntoIterator<Item = M>,
M: Into<InputMedia>,
{
let request = reply_media_group_request(update, media)?;
Ok(BlockingMediaGroupSendBuilder::new(
self.client.clone(),
request,
))
}
pub fn send_text(
&self,
chat_id: impl Into<ChatId>,
text: impl Into<String>,
) -> Result<Message> {
self.text(chat_id, text)?.send()
}
pub fn reply_text(&self, update: &Update, text: impl Into<String>) -> Result<Message> {
self.reply(update, text)?.send()
}
pub fn answer_callback(
&self,
callback_query_id: impl Into<String>,
text: Option<String>,
) -> Result<bool> {
self.callback_answer(callback_query_id)
.text_optional(text)
.send()
}
pub fn answer_callback_from_update(
&self,
update: &Update,
text: Option<String>,
) -> Result<bool> {
self.callback_answer_from_update(update)?
.text_optional(text)
.send()
}
}