mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
Add option to send requests with json instead of multipart/form-data
This commit is contained in:
parent
19f7ce1435
commit
27debb0c77
5 changed files with 56 additions and 41 deletions
|
@ -5,6 +5,7 @@ use serde::de::DeserializeOwned;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::core::requests::{RequestError, ResponseResult};
|
use crate::core::requests::{RequestError, ResponseResult};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
const TELEGRAM_API_URL: &str = "https://api.telegram.org";
|
const TELEGRAM_API_URL: &str = "https://api.telegram.org";
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ fn file_url(base: &str, token: &str, file_path: &str) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn request<T: DeserializeOwned>(
|
pub async fn request_multipart<T: DeserializeOwned>(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
token: &str,
|
token: &str,
|
||||||
method_name: &str,
|
method_name: &str,
|
||||||
|
@ -68,6 +69,39 @@ pub async fn request<T: DeserializeOwned>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn request_json<T: DeserializeOwned, P: Serialize>(
|
||||||
|
client: &Client,
|
||||||
|
token: &str,
|
||||||
|
method_name: &str,
|
||||||
|
params: &P,
|
||||||
|
) -> ResponseResult<T> {
|
||||||
|
let mut response = client
|
||||||
|
.post(&method_url(TELEGRAM_API_URL, token, method_name))
|
||||||
|
.json(params)
|
||||||
|
.send()
|
||||||
|
.compat()
|
||||||
|
.await
|
||||||
|
.map_err(RequestError::NetworkError)?;
|
||||||
|
|
||||||
|
let response_json = serde_json::from_str::<Value>(
|
||||||
|
&response
|
||||||
|
.text()
|
||||||
|
.compat()
|
||||||
|
.await
|
||||||
|
.map_err(RequestError::NetworkError)?,
|
||||||
|
)
|
||||||
|
.map_err(RequestError::InvalidJson)?;
|
||||||
|
|
||||||
|
if response_json["ok"] == "false" {
|
||||||
|
Err(RequestError::ApiError {
|
||||||
|
status_code: response.status(),
|
||||||
|
description: response_json["description"].to_string(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Ok(serde_json::from_value(response_json["result"].clone()).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -3,10 +3,11 @@ use crate::core::requests::{ChatId, RequestContext, Request, RequestFuture, Resp
|
||||||
use crate::core::types::Message;
|
use crate::core::types::Message;
|
||||||
use crate::core::network;
|
use crate::core::network;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
/// Use this method to forward messages of any kind. On success, the sent
|
/// Use this method to forward messages of any kind. On success, the sent
|
||||||
/// [`Message`] is returned.
|
/// [`Message`] is returned.
|
||||||
pub struct ForwardMessage<'a> {
|
pub struct ForwardMessage<'a> {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
ctx: RequestContext<'a>,
|
ctx: RequestContext<'a>,
|
||||||
|
|
||||||
/// Unique identifier for the target chat or username of the target channel
|
/// Unique identifier for the target chat or username of the target channel
|
||||||
|
@ -19,6 +20,7 @@ pub struct ForwardMessage<'a> {
|
||||||
pub message_id: i64,
|
pub message_id: i64,
|
||||||
|
|
||||||
/// Sends the message silently. Users will receive a notification with no sound.
|
/// Sends the message silently. Users will receive a notification with no sound.
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub disable_notification: Option<bool>,
|
pub disable_notification: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,21 +29,11 @@ impl<'a> Request<'a> for ForwardMessage<'a> {
|
||||||
|
|
||||||
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
|
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let params = FormBuilder::new()
|
network::request_json(
|
||||||
.add("chat_id", &self.chat_id)
|
|
||||||
.add("from_chat_id", &self.from_chat_id)
|
|
||||||
.add("message_id", &self.message_id)
|
|
||||||
.add_if_some(
|
|
||||||
"disable_notification",
|
|
||||||
self.disable_notification.as_ref()
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
network::request(
|
|
||||||
&self.ctx.client,
|
&self.ctx.client,
|
||||||
&self.ctx.token,
|
&self.ctx.token,
|
||||||
"forwardMessage",
|
"forwardMessage",
|
||||||
Some(params),
|
&self,
|
||||||
).await
|
).await
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ impl<'a> Request<'a> for GetMe<'a> {
|
||||||
|
|
||||||
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
|
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
network::request(self.info.client, self.info.token, "getMe", None)
|
network::request_multipart(self.info.client, self.info.token, "getMe", None)
|
||||||
.await
|
.await
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,12 @@ use crate::core::requests::{
|
||||||
};
|
};
|
||||||
use crate::core::{network, types::Message, types::ParseMode};
|
use crate::core::{network, types::Message, types::ParseMode};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
/// Use this method to send text messages. On success, the sent [`Message`] is returned.
|
/// Use this method to send text messages. On success, the sent [`Message`] is returned.
|
||||||
pub struct SendMessage<'a> {
|
pub struct SendMessage<'a> {
|
||||||
info: RequestContext<'a>,
|
#[serde(skip_serializing)]
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
|
||||||
/// Unique identifier for the target chat or username of the target channel
|
/// Unique identifier for the target chat or username of the target channel
|
||||||
/// (in the format @channelusername)
|
/// (in the format @channelusername)
|
||||||
|
@ -23,13 +25,18 @@ pub struct SendMessage<'a> {
|
||||||
/// [Html]: crate::core::types::ParseMode::Html
|
/// [Html]: crate::core::types::ParseMode::Html
|
||||||
/// [bold, italic, fixed-width text or inline URLs]:
|
/// [bold, italic, fixed-width text or inline URLs]:
|
||||||
/// crate::core::types::ParseMode
|
/// crate::core::types::ParseMode
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub parse_mode: Option<ParseMode>,
|
pub parse_mode: Option<ParseMode>,
|
||||||
/// Disables link previews for links in this message
|
/// Disables link previews for links in this message
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub disable_web_page_preview: Option<bool>,
|
pub disable_web_page_preview: Option<bool>,
|
||||||
/// Sends the message silently. Users will receive a notification with no sound.
|
/// Sends the message silently. Users will receive a notification with no sound.
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub disable_notification: Option<bool>,
|
pub disable_notification: Option<bool>,
|
||||||
/// If the message is a reply, ID of the original message
|
/// If the message is a reply, ID of the original message
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub reply_to_message_id: Option<i64>,
|
pub reply_to_message_id: Option<i64>,
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub reply_markup: Option<()>, // TODO: ReplyMarkup enum
|
pub reply_markup: Option<()>, // TODO: ReplyMarkup enum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,29 +45,11 @@ impl<'a> Request<'a> for SendMessage<'a> {
|
||||||
|
|
||||||
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
|
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let params = FormBuilder::new()
|
network::request_json(
|
||||||
.add("chat_id", &self.chat_id)
|
&self.ctx.client,
|
||||||
.add::<str>("text", &self.text)
|
&self.ctx.token,
|
||||||
.add_if_some("parse_mode", self.parse_mode.as_ref())
|
|
||||||
.add_if_some(
|
|
||||||
"disable_web_page_preview",
|
|
||||||
self.disable_web_page_preview.as_ref(),
|
|
||||||
)
|
|
||||||
.add_if_some(
|
|
||||||
"disable_notification",
|
|
||||||
self.disable_notification.as_ref(),
|
|
||||||
)
|
|
||||||
.add_if_some(
|
|
||||||
"reply_to_message_id",
|
|
||||||
self.reply_to_message_id.as_ref(),
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
network::request(
|
|
||||||
&self.info.client,
|
|
||||||
&self.info.token,
|
|
||||||
"sendMessage",
|
"sendMessage",
|
||||||
Some(params),
|
&self,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
})
|
})
|
||||||
|
@ -74,7 +63,7 @@ impl<'a> SendMessage<'a> {
|
||||||
text: String,
|
text: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
SendMessage {
|
SendMessage {
|
||||||
info,
|
ctx: info,
|
||||||
chat_id,
|
chat_id,
|
||||||
text,
|
text,
|
||||||
parse_mode: None,
|
parse_mode: None,
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl<'a> Request<'a> for SendPhoto<'a> {
|
||||||
};
|
};
|
||||||
let params = params.build();
|
let params = params.build();
|
||||||
|
|
||||||
network::request(
|
network::request_multipart(
|
||||||
&self.ctx.client,
|
&self.ctx.client,
|
||||||
&self.ctx.token,
|
&self.ctx.token,
|
||||||
"sendPhoto",
|
"sendPhoto",
|
||||||
|
|
Loading…
Reference in a new issue