feat: send notification when access request is approved (#854)
This commit is contained in:
parent
3b320b0619
commit
1664fe869e
|
|
@ -0,0 +1,131 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:v="urn:schemas-microsoft-com:vml">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="x-apple-disable-message-reformatting">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="format-detection" content="telephone=no, date=no, address=no, email=no, url=no">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<meta name="supported-color-schemes" content="light dark">
|
||||||
|
<!--[if mso]>
|
||||||
|
<noscript>
|
||||||
|
<xml>
|
||||||
|
<o:OfficeDocumentSettings xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||||
|
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||||
|
</o:OfficeDocumentSettings>
|
||||||
|
</xml>
|
||||||
|
</noscript>
|
||||||
|
<style>
|
||||||
|
td,th,div,p,a,h1,h2,h3,h4,h5,h6 {font-family: "Segoe UI", sans-serif; mso-line-height-rule: exactly;}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
<title>Your access request has been approved</title>
|
||||||
|
<style>
|
||||||
|
.hover-opacity-90:hover {
|
||||||
|
opacity: 0.9 !important
|
||||||
|
}
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.sm-px-4 {
|
||||||
|
padding-left: 16px !important;
|
||||||
|
padding-right: 16px !important
|
||||||
|
}
|
||||||
|
.sm-py-12 {
|
||||||
|
padding-top: 48px !important;
|
||||||
|
padding-bottom: 48px !important
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="margin: 0; width: 100%; background-color: #faf5ff; padding: 0; -webkit-font-smoothing: antialiased; word-break: break-word">
|
||||||
|
<div style="display: none">
|
||||||
|
Workspace access request approved notification
|
||||||
|
 ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏  ͏
|
||||||
|
</div>
|
||||||
|
<div role="article" aria-roledescription="email" aria-label="Your access request has been approved" lang="en">
|
||||||
|
<div class="sm-px-4 sm-py-12" style="background-color: #faf5ff; padding: 96px 48px; font-family: Helvetica, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; color: #000">
|
||||||
|
<table align="center" cellpadding="0" cellspacing="0" role="none">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 552px; max-width: 100%">
|
||||||
|
<p style="width: 100%; white-space: normal; overflow-wrap: break-word; text-align: center; font-size: 24px">
|
||||||
|
<span>Your request to access </span>
|
||||||
|
<span style="font-size: 30px; font-weight: 700">{{ workspace_name }}</span>
|
||||||
|
<span> has been approved </span>
|
||||||
|
</p>
|
||||||
|
<div role="separator" style="background-color: #cbd5e1; height: 1px; line-height: 1px; margin: 24px 20%">‍</div>
|
||||||
|
<table align="center" cellpadding="0" cellspacing="0" role="none">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 60px">
|
||||||
|
<div style="margin-right: 8px; height: 60px; width: 60px; overflow: hidden; border-radius: 16px; background-color: #fff; border: 2px solid black">
|
||||||
|
<img src="{{ workspace_icon_url }}" width="100%" height="100%" alt="{{ workspace_name }}" style="max-width: 100%; vertical-align: middle; line-height: 1; overflow: hidden; object-fit: cover">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div style="margin-bottom: 8px; font-weight: 700">{{ workspace_name }}</div>
|
||||||
|
<div style="font-size: 14px; color: #64748b">
|
||||||
|
{{ workspace_member_count }} members
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<a href="{{ launch_workspace_url }}" class="hover-opacity-90" style="margin-top: 32px; margin-bottom: 32px; display: inline-block; width: 60%; cursor: pointer; border-radius: 16px; padding: 16px 24px; color: #f8fafc; text-decoration: none; background-color: #9327ff; font-size: 20px; font-weight: 400; line-height: 20px">
|
||||||
|
<!--[if mso]>
|
||||||
|
<i style="mso-font-width: 150%; mso-text-raise: 30px" hidden> </i>
|
||||||
|
<![endif]-->
|
||||||
|
<span style="mso-text-raise: 16px">
|
||||||
|
<div style="font-size: 24px; font-weight: 500">View workspace</div>
|
||||||
|
</span>
|
||||||
|
<!--[if mso]>
|
||||||
|
<i hidden style="mso-font-width: 150%;"> ​</i>
|
||||||
|
<![endif]-->
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div style="
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 70%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
color: #64748b;
|
||||||
|
">
|
||||||
|
By clicking "View workspace" above, you confirm that you have read,
|
||||||
|
understood, and agreed to AppFlowy's
|
||||||
|
<a href="https://appflowy.io/terms/app" style="color: #64748b">Terms & Conditions</a>
|
||||||
|
and
|
||||||
|
<a href="https://appflowy.io/privacy/app" style="color: #64748b">Privacy Policy</a>.
|
||||||
|
</div>
|
||||||
|
<div role="separator" style="background-color: #cbd5e1; height: 1px; line-height: 1px; margin: 24px 20%;">‍</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding-left: 24px; padding-right: 24px; text-align: center; font-size: 12px; color: #475569">
|
||||||
|
<p style="margin: 0 0 16px; cursor: pointer; text-transform: uppercase">
|
||||||
|
<a href="https://appflowy.io">
|
||||||
|
<img src="https://raw.githubusercontent.com/AppFlowy-IO/AppFlowy-Cloud/main/assets/mailer_templates/build_production/images/appflowy-logo.png" width="150px" style="max-width: 100%; vertical-align: middle; line-height: 1;" alt="">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p style="margin: 0; font-size: 14px; font-weight: 500; color: #000;">
|
||||||
|
Bring projects, knowledge, and teams together with the power of AI.
|
||||||
|
</p>
|
||||||
|
<p style="cursor: default">
|
||||||
|
<a href="https://twitter.com/appflowy" style="margin-right: 16px; color: #4338ca; text-decoration: none">
|
||||||
|
<img src="https://raw.githubusercontent.com/AppFlowy-IO/AppFlowy-Cloud/main/assets/mailer_templates/build_production/images/twitter.png" width="20" alt="Maizzle" style="max-width: 100%; vertical-align: middle; line-height: 1;">
|
||||||
|
</a>
|
||||||
|
<a href="https://www.reddit.com/r/AppFlowy" style="margin-right: 16px; color: #4338ca; text-decoration: none;">
|
||||||
|
<img src="https://raw.githubusercontent.com/AppFlowy-IO/AppFlowy-Cloud/main/assets/mailer_templates/build_production/images/reddit.png" width="20" alt="Maizzle" style="max-width: 100%; vertical-align: middle; line-height: 1;">
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/AppFlowy-IO/AppFlowy" style="margin-right: 16px; color: #4338ca; text-decoration: none;">
|
||||||
|
<img src="https://raw.githubusercontent.com/AppFlowy-IO/AppFlowy-Cloud/main/assets/mailer_templates/build_production/images/github.png" width="20" alt="Maizzle" style="max-width: 100%; vertical-align: middle; line-height: 1;">
|
||||||
|
</a>
|
||||||
|
<a href="https://discord.gg/9Q2xaN37tV" style="margin-right: 16px; color: #4338ca; text-decoration: none;">
|
||||||
|
<img src="https://raw.githubusercontent.com/AppFlowy-IO/AppFlowy-Cloud/main/assets/mailer_templates/build_production/images/discord.png" width="20" alt="Maizzle" style="max-width: 100%; vertical-align: middle; line-height: 1;">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -30,6 +30,7 @@ module.exports = {
|
||||||
userName: "John Doe",
|
userName: "John Doe",
|
||||||
acceptUrl: "https://appflowy.io",
|
acceptUrl: "https://appflowy.io",
|
||||||
approveUrl: "https://appflowy.io",
|
approveUrl: "https://appflowy.io",
|
||||||
|
launchWorkspaceUrl: "https://appflowy.io",
|
||||||
workspaceName: "AppFlowy",
|
workspaceName: "AppFlowy",
|
||||||
workspaceMembersCount: "100",
|
workspaceMembersCount: "100",
|
||||||
workspaceIconURL: "https://cdn-icons-png.flaticon.com/512/1078/1078013.png",
|
workspaceIconURL: "https://cdn-icons-png.flaticon.com/512/1078/1078013.png",
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ module.exports = {
|
||||||
userName: "{{ username }}",
|
userName: "{{ username }}",
|
||||||
acceptUrl: "{{ accept_url }}",
|
acceptUrl: "{{ accept_url }}",
|
||||||
approveUrl: "{{ approve_url }}",
|
approveUrl: "{{ approve_url }}",
|
||||||
|
launchWorkspaceUrl: "{{ launch_workspace_url }}",
|
||||||
workspaceName: "{{ workspace_name }}",
|
workspaceName: "{{ workspace_name }}",
|
||||||
workspaceMembersCount: "{{ workspace_member_count }}",
|
workspaceMembersCount: "{{ workspace_member_count }}",
|
||||||
workspaceIconURL: "{{ workspace_icon_url }}",
|
workspaceIconURL: "{{ workspace_icon_url }}",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
---
|
||||||
|
title: "Your access request has been approved"
|
||||||
|
preheader: "Workspace access request approved notification"
|
||||||
|
bodyClass: bg-purple-50
|
||||||
|
---
|
||||||
|
|
||||||
|
<x-main>
|
||||||
|
<div
|
||||||
|
class="bg-purple-50 font-helvetica sm:px-4 px-12 sm:py-12 py-24 text-black"
|
||||||
|
>
|
||||||
|
<table align="center">
|
||||||
|
<tr>
|
||||||
|
<td class="w-[552px] max-w-full">
|
||||||
|
<p class="w-full text-center break-words whitespace-normal text-2xl">
|
||||||
|
<span class="mx-2=1">Your request to access </span>
|
||||||
|
<span class="text-3xl font-bold">{{ workspaceName }}</span>
|
||||||
|
<span class="mx-2=1"> has been approved </span>
|
||||||
|
</p>
|
||||||
|
<x-divider space-x="20%" />
|
||||||
|
<table align="center">
|
||||||
|
<tr>
|
||||||
|
<td class="w-[60px]">
|
||||||
|
<div
|
||||||
|
style="border: 2px solid black"
|
||||||
|
class="rounded-2xl mr-2 w-[60px] h-[60px] bg-white overflow-hidden"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="{{ workspaceIconURL }}"
|
||||||
|
class="overflow-hidden object-cover"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
alt="{{ workspaceName }}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="font-bold mb-2">{{ workspaceName }}</div>
|
||||||
|
<div class="text-sm text-slate-500">
|
||||||
|
{{ workspaceMembersCount }} members
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<x-button
|
||||||
|
align="center"
|
||||||
|
class="hover:opacity-90 cursor-pointer !text-xl !leading-[20px] !bg-[#9327ff] !font-normal w-[60%] my-8 rounded-2xl"
|
||||||
|
href="{{ launchWorkspaceUrl }}"
|
||||||
|
>
|
||||||
|
<div class="font-medium text-[24px]">View workspace</div>
|
||||||
|
</x-button>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 70%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
color: #64748b;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
By clicking "View workspace" above, you confirm that you have read,
|
||||||
|
understood, and agreed to AppFlowy's
|
||||||
|
<a href="https://appflowy.io/terms/app" style="color: #64748b"
|
||||||
|
>Terms & Conditions</a
|
||||||
|
>
|
||||||
|
and
|
||||||
|
<a href="https://appflowy.io/privacy/app" style="color: #64748b"
|
||||||
|
>Privacy Policy</a
|
||||||
|
>.
|
||||||
|
</div>
|
||||||
|
<x-divider space-x="20%" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center text-slate-600 text-xs px-6">
|
||||||
|
<p class="m-0 mb-4 uppercase cursor-pointer">
|
||||||
|
<a href="https://appflowy.io">
|
||||||
|
<img
|
||||||
|
src="{{ cdnBaseUrl }}images/appflowy-logo.png"
|
||||||
|
width="150px"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p class="m-0 text-sm text-black font-medium">
|
||||||
|
Bring projects, knowledge, and teams together with the power of AI.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="cursor-default">
|
||||||
|
<a
|
||||||
|
href="https://twitter.com/appflowy"
|
||||||
|
class="text-indigo-700 [text-decoration:none] mr-4"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="{{ cdnBaseUrl }}images/twitter.png"
|
||||||
|
width="20"
|
||||||
|
alt="Maizzle"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://www.reddit.com/r/AppFlowy"
|
||||||
|
class="text-indigo-700 [text-decoration:none] mr-4"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="{{ cdnBaseUrl }}images/reddit.png"
|
||||||
|
width="20"
|
||||||
|
alt="Maizzle"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://github.com/AppFlowy-IO/AppFlowy"
|
||||||
|
class="text-indigo-700 [text-decoration:none] mr-4"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="{{ cdnBaseUrl }}images/github.png"
|
||||||
|
width="20"
|
||||||
|
alt="Maizzle"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://discord.gg/9Q2xaN37tV"
|
||||||
|
class="text-indigo-700 [text-decoration:none] mr-4"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="{{ cdnBaseUrl }}images/discord.png"
|
||||||
|
width="20"
|
||||||
|
alt="Maizzle"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</x-main>
|
||||||
|
|
@ -88,7 +88,22 @@ async fn post_approve_access_request_handler(
|
||||||
let uid = state.user_cache.get_user_uid(&uuid).await?;
|
let uid = state.user_cache.get_user_uid(&uuid).await?;
|
||||||
let access_request_id = access_request_id.into_inner();
|
let access_request_id = access_request_id.into_inner();
|
||||||
let is_approved = approve_access_request_params.is_approved;
|
let is_approved = approve_access_request_params.is_approved;
|
||||||
approve_or_reject_access_request(&state.pg_pool, access_request_id, uid, *uuid, is_approved)
|
let appflowy_web_url = state
|
||||||
.await?;
|
.config
|
||||||
|
.appflowy_web_url
|
||||||
|
.clone()
|
||||||
|
.ok_or(AppError::Internal(anyhow!(
|
||||||
|
"AppFlowy web url has not been set"
|
||||||
|
)))?;
|
||||||
|
approve_or_reject_access_request(
|
||||||
|
&state.pg_pool,
|
||||||
|
state.mailer.clone(),
|
||||||
|
&appflowy_web_url,
|
||||||
|
access_request_id,
|
||||||
|
uid,
|
||||||
|
*uuid,
|
||||||
|
is_approved,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Ok(Json(AppResponse::Ok()))
|
Ok(Json(AppResponse::Ok()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
folder_view::{to_dto_view_icon, to_view_layout},
|
folder_view::{to_dto_view_icon, to_view_layout},
|
||||||
ops::get_latest_collab_folder,
|
ops::get_latest_collab_folder,
|
||||||
},
|
},
|
||||||
mailer::{Mailer, WorkspaceAccessRequestMailerParam},
|
mailer::{Mailer, WorkspaceAccessRequestApprovedMailerParam, WorkspaceAccessRequestMailerParam},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn create_access_request(
|
pub async fn create_access_request(
|
||||||
|
|
@ -58,7 +58,7 @@ pub async fn create_access_request(
|
||||||
workspace_name: access_request.workspace.workspace_name,
|
workspace_name: access_request.workspace.workspace_name,
|
||||||
workspace_icon_url,
|
workspace_icon_url,
|
||||||
workspace_member_count: access_request.workspace.member_count.unwrap_or(0),
|
workspace_member_count: access_request.workspace.member_count.unwrap_or(0),
|
||||||
approve_url: approve_url.to_string(),
|
approve_url,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|
@ -110,6 +110,8 @@ pub async fn get_access_request(
|
||||||
|
|
||||||
pub async fn approve_or_reject_access_request(
|
pub async fn approve_or_reject_access_request(
|
||||||
pg_pool: &PgPool,
|
pg_pool: &PgPool,
|
||||||
|
mailer: Mailer,
|
||||||
|
appflowy_web_url: &str,
|
||||||
request_id: Uuid,
|
request_id: Uuid,
|
||||||
uid: i64,
|
uid: i64,
|
||||||
user_uuid: Uuid,
|
user_uuid: Uuid,
|
||||||
|
|
@ -133,6 +135,35 @@ pub async fn approve_or_reject_access_request(
|
||||||
role,
|
role,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
let cloned_mailer = mailer.clone();
|
||||||
|
let launch_workspace_url = format!(
|
||||||
|
"{}/app/{}",
|
||||||
|
appflowy_web_url, &access_request.workspace.workspace_id
|
||||||
|
);
|
||||||
|
|
||||||
|
// use default icon until we have workspace icon
|
||||||
|
let workspace_icon_url =
|
||||||
|
"https://miro.medium.com/v2/resize:fit:2400/1*mTPfm7CwU31-tLhtLNkyJw.png".to_string();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
if let Err(err) = cloned_mailer
|
||||||
|
.send_workspace_access_request_approval_notification(
|
||||||
|
&access_request.requester.name,
|
||||||
|
&access_request.requester.email,
|
||||||
|
WorkspaceAccessRequestApprovedMailerParam {
|
||||||
|
workspace_name: access_request.workspace.workspace_name,
|
||||||
|
workspace_icon_url,
|
||||||
|
workspace_member_count: access_request.workspace.member_count.unwrap_or(0),
|
||||||
|
launch_workspace_url,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
tracing::error!(
|
||||||
|
"Failed to send access request approved notification email: {:?}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
let status = if is_approved {
|
let status = if is_approved {
|
||||||
AFAccessRequestStatusColumn::Approved
|
AFAccessRequestStatusColumn::Approved
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ pub struct Mailer {
|
||||||
|
|
||||||
pub const WORKSPACE_INVITE_TEMPLATE_NAME: &str = "workspace_invite";
|
pub const WORKSPACE_INVITE_TEMPLATE_NAME: &str = "workspace_invite";
|
||||||
pub const WORKSPACE_ACCESS_REQUEST_TEMPLATE_NAME: &str = "workspace_access_request";
|
pub const WORKSPACE_ACCESS_REQUEST_TEMPLATE_NAME: &str = "workspace_access_request";
|
||||||
|
pub const WORKSPACE_ACCESS_REQUEST_APPROVED_NOTIFICATION_TEMPLATE_NAME: &str =
|
||||||
|
"workspace_access_request_approved_notification";
|
||||||
|
|
||||||
impl Mailer {
|
impl Mailer {
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
|
|
@ -39,12 +41,19 @@ impl Mailer {
|
||||||
include_str!("../assets/mailer_templates/build_production/workspace_invitation.html");
|
include_str!("../assets/mailer_templates/build_production/workspace_invitation.html");
|
||||||
let access_request_template =
|
let access_request_template =
|
||||||
include_str!("../assets/mailer_templates/build_production/access_request.html");
|
include_str!("../assets/mailer_templates/build_production/access_request.html");
|
||||||
|
let access_request_approved_notification_template = include_str!(
|
||||||
|
"../assets/mailer_templates/build_production/access_request_approved_notification.html"
|
||||||
|
);
|
||||||
let template_strings = HashMap::from([
|
let template_strings = HashMap::from([
|
||||||
(WORKSPACE_INVITE_TEMPLATE_NAME, workspace_invite_template),
|
(WORKSPACE_INVITE_TEMPLATE_NAME, workspace_invite_template),
|
||||||
(
|
(
|
||||||
WORKSPACE_ACCESS_REQUEST_TEMPLATE_NAME,
|
WORKSPACE_ACCESS_REQUEST_TEMPLATE_NAME,
|
||||||
access_request_template,
|
access_request_template,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
WORKSPACE_ACCESS_REQUEST_APPROVED_NOTIFICATION_TEMPLATE_NAME,
|
||||||
|
access_request_approved_notification_template,
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (template_name, template_string) in template_strings {
|
for (template_name, template_string) in template_strings {
|
||||||
|
|
@ -135,6 +144,24 @@ impl Mailer {
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_workspace_access_request_approval_notification(
|
||||||
|
&self,
|
||||||
|
recipient_name: &str,
|
||||||
|
email: &str,
|
||||||
|
param: WorkspaceAccessRequestApprovedMailerParam,
|
||||||
|
) -> Result<(), anyhow::Error> {
|
||||||
|
let subject = "Notification: Workspace access request approved";
|
||||||
|
self
|
||||||
|
.send_email_template(
|
||||||
|
Some(recipient_name.to_string()),
|
||||||
|
email,
|
||||||
|
WORKSPACE_ACCESS_REQUEST_APPROVED_NOTIFICATION_TEMPLATE_NAME,
|
||||||
|
param,
|
||||||
|
subject,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
|
|
@ -156,3 +183,11 @@ pub struct WorkspaceAccessRequestMailerParam {
|
||||||
pub workspace_member_count: i64,
|
pub workspace_member_count: i64,
|
||||||
pub approve_url: String,
|
pub approve_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Serialize)]
|
||||||
|
pub struct WorkspaceAccessRequestApprovedMailerParam {
|
||||||
|
pub workspace_name: String,
|
||||||
|
pub workspace_icon_url: String,
|
||||||
|
pub workspace_member_count: i64,
|
||||||
|
pub launch_workspace_url: String,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue