inital webhook support

This commit is contained in:
Zomatree
2022-11-26 23:07:22 +00:00
parent ee1c4cc2d5
commit 5cb2320760
31 changed files with 653 additions and 38 deletions

View File

@@ -1,4 +1,4 @@
use crate::models::channel::{Channel, FieldsChannel, PartialChannel};
use crate::models::{channel::{Channel, FieldsChannel, PartialChannel}};
use crate::{AbstractAttachment, AbstractChannel, Error, OverrideField, Result};
use super::super::DummyDb;

View File

@@ -9,7 +9,7 @@ impl AbstractMessage for DummyDb {
Ok(Message {
id: id.into(),
channel: "channel".into(),
author: "author".into(),
author: Some("author".into()),
content: Some("message content".into()),
..Default::default()

View File

@@ -0,0 +1,40 @@
use crate::models::webhook::{Webhook, FieldsWebhook, PartialWebhook};
use crate::{AbstractWebhook, Result};
use super::super::DummyDb;
#[async_trait]
impl AbstractWebhook for DummyDb {
async fn insert_webhook(&self, webhook: &Webhook) -> Result<()> {
info!("Created webhook {} in {}", webhook.name, webhook.channel);
Ok(())
}
async fn delete_webhook(&self, webhook_id: &str) -> Result<()> {
info!("deleting webhook {webhook_id}");
Ok(())
}
async fn fetch_webhook(&self, webhook_id: &str) -> Result<Webhook> {
Ok(Webhook {
id: webhook_id.to_string(),
name: "".to_string(),
avatar: None,
channel: "0".to_string(),
token: "".to_owned(),
})
}
async fn update_webook(&self, webhook_id: &str, partial_webhook: &PartialWebhook, remove: &[FieldsWebhook]) -> Result<()> {
info!("updating webhook {webhook_id}, {partial_webhook:?}, removing {remove:?}");
Ok(())
}
async fn fetch_webhooks_for_channel(&self, channel: &str) -> Result<Vec<Webhook>> {
info!("fetching webhooks for channel {channel}");
Ok(vec![self.fetch_webhook("0").await?])
}
}

View File

@@ -14,6 +14,7 @@ pub mod channels {
pub mod channel_invite;
pub mod channel_unread;
pub mod message;
pub mod webhook;
}
pub mod servers {

View File

@@ -18,7 +18,7 @@ use crate::{
tasks::ack::AckEvent,
types::{
january::{Embed, Text},
push::PushNotification,
push::{PushNotification, MessageAuthor},
},
Database, Error, Permission, Result,
};
@@ -66,7 +66,7 @@ impl Message {
&mut self,
db: &Database,
channel: &Channel,
sender: Option<&User>,
sender: Option<MessageAuthor<'_>>,
) -> Result<()> {
self.create_no_web_push(db, channel.id(), channel.is_direct_dm())
.await?;
@@ -271,6 +271,14 @@ impl Message {
// Write to database
db.clear_reaction(&self.id, emoji).await
}
/// Gets either the user or the webhook id which sent this message
pub fn author_id(&self) -> &str {
match &self.author {
Some(id) => id,
None => self.webhook.as_deref().unwrap()
}
}
}
pub trait IntoUsers {
@@ -279,7 +287,11 @@ pub trait IntoUsers {
impl IntoUsers for Message {
fn get_user_ids(&self) -> Vec<String> {
let mut ids = vec![self.author.clone()];
let mut ids = Vec::new();
if let Some(author) = &self.author {
ids.push(author.clone());
};
if let Some(msg) = &self.system {
match msg {
@@ -319,7 +331,7 @@ impl SystemMessage {
Message {
id: Ulid::new().to_string(),
channel,
author: "00000000000000000000000000".to_string(),
author: Some("00000000000000000000000000".to_string()),
system: Some(self),
..Default::default()

View File

@@ -0,0 +1,58 @@
use crate::{
events::client::EventV1,
models::{
webhook::{Webhook, PartialWebhook, FieldsWebhook}
},
Database, Result
};
impl Webhook {
pub async fn create(&self, db: &Database) -> Result<()> {
db.insert_webhook(self).await?;
EventV1::WebhookCreate(self.clone())
.p(self.channel.clone()).await;
Ok(())
}
pub async fn delete(&self, db: &Database) -> Result<()> {
db.delete_webhook(&self.id).await?;
EventV1::WebhookDelete { id: self.id.clone() }
.p(self.channel.clone()).await;
Ok(())
}
pub async fn update(
&mut self,
db: &Database,
partial: PartialWebhook,
remove: Vec<FieldsWebhook>
) -> Result<()> {
for field in &remove {
self.remove(field)
};
self.apply_options(partial.clone());
db.update_webook(&self.id, &partial, &remove).await?;
EventV1::WebhookUpdate {
id: self.id.clone(),
data: partial,
remove
}
.p(self.channel.clone())
.await;
Ok(())
}
fn remove(&mut self, field: &FieldsWebhook) {
match field {
FieldsWebhook::Avatar => self.avatar = None
}
}
}

View File

@@ -14,6 +14,7 @@ pub mod channels {
pub mod channel_invite;
pub mod channel_unread;
pub mod message;
pub mod webhook;
}
pub mod servers {

View File

@@ -37,9 +37,24 @@ impl MongoDb {
operation: "delete_many",
with: "channel_unreads",
})
.map(|_| ())
.map(|_| ())?;
// update many attachments with parent id
// Delete all webhooks on this channel.
self.col::<Document>("webhooks")
.delete_many(
doc! {
"channel": &id
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "delete_many",
with: "webhooks",
})
.map(|_| ())
}
}

View File

@@ -0,0 +1,57 @@
use crate::models::{webhook::{Webhook, PartialWebhook, FieldsWebhook}};
use crate::r#impl::mongo::IntoDocumentPath;
use crate::{Result, AbstractWebhook};
use super::super::MongoDb;
static COL: &str = "webhooks";
#[async_trait]
impl AbstractWebhook for MongoDb {
async fn insert_webhook(&self, webhook: &Webhook) -> Result<()> {
self.insert_one(COL, webhook).await?;
Ok(())
}
async fn fetch_webhook(&self, webhook_id: &str) -> Result<Webhook> {
info!("{COL} {webhook_id}");
self.find_one_by_id(COL, webhook_id).await
}
async fn delete_webhook(&self, webhook_id: &str) -> Result<()> {
self.delete_one_by_id(COL, webhook_id).await?;
Ok(())
}
async fn update_webook(&self, webhook_id: &str, partial_webhook: &PartialWebhook, remove: &[FieldsWebhook]) -> Result<()> {
self.update_one_by_id(
COL,
webhook_id,
partial_webhook,
remove.iter().map(|x| x as &dyn IntoDocumentPath).collect(),
None,
)
.await
.map(|_| ())
}
async fn fetch_webhooks_for_channel(&self, channel: &str) -> Result<Vec<Webhook>> {
self.find(
COL,
doc! {
"channel": channel
})
.await
}
}
impl IntoDocumentPath for FieldsWebhook {
fn as_path(&self) -> Option<&'static str> {
match self {
FieldsWebhook::Avatar => Some("avatar"),
}
}
}

View File

@@ -25,6 +25,7 @@ pub mod channels {
pub mod channel_invite;
pub mod channel_unread;
pub mod message;
pub mod webhook;
}
pub mod servers {