headless_lms_models/
email_deliveries.rs

1use lettre::transport::smtp::Error;
2
3use crate::prelude::*;
4
5#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
6pub struct EmailDelivery {
7    pub id: Uuid,
8    pub created_at: DateTime<Utc>,
9    pub updated_at: DateTime<Utc>,
10    pub deleted_at: Option<DateTime<Utc>>,
11    pub email_template_id: Uuid,
12    pub error: Option<String>,
13    pub sent: bool,
14    pub user_id: Uuid,
15}
16
17pub struct Email {
18    pub id: Uuid,
19    // TODO: change to user.email when field exists in the db.
20    pub to: Uuid,
21    pub subject: Option<String>,
22    pub body: Option<serde_json::Value>,
23}
24
25pub async fn fetch_emails(conn: &mut PgConnection) -> ModelResult<Vec<Email>> {
26    let emails = sqlx::query_as!(
27        Email,
28        "
29SELECT ed.id AS id,
30  u.id AS to,
31  et.subject AS subject,
32  et.content AS body
33FROM email_deliveries ed
34  JOIN email_templates et ON et.id = ed.email_template_id
35  JOIN users u ON u.id = ed.user_id
36WHERE ed.deleted_at IS NULL
37  AND ed.sent = FALSE
38  AND ed.error IS NULL
39LIMIT 10000;
40  ",
41    )
42    .fetch_all(conn)
43    .await?;
44
45    Ok(emails)
46}
47
48pub async fn mark_as_sent(email_id: Uuid, conn: &mut PgConnection) -> ModelResult<()> {
49    sqlx::query!(
50        "
51update email_deliveries
52set sent = TRUE
53where id = $1;
54    ",
55        email_id
56    )
57    .execute(conn)
58    .await?;
59
60    Ok(())
61}
62
63pub async fn save_err_to_email(
64    email_id: Uuid,
65    err: Error,
66    conn: &mut PgConnection,
67) -> ModelResult<()> {
68    sqlx::query!(
69        "
70update email_deliveries
71set sent = FALSE,
72  error = $1
73where id = $2;
74    ",
75        err.to_string(),
76        email_id
77    )
78    .execute(conn)
79    .await?;
80
81    Ok(())
82}