Merge pull request #29 from polyphony-chat/feature/sending-messages

Bring main up to date
This commit is contained in:
Flori 2023-05-05 22:10:43 +02:00 committed by GitHub
commit 7ebf9e5cc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 91 deletions

View File

@ -8,7 +8,7 @@ edition = "2021"
tokio = {version = "1.27.0", features = ["rt", "macros", "rt-multi-thread"]} tokio = {version = "1.27.0", features = ["rt", "macros", "rt-multi-thread"]}
serde = {version = "1.0.159", features = ["derive"]} serde = {version = "1.0.159", features = ["derive"]}
serde_json = "1.0.95" serde_json = "1.0.95"
reqwest = "0.11.16" reqwest = {version = "0.11.16", features = ["multipart"]}
url = "2.3.1" url = "2.3.1"
chrono = "0.4.24" chrono = "0.4.24"
regex = "1.7.3" regex = "1.7.3"

View File

@ -1,11 +1,6 @@
pub mod messages { pub mod messages {
use reqwest::{Client, Response};
use serde_json::to_string;
use std::io::Read;
use crate::api::limits::Limits; use crate::api::limits::Limits;
use crate::api::types::{DiscordFileAttachment, Message, User}; use crate::api::types::{Message, PartialDiscordFileAttachment, User};
use crate::errors::InstanceServerError;
use crate::limit::LimitedRequester; use crate::limit::LimitedRequester;
impl Message { impl Message {
@ -20,54 +15,21 @@ pub mod messages {
# Errors # Errors
* [`InstanceServerError`] - If the message cannot be sent. * [`InstanceServerError`] - If the message cannot be sent.
*/ */
pub async fn send(
pub async fn send<'a>(
url_api: &String, url_api: &String,
token: &String, message: &mut Message,
message: &Message, files: Option<Vec<PartialDiscordFileAttachment>>,
files: Option<Vec<DiscordFileAttachment>>, user: &mut User<'a>,
limits_user: &mut Limits,
limits_instance: &mut Limits, limits_instance: &mut Limits,
requester: &mut LimitedRequester, requester: &mut LimitedRequester,
) -> Result<Response, InstanceServerError> { ) {
let mut request = Client::new() let token = user.token();
.post(format!( let mut limits = &mut user.rate_limits;
"{}/channels/{}/messages",
url_api, message.channel_id
))
.body(to_string(message).unwrap())
.bearer_auth(token);
if files.is_some() {}
match requester
.send_request(
request,
crate::api::limits::LimitType::Channel,
limits_instance,
limits_user,
)
.await
{
Ok(result) => Ok(result),
Err(e) => Err(e),
}
} }
} }
impl<'a> User<'a> { impl<'a> User<'a> {
pub async fn send_message( pub async fn send_message() {}
&mut self,
message: &Message,
files: Option<Vec<DiscordFileAttachment>>,
) -> Result<Response, InstanceServerError> {
Message::send(
&self.belongs_to().urls.get_api().to_string(),
&self.token(),
message,
files,
self.rate_limits.get_as_mut(),
&mut self.belongs_to.limits.get_as_mut(),
&mut LimitedRequester::new().await,
)
.await
}
} }
} }

View File

@ -1,8 +1,12 @@
use std::{collections::HashMap, io::Bytes};
use regex::Regex; use regex::Regex;
use serde::{Deserialize, Serialize}; use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
use crate::errors::FieldFormatError; use crate::errors::FieldFormatError;
use super::{DiscordFileAttachment, Embed};
/** /**
A struct that represents a well-formed email address. A struct that represents a well-formed email address.
*/ */
@ -240,6 +244,24 @@ pub struct TotpSchema {
login_source: Option<String>, login_source: Option<String>,
} }
#[derive(Debug, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct MessageSendSchema {
#[serde(rename = "type")]
message_type: i32,
content: Option<String>,
nonce: Option<String>,
tts: Option<bool>,
embeds: Option<Vec<super::Embed>>,
allowed_mentions: Option<super::AllowedMention>,
message_reference: Option<super::MessageReference>,
components: Option<Vec<super::Component>>,
sticker_ids: Option<Vec<String>>,
#[serde(flatten)]
files: Option<HashMap<String, Vec<u8>>>,
attachments: Option<Vec<super::PartialDiscordFileAttachment>>,
}
// I know that some of these tests are... really really basic and unneccessary, but sometimes, I // I know that some of these tests are... really really basic and unneccessary, but sometimes, I
// just feel like writing tests, so there you go :) -@bitfl0wer // just feel like writing tests, so there you go :) -@bitfl0wer
#[cfg(test)] #[cfg(test)]

View File

@ -4,7 +4,7 @@ https://discord.com/developers/docs .
I do not feel like re-documenting all of this, as everything is already perfectly explained there. I do not feel like re-documenting all of this, as everything is already perfectly explained there.
*/ */
use std::fs::File; use std::{collections::HashMap, fs::File};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -216,7 +216,7 @@ pub struct Message {
mentions: Vec<UserObject>, mentions: Vec<UserObject>,
mention_roles: Vec<String>, mention_roles: Vec<String>,
mention_channels: Option<Vec<ChannelMention>>, mention_channels: Option<Vec<ChannelMention>>,
attachments: Vec<Attachment>, pub attachments: Vec<DiscordFileAttachment>,
embeds: Vec<Embed>, embeds: Vec<Embed>,
reactions: Option<Vec<Reaction>>, reactions: Option<Vec<Reaction>>,
nonce: Option<serde_json::Value>, nonce: Option<serde_json::Value>,
@ -263,7 +263,7 @@ struct PartialMessage {
mentions: Option<Vec<UserObject>>, mentions: Option<Vec<UserObject>>,
mention_roles: Option<Vec<String>>, mention_roles: Option<Vec<String>>,
mention_channels: Option<Vec<ChannelMention>>, mention_channels: Option<Vec<ChannelMention>>,
attachments: Option<Vec<Attachment>>, attachments: Option<Vec<DiscordFileAttachment>>,
embeds: Option<Vec<Embed>>, embeds: Option<Vec<Embed>>,
reactions: Option<Vec<Reaction>>, reactions: Option<Vec<Reaction>>,
nonce: Option<serde_json::Value>, nonce: Option<serde_json::Value>,
@ -368,25 +368,11 @@ struct ChannelMention {
name: String, name: String,
} }
#[derive(Debug, Serialize, Deserialize)]
struct Attachment {
id: String,
filename: String,
description: Option<String>,
content_type: Option<String>,
size: i64,
url: String,
proxy_url: String,
height: Option<String>,
width: Option<String>,
ephemeral: Option<bool>,
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
/** /**
Represents an Embed. [See the Discord Documentation](https://discord.com/developers/docs/resources/channel#embed-object). Represents an Embed. [See the Discord Documentation](https://discord.com/developers/docs/resources/channel#embed-object).
*/ */
struct Embed { pub struct Embed {
title: Option<String>, title: Option<String>,
#[serde(rename = "type")] #[serde(rename = "type")]
embed_type: Option<String>, embed_type: Option<String>,
@ -539,9 +525,9 @@ struct InstallParams {
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct MessageReference { pub struct MessageReference {
message_id: Option<String>, message_id: String,
channel_id: Option<String>, channel_id: String,
guild_id: Option<String>, guild_id: Option<String>,
fail_if_not_exists: Option<bool>, fail_if_not_exists: Option<bool>,
} }
@ -655,7 +641,7 @@ struct DefaultReaction {
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
enum Component { pub enum Component {
ActionRow = 1, ActionRow = 1,
Button = 2, Button = 2,
StringSelect = 3, StringSelect = 3,
@ -842,27 +828,51 @@ pub struct GatewayPayload {
impl WebSocketEvent for GatewayPayload {} impl WebSocketEvent for GatewayPayload {}
#[derive(Debug, Serialize, Deserialize)]
pub struct DiscordFileAttachment { pub struct DiscordFileAttachment {
pub name: String, pub id: i16,
pub filename: String, pub filename: String,
pub file: File, description: Option<String>,
content_type: Option<String>,
size: i64,
url: String,
proxy_url: String,
height: Option<i32>,
width: Option<i32>,
ephemeral: Option<bool>,
duration_secs: Option<f32>,
waveform: Option<String>,
} }
impl DiscordFileAttachment { #[derive(Debug, Serialize, Deserialize)]
pub fn new(filenames: &Vec<String>, files: Vec<File>) {
//-> Vec<DiscordFileAttachment> { pub struct PartialDiscordFileAttachment {
if filenames.len() != files.len() { pub id: Option<i16>,
panic!("Your 'filenames' Vector has either more or less elements than your 'files' Vector.") pub filename: Option<String>,
} description: Option<String>,
let mut return_vec: Vec<DiscordFileAttachment> = Vec::new(); content_type: Option<String>,
let mut counter = 0; size: Option<i64>,
/*for _ in 0..files.len() { url: Option<String>,
return_vec.push(DiscordFileAttachment { proxy_url: Option<String>,
name: format!("files[{}]", counter.to_string()), height: Option<i32>,
filename: filenames.iter().next().unwrap().to_string(), width: Option<i32>,
file: files.get(0).unwrap(), ephemeral: Option<bool>,
}); duration_secs: Option<f32>,
} waveform: Option<String>,
return_vec*/ }
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AllowedMention {
parse: Vec<AllowedMentionType>,
roles: Vec<String>,
users: Vec<String>,
replied_user: bool,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AllowedMentionType {
Roles,
Users,
Everyone,
} }