use crate::client::BotClient;
use crate::error::Result;
use rustigram_types::message::{Message, ReplyParameters};
use rustigram_types::payments::{LabeledPrice, ShippingOption, StarAmount, StarTransactions};
use rustigram_types::suggested_post::SuggestedPostParameters;
use rustigram_types::user::ChatId;
use serde::Serialize;
use std::future::{Future, IntoFuture};
use std::pin::Pin;
macro_rules! impl_into_future {
($builder:ident, $return_ty:ty, $method:literal) => {
impl IntoFuture for $builder {
type Output = Result<$return_ty>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { self.client.post_json($method, &self.params).await })
}
}
};
}
#[derive(Serialize)]
struct SendInvoiceParams {
chat_id: ChatId,
title: String,
description: String,
payload: String,
currency: String,
prices: Vec<LabeledPrice>,
#[serde(skip_serializing_if = "Option::is_none")]
message_thread_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
direct_messages_topic_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
provider_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
max_tip_amount: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
suggested_tip_amounts: Option<Vec<u32>>,
#[serde(skip_serializing_if = "Option::is_none")]
start_parameter: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
provider_data: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_size: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_width: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_height: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
need_name: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
need_phone_number: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
need_email: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
need_shipping_address: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
send_phone_number_to_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
send_email_to_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
is_flexible: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
disable_notification: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
protect_content: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
allow_paid_broadcast: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
reply_parameters: Option<ReplyParameters>,
#[serde(skip_serializing_if = "Option::is_none")]
reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
#[serde(skip_serializing_if = "Option::is_none")]
suggested_post_parameters: Option<SuggestedPostParameters>,
#[serde(skip_serializing_if = "Option::is_none")]
message_effect_id: Option<String>,
}
pub struct SendInvoice {
client: BotClient,
params: SendInvoiceParams,
}
impl SendInvoice {
pub(crate) fn new(
client: BotClient,
chat_id: impl Into<ChatId>,
title: impl Into<String>,
description: impl Into<String>,
payload: impl Into<String>,
currency: impl Into<String>,
prices: Vec<LabeledPrice>,
) -> Self {
Self {
client,
params: SendInvoiceParams {
chat_id: chat_id.into(),
title: title.into(),
description: description.into(),
payload: payload.into(),
currency: currency.into(),
prices,
message_thread_id: None,
direct_messages_topic_id: None,
provider_token: None,
max_tip_amount: None,
suggested_tip_amounts: None,
start_parameter: None,
provider_data: None,
photo_url: None,
photo_size: None,
photo_width: None,
photo_height: None,
need_name: None,
need_phone_number: None,
need_email: None,
need_shipping_address: None,
send_phone_number_to_provider: None,
send_email_to_provider: None,
is_flexible: None,
disable_notification: None,
protect_content: None,
allow_paid_broadcast: None,
reply_parameters: None,
reply_markup: None,
suggested_post_parameters: None,
message_effect_id: None,
},
}
}
pub fn message_thread_id(mut self, id: i64) -> Self {
self.params.message_thread_id = Some(id);
self
}
pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
self.params.direct_messages_topic_id = Some(id);
self
}
pub fn provider_token(mut self, t: impl Into<String>) -> Self {
self.params.provider_token = Some(t.into());
self
}
pub fn need_name(mut self, v: bool) -> Self {
self.params.need_name = Some(v);
self
}
pub fn need_shipping_address(mut self, v: bool) -> Self {
self.params.need_shipping_address = Some(v);
self
}
pub fn is_flexible(mut self, v: bool) -> Self {
self.params.is_flexible = Some(v);
self
}
pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
self.params.reply_markup = Some(m);
self
}
pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
self.params.suggested_post_parameters = Some(params);
self
}
pub fn message_effect_id(mut self, v: impl Into<String>) -> Self {
self.params.message_effect_id = Some(v.into());
self
}
pub fn max_tip_amount(mut self, v: u32) -> Self {
self.params.max_tip_amount = Some(v);
self
}
pub fn suggested_tip_amounts(mut self, v: Vec<u32>) -> Self {
self.params.suggested_tip_amounts = Some(v);
self
}
pub fn start_parameter(mut self, v: impl Into<String>) -> Self {
self.params.start_parameter = Some(v.into());
self
}
pub fn provider_data(mut self, v: impl Into<String>) -> Self {
self.params.provider_data = Some(v.into());
self
}
pub fn photo_url(mut self, v: impl Into<String>) -> Self {
self.params.photo_url = Some(v.into());
self
}
pub fn photo_size(mut self, v: u32) -> Self {
self.params.photo_size = Some(v);
self
}
pub fn photo_width(mut self, v: u32) -> Self {
self.params.photo_width = Some(v);
self
}
pub fn photo_height(mut self, v: u32) -> Self {
self.params.photo_height = Some(v);
self
}
pub fn need_phone_number(mut self, v: bool) -> Self {
self.params.need_phone_number = Some(v);
self
}
pub fn need_email(mut self, v: bool) -> Self {
self.params.need_email = Some(v);
self
}
pub fn send_phone_number_to_provider(mut self, v: bool) -> Self {
self.params.send_phone_number_to_provider = Some(v);
self
}
pub fn send_email_to_provider(mut self, v: bool) -> Self {
self.params.send_email_to_provider = Some(v);
self
}
pub fn disable_notification(mut self, v: bool) -> Self {
self.params.disable_notification = Some(v);
self
}
pub fn protect_content(mut self, v: bool) -> Self {
self.params.protect_content = Some(v);
self
}
pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
self.params.allow_paid_broadcast = Some(v);
self
}
pub fn reply_parameters(mut self, v: ReplyParameters) -> Self {
self.params.reply_parameters = Some(v);
self
}
}
impl_into_future!(SendInvoice, Message, "sendInvoice");
#[derive(Serialize)]
struct CreateInvoiceLinkParams {
title: String,
description: String,
payload: String,
currency: String,
prices: Vec<LabeledPrice>,
#[serde(skip_serializing_if = "Option::is_none")]
business_connection_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
provider_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
subscription_period: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
max_tip_amount: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
suggested_tip_amounts: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
provider_data: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_size: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_width: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
photo_height: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
need_name: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
need_phone_number: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
need_email: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
need_shipping_address: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
send_phone_number_to_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
send_email_to_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
is_flexible: Option<bool>,
}
pub struct CreateInvoiceLink {
client: BotClient,
params: CreateInvoiceLinkParams,
}
impl CreateInvoiceLink {
pub(crate) fn new(
client: BotClient,
title: impl Into<String>,
description: impl Into<String>,
payload: impl Into<String>,
currency: impl Into<String>,
prices: Vec<LabeledPrice>,
) -> Self {
Self {
client,
params: CreateInvoiceLinkParams {
title: title.into(),
description: description.into(),
payload: payload.into(),
currency: currency.into(),
prices,
business_connection_id: None,
provider_token: None,
subscription_period: None,
max_tip_amount: None,
suggested_tip_amounts: None,
provider_data: None,
photo_url: None,
photo_size: None,
photo_width: None,
photo_height: None,
need_name: None,
need_phone_number: None,
need_email: None,
need_shipping_address: None,
send_phone_number_to_provider: None,
send_email_to_provider: None,
is_flexible: None,
},
}
}
pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
self.params.business_connection_id = Some(id.into());
self
}
pub fn provider_token(mut self, t: impl Into<String>) -> Self {
self.params.provider_token = Some(t.into());
self
}
pub fn subscription_period(mut self, secs: i64) -> Self {
self.params.subscription_period = Some(secs);
self
}
pub fn max_tip_amount(mut self, v: i64) -> Self {
self.params.max_tip_amount = Some(v);
self
}
pub fn photo_url(mut self, url: impl Into<String>) -> Self {
self.params.photo_url = Some(url.into());
self
}
pub fn need_name(mut self, v: bool) -> Self {
self.params.need_name = Some(v);
self
}
pub fn need_phone_number(mut self, v: bool) -> Self {
self.params.need_phone_number = Some(v);
self
}
pub fn need_email(mut self, v: bool) -> Self {
self.params.need_email = Some(v);
self
}
pub fn need_shipping_address(mut self, v: bool) -> Self {
self.params.need_shipping_address = Some(v);
self
}
pub fn send_phone_number_to_provider(mut self, v: bool) -> Self {
self.params.send_phone_number_to_provider = Some(v);
self
}
pub fn send_email_to_provider(mut self, v: bool) -> Self {
self.params.send_email_to_provider = Some(v);
self
}
pub fn is_flexible(mut self, v: bool) -> Self {
self.params.is_flexible = Some(v);
self
}
pub fn suggested_tip_amounts(mut self, v: Vec<i64>) -> Self {
self.params.suggested_tip_amounts = Some(v);
self
}
pub fn provider_data(mut self, v: impl Into<String>) -> Self {
self.params.provider_data = Some(v.into());
self
}
pub fn photo_size(mut self, v: i64) -> Self {
self.params.photo_size = Some(v);
self
}
pub fn photo_width(mut self, v: i64) -> Self {
self.params.photo_width = Some(v);
self
}
pub fn photo_height(mut self, v: i64) -> Self {
self.params.photo_height = Some(v);
self
}
}
impl_into_future!(CreateInvoiceLink, String, "createInvoiceLink");
#[derive(Serialize)]
struct AnswerShippingQueryParams {
shipping_query_id: String,
ok: bool,
#[serde(skip_serializing_if = "Option::is_none")]
shipping_options: Option<Vec<ShippingOption>>,
#[serde(skip_serializing_if = "Option::is_none")]
error_message: Option<String>,
}
pub struct AnswerShippingQuery {
client: BotClient,
params: AnswerShippingQueryParams,
}
impl AnswerShippingQuery {
pub(crate) fn new(client: BotClient, shipping_query_id: impl Into<String>, ok: bool) -> Self {
Self {
client,
params: AnswerShippingQueryParams {
shipping_query_id: shipping_query_id.into(),
ok,
shipping_options: None,
error_message: None,
},
}
}
pub fn shipping_options(mut self, opts: Vec<ShippingOption>) -> Self {
self.params.shipping_options = Some(opts);
self
}
pub fn error_message(mut self, msg: impl Into<String>) -> Self {
self.params.error_message = Some(msg.into());
self
}
}
impl_into_future!(AnswerShippingQuery, bool, "answerShippingQuery");
#[derive(Serialize)]
struct AnswerPreCheckoutQueryParams {
pre_checkout_query_id: String,
ok: bool,
#[serde(skip_serializing_if = "Option::is_none")]
error_message: Option<String>,
}
pub struct AnswerPreCheckoutQuery {
client: BotClient,
params: AnswerPreCheckoutQueryParams,
}
impl AnswerPreCheckoutQuery {
pub(crate) fn new(
client: BotClient,
pre_checkout_query_id: impl Into<String>,
ok: bool,
) -> Self {
Self {
client,
params: AnswerPreCheckoutQueryParams {
pre_checkout_query_id: pre_checkout_query_id.into(),
ok,
error_message: None,
},
}
}
pub fn error_message(mut self, msg: impl Into<String>) -> Self {
self.params.error_message = Some(msg.into());
self
}
}
impl_into_future!(AnswerPreCheckoutQuery, bool, "answerPreCheckoutQuery");
#[derive(Serialize)]
struct RefundStarPaymentParams {
user_id: i64,
telegram_payment_charge_id: String,
}
pub struct RefundStarPayment {
client: BotClient,
params: RefundStarPaymentParams,
}
impl RefundStarPayment {
pub(crate) fn new(
client: BotClient,
user_id: i64,
telegram_payment_charge_id: impl Into<String>,
) -> Self {
Self {
client,
params: RefundStarPaymentParams {
user_id,
telegram_payment_charge_id: telegram_payment_charge_id.into(),
},
}
}
}
impl_into_future!(RefundStarPayment, bool, "refundStarPayment");
#[derive(Serialize)]
struct EditUserStarSubscriptionParams {
user_id: i64,
telegram_payment_charge_id: String,
is_canceled: bool,
}
pub struct EditUserStarSubscription {
client: BotClient,
params: EditUserStarSubscriptionParams,
}
impl EditUserStarSubscription {
pub(crate) fn new(
client: BotClient,
user_id: i64,
telegram_payment_charge_id: impl Into<String>,
is_canceled: bool,
) -> Self {
Self {
client,
params: EditUserStarSubscriptionParams {
user_id,
telegram_payment_charge_id: telegram_payment_charge_id.into(),
is_canceled,
},
}
}
}
impl_into_future!(EditUserStarSubscription, bool, "editUserStarSubscription");
pub struct GetMyStarBalance {
client: BotClient,
}
impl GetMyStarBalance {
pub(crate) fn new(client: BotClient) -> Self {
Self { client }
}
}
impl IntoFuture for GetMyStarBalance {
type Output = Result<StarAmount>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
self.client
.post_json("getMyStarBalance", &serde_json::json!({}))
.await
})
}
}
#[derive(Serialize, Default)]
struct GetStarTransactionsParams {
#[serde(skip_serializing_if = "Option::is_none")]
offset: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<u32>,
}
pub struct GetStarTransactions {
client: BotClient,
params: GetStarTransactionsParams,
}
impl GetStarTransactions {
pub(crate) fn new(client: BotClient) -> Self {
Self {
client,
params: Default::default(),
}
}
pub fn offset(mut self, v: u32) -> Self {
self.params.offset = Some(v);
self
}
pub fn limit(mut self, v: u32) -> Self {
self.params.limit = Some(v);
self
}
}
impl_into_future!(GetStarTransactions, StarTransactions, "getStarTransactions");