249 lines
6.9 KiB
Rust
249 lines
6.9 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use std::{collections::HashMap, error::Error};
|
|
|
|
const API_BASE: &str = "https://api.telegram.org";
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct TelegramAPIResponse<T> {
|
|
pub ok: bool,
|
|
pub error_code: Option<u16>,
|
|
pub description: Option<String>,
|
|
pub result: Option<T>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct TelegramStickerSet {
|
|
pub name: String,
|
|
pub title: String,
|
|
pub is_animated: bool,
|
|
pub is_video: bool,
|
|
pub stickers: Vec<TelegramSticker>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct TelegramSticker {
|
|
pub file_id: String,
|
|
pub file_unique_id: String,
|
|
pub is_animated: bool,
|
|
pub is_video: bool,
|
|
pub emoji: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct TelegramError {
|
|
error_code: u16,
|
|
description: String,
|
|
}
|
|
|
|
impl TelegramError {
|
|
fn new(error_code: u16, description: String) -> TelegramError {
|
|
TelegramError {
|
|
error_code,
|
|
description,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for TelegramError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
write!(f, "{} {}", self.error_code, self.description)
|
|
}
|
|
}
|
|
|
|
impl Error for TelegramError {
|
|
fn description(&self) -> &str {
|
|
self.description.as_str()
|
|
}
|
|
}
|
|
|
|
pub struct TelegramAPI {
|
|
token: String,
|
|
client: reqwest::Client,
|
|
}
|
|
|
|
impl TelegramAPI {
|
|
pub fn new(token: String) -> Self {
|
|
Self {
|
|
token,
|
|
client: reqwest::Client::new(),
|
|
}
|
|
}
|
|
|
|
pub async fn get_sticker_set(
|
|
&self,
|
|
pack_name: &str,
|
|
) -> Result<TelegramStickerSet, Box<dyn Error>> {
|
|
let url = format!("{}/bot{}/getStickerSet", API_BASE, self.token);
|
|
let res = self
|
|
.client
|
|
.get(url)
|
|
.form(&HashMap::from([("name", pack_name)]))
|
|
.send()
|
|
.await?;
|
|
|
|
let res_json = res
|
|
.json::<TelegramAPIResponse<TelegramStickerSet>>()
|
|
.await?;
|
|
|
|
if !res_json.ok {
|
|
return Err(Box::new(TelegramError::new(
|
|
res_json.error_code.unwrap(),
|
|
res_json.description.unwrap(),
|
|
)));
|
|
}
|
|
|
|
Ok(res_json.result.unwrap())
|
|
}
|
|
|
|
pub async fn delete_sticker(&self, sticker_file_id: &str) -> Result<bool, Box<dyn Error>> {
|
|
let url = format!("{}/bot{}/deleteStickerFromSet", API_BASE, self.token);
|
|
let res = self
|
|
.client
|
|
.get(url)
|
|
.form(&HashMap::from([("sticker", sticker_file_id)]))
|
|
.send()
|
|
.await?;
|
|
|
|
let res_json = res.json::<TelegramAPIResponse<bool>>().await?;
|
|
|
|
if !res_json.ok {
|
|
return Err(Box::new(TelegramError::new(
|
|
res_json.error_code.unwrap(),
|
|
res_json.description.unwrap(),
|
|
)));
|
|
}
|
|
|
|
Ok(res_json.result.unwrap())
|
|
}
|
|
|
|
#[allow(clippy::too_many_arguments)]
|
|
pub async fn create_sticker_pack(
|
|
&self,
|
|
user_id: u64,
|
|
name: String,
|
|
title: String,
|
|
emojis: String,
|
|
png_sticker: Option<Vec<u8>>,
|
|
tgs_sticker: Option<Vec<u8>>,
|
|
webm_sticker: Option<Vec<u8>>,
|
|
) -> Result<bool, Box<dyn Error>> {
|
|
let url = format!("{}/bot{}/createNewStickerSet", API_BASE, self.token);
|
|
|
|
let mut form = reqwest::multipart::Form::new();
|
|
form = form.text("user_id", user_id.to_string());
|
|
form = form.text("name", name);
|
|
form = form.text("title", title);
|
|
form = form.text("emojis", emojis);
|
|
|
|
if png_sticker.is_some() {
|
|
form = form.part(
|
|
"png_sticker",
|
|
reqwest::multipart::Part::bytes(png_sticker.unwrap()).file_name(""),
|
|
);
|
|
}
|
|
if tgs_sticker.is_some() {
|
|
form = form.part(
|
|
"tgs_sticker",
|
|
reqwest::multipart::Part::bytes(tgs_sticker.unwrap()),
|
|
);
|
|
}
|
|
if webm_sticker.is_some() {
|
|
form = form.part(
|
|
"webm_sticker",
|
|
reqwest::multipart::Part::bytes(webm_sticker.unwrap()),
|
|
);
|
|
}
|
|
|
|
let res = self.client.get(url).multipart(form).send().await?;
|
|
|
|
let res_json = res.json::<TelegramAPIResponse<bool>>().await?;
|
|
|
|
if !res_json.ok {
|
|
return Err(Box::new(TelegramError::new(
|
|
res_json.error_code.unwrap(),
|
|
res_json.description.unwrap(),
|
|
)));
|
|
}
|
|
|
|
Ok(res_json.result.unwrap())
|
|
}
|
|
|
|
pub async fn upload_sticker(
|
|
&self,
|
|
user_id: u64,
|
|
sticker_pack_name: String,
|
|
emojis: Option<String>,
|
|
png_sticker: Option<Vec<u8>>,
|
|
tgs_sticker: Option<Vec<u8>>,
|
|
webm_sticker: Option<Vec<u8>>,
|
|
) -> Result<bool, Box<dyn Error>> {
|
|
let url = format!("{}/bot{}/addStickerToSet", API_BASE, self.token);
|
|
|
|
let mut form = reqwest::multipart::Form::new();
|
|
form = form.text("user_id", user_id.to_string());
|
|
form = form.text("name", sticker_pack_name);
|
|
if emojis.is_some() {
|
|
form = form.text("emojis", emojis.unwrap());
|
|
}
|
|
if png_sticker.is_some() {
|
|
form = form.part(
|
|
"png_sticker",
|
|
reqwest::multipart::Part::bytes(png_sticker.unwrap()).file_name(""),
|
|
);
|
|
}
|
|
if tgs_sticker.is_some() {
|
|
form = form.part(
|
|
"tgs_sticker",
|
|
reqwest::multipart::Part::bytes(tgs_sticker.unwrap()),
|
|
);
|
|
}
|
|
if webm_sticker.is_some() {
|
|
form = form.part(
|
|
"webm_sticker",
|
|
reqwest::multipart::Part::bytes(webm_sticker.unwrap()),
|
|
);
|
|
}
|
|
|
|
let res = self.client.get(url).multipart(form).send().await?;
|
|
|
|
let res_json = res.json::<TelegramAPIResponse<bool>>().await?;
|
|
|
|
if !res_json.ok {
|
|
return Err(Box::new(TelegramError::new(
|
|
res_json.error_code.unwrap(),
|
|
res_json.description.unwrap(),
|
|
)));
|
|
}
|
|
|
|
Ok(res_json.result.unwrap())
|
|
}
|
|
|
|
pub async fn set_sticker_position(
|
|
&self,
|
|
sticker_file_id: String,
|
|
sticker_position: usize,
|
|
) -> Result<bool, Box<dyn Error>> {
|
|
let url = format!("{}/bot{}/setStickerPositionInSet", API_BASE, self.token);
|
|
let res = self
|
|
.client
|
|
.get(url)
|
|
.form(&HashMap::from([
|
|
("sticker", sticker_file_id),
|
|
("position", sticker_position.to_string()),
|
|
]))
|
|
.send()
|
|
.await?;
|
|
|
|
let res_json = res.json::<TelegramAPIResponse<bool>>().await?;
|
|
|
|
if !res_json.ok {
|
|
return Err(Box::new(TelegramError::new(
|
|
res_json.error_code.unwrap(),
|
|
res_json.description.unwrap(),
|
|
)));
|
|
}
|
|
|
|
Ok(res_json.result.unwrap())
|
|
}
|
|
}
|