shoutdotdev/src/channels.rs

101 lines
2.8 KiB
Rust
Raw Normal View History

2025-02-26 13:10:45 -08:00
use anyhow::Context;
use deadpool_diesel::postgres::Connection;
use diesel::{
dsl::{auto_type, insert_into, AsSelect},
pg::Pg,
prelude::*,
Connection as _,
};
use serde::Serialize;
use uuid::Uuid;
use crate::{
app_error::AppError,
schema::{channels, email_channels, slack_channels},
teams::Team,
};
#[derive(Associations, Clone, Debug, Identifiable, Queryable, Selectable)]
#[diesel(belongs_to(Team))]
pub struct Channel {
pub id: Uuid,
pub team_id: Uuid,
pub name: String,
pub enable_by_default: bool,
#[diesel(embed)]
pub email_data: Option<EmailChannel>,
#[diesel(embed)]
pub slack_data: Option<SlackChannel>,
}
#[derive(
Associations, Clone, Debug, Identifiable, Insertable, Queryable, Selectable, Serialize,
)]
#[diesel(belongs_to(Channel, foreign_key = id))]
pub struct EmailChannel {
pub id: Uuid,
pub recipient: String,
#[serde(skip_serializing)]
pub verification_code: String,
pub verification_code_guesses: i32,
pub verified: bool,
}
#[derive(Associations, Clone, Debug, Identifiable, Insertable, Queryable, Selectable)]
#[diesel(belongs_to(Channel, foreign_key = id))]
pub struct SlackChannel {
pub id: Uuid,
pub oauth_state: String,
pub access_token: String,
pub conversation_id: String,
}
impl Channel {
#[auto_type(no_type_alias)]
pub fn all() -> _ {
let select: AsSelect<Channel, Pg> = Channel::as_select();
channels::table
.left_join(email_channels::table)
.left_join(slack_channels::table)
.select(select)
}
#[auto_type(no_type_alias)]
pub fn with_id(channel_id: Uuid) -> _ {
channels::id.eq(channel_id)
}
#[auto_type(no_type_alias)]
pub fn with_team(team_id: Uuid) -> _ {
channels::team_id.eq(team_id)
}
pub async fn create_email_channel(
db_conn: &Connection,
team_id: Uuid,
) -> Result<Self, AppError> {
let id = Uuid::now_v7();
db_conn
.interact(move |conn| {
conn.transaction(move |conn| {
insert_into(channels::table)
.values((
channels::id.eq(id.clone()),
channels::team_id.eq(team_id),
channels::name.eq("Untitled Email Channel"),
))
.execute(conn)?;
insert_into(email_channels::table)
.values(email_channels::id.eq(id.clone()))
.execute(conn)?;
Self::all().filter(Self::with_id(id)).first(conn)
})
})
.await
.unwrap()
.context("Failed to insert new EmailChannel.")
.map_err(|err| err.into())
}
}