diff --git a/apps/labrinth/migrations/20260630120000_shared-instance-invite-notification.sql b/apps/labrinth/migrations/20260630120000_shared-instance-invite-notification.sql new file mode 100644 index 0000000000..3a4f777508 --- /dev/null +++ b/apps/labrinth/migrations/20260630120000_shared-instance-invite-notification.sql @@ -0,0 +1,6 @@ +INSERT INTO notifications_types + (name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications) +VALUES ('shared_instance_invite', 1, FALSE, TRUE); + +INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled) +VALUES (NULL, 'email', 'shared_instance_invite', FALSE); diff --git a/apps/labrinth/src/models/v2/notifications.rs b/apps/labrinth/src/models/v2/notifications.rs index e0b632ca21..3e60cdbe89 100644 --- a/apps/labrinth/src/models/v2/notifications.rs +++ b/apps/labrinth/src/models/v2/notifications.rs @@ -73,6 +73,10 @@ pub enum LegacyNotificationBody { invited_by: UserId, role: String, }, + SharedInstanceInvite { + shared_instance_id: String, + shared_instance_name: String, + }, StatusChange { project_id: ProjectId, old_status: ProjectStatus, @@ -177,6 +181,9 @@ impl LegacyNotification { NotificationBody::ServerInvite { .. } => { Some("server_invite".to_string()) } + NotificationBody::SharedInstanceInvite { .. } => { + Some("shared_instance_invite".to_string()) + } NotificationBody::StatusChange { .. } => { Some("status_change".to_string()) } @@ -294,6 +301,13 @@ impl LegacyNotification { invited_by, role, }, + NotificationBody::SharedInstanceInvite { + shared_instance_id, + shared_instance_name, + } => LegacyNotificationBody::SharedInstanceInvite { + shared_instance_id, + shared_instance_name, + }, NotificationBody::StatusChange { project_id, old_status, diff --git a/apps/labrinth/src/models/v3/notifications.rs b/apps/labrinth/src/models/v3/notifications.rs index d8ea3d4f71..ebef09548f 100644 --- a/apps/labrinth/src/models/v3/notifications.rs +++ b/apps/labrinth/src/models/v3/notifications.rs @@ -36,6 +36,7 @@ pub enum NotificationType { TeamInvite, OrganizationInvite, ServerInvite, + SharedInstanceInvite, StatusChange, ModeratorMessage, LegacyMarkdown, @@ -71,6 +72,7 @@ impl NotificationType { NotificationType::TeamInvite => "team_invite", NotificationType::OrganizationInvite => "organization_invite", NotificationType::ServerInvite => "server_invite", + NotificationType::SharedInstanceInvite => "shared_instance_invite", NotificationType::StatusChange => "status_change", NotificationType::ModeratorMessage => "moderator_message", NotificationType::LegacyMarkdown => "legacy_markdown", @@ -112,6 +114,7 @@ impl NotificationType { "team_invite" => NotificationType::TeamInvite, "organization_invite" => NotificationType::OrganizationInvite, "server_invite" => NotificationType::ServerInvite, + "shared_instance_invite" => NotificationType::SharedInstanceInvite, "status_change" => NotificationType::StatusChange, "moderator_message" => NotificationType::ModeratorMessage, "legacy_markdown" => NotificationType::LegacyMarkdown, @@ -173,6 +176,10 @@ pub enum NotificationBody { invited_by: UserId, role: String, }, + SharedInstanceInvite { + shared_instance_id: String, + shared_instance_name: String, + }, StatusChange { project_id: ProjectId, old_status: ProjectStatus, @@ -288,6 +295,9 @@ impl NotificationBody { NotificationBody::ServerInvite { .. } => { NotificationType::ServerInvite } + NotificationBody::SharedInstanceInvite { .. } => { + NotificationType::SharedInstanceInvite + } NotificationBody::StatusChange { .. } => { NotificationType::StatusChange } @@ -470,6 +480,32 @@ impl From for Notification { }, ], ), + NotificationBody::SharedInstanceInvite { + shared_instance_name, + .. + } => ( + "You have been invited to a shared instance!".to_string(), + format!( + "An invite has been sent for you to join {shared_instance_name}" + ), + "#".to_string(), + vec![ + NotificationAction { + name: "Accept".to_string(), + action_route: ( + "POST".to_string(), + String::new(), + ), + }, + NotificationAction { + name: "Deny".to_string(), + action_route: ( + "POST".to_string(), + String::new(), + ), + }, + ], + ), NotificationBody::StatusChange { old_status, new_status, diff --git a/apps/labrinth/src/queue/email/templates.rs b/apps/labrinth/src/queue/email/templates.rs index a1fd487d29..c5772a413f 100644 --- a/apps/labrinth/src/queue/email/templates.rs +++ b/apps/labrinth/src/queue/email/templates.rs @@ -772,6 +772,7 @@ async fn collect_template_variables( } NotificationBody::ProjectUpdate { .. } + | NotificationBody::SharedInstanceInvite { .. } | NotificationBody::ModeratorMessage { .. } | NotificationBody::LegacyMarkdown { .. } | NotificationBody::Unknown => Ok(EmailTemplate::Static(map)),