Skip to content

Commit

Permalink
feat(dashboard_metadata): Add email alert for Prod Intent (juspay#3482)
Browse files Browse the repository at this point in the history
Co-authored-by: Mani Chandra Dulam <[email protected]>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 31, 2024
1 parent 90a2462 commit 94cd7b6
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 6 deletions.
1 change: 1 addition & 0 deletions crates/router/src/consts/user.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub const MAX_NAME_LENGTH: usize = 70;
pub const MAX_COMPANY_NAME_LENGTH: usize = 70;
pub const BUSINESS_EMAIL: &str = "[email protected]";
24 changes: 22 additions & 2 deletions crates/router/src/core/user/dashboard_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use diesel_models::{
enums::DashboardMetadata as DBEnum, user::dashboard_metadata::DashboardMetadata,
};
use error_stack::ResultExt;
#[cfg(feature = "email")]
use router_env::logger;

#[cfg(feature = "email")]
use crate::services::email::types as email_types;
use crate::{
core::errors::{UserErrors, UserResponse, UserResult},
routes::AppState,
Expand Down Expand Up @@ -434,15 +438,31 @@ async fn insert_metadata(
if utils::is_update_required(&metadata) {
metadata = utils::update_user_scoped_metadata(
state,
user.user_id,
user.user_id.clone(),
user.merchant_id,
user.org_id,
metadata_key,
data,
data.clone(),
)
.await
.change_context(UserErrors::InternalServerError);
}

#[cfg(feature = "email")]
{
if utils::is_prod_email_required(&data) {
let email_contents = email_types::BizEmailProd::new(state, data)?;
let send_email_result = state
.email_client
.compose_and_send_email(
Box::new(email_contents),
state.conf.proxy.https_url.as_ref(),
)
.await;
logger::info!(?send_email_result);
}
}

metadata
}
types::MetaData::SPTestPayment(data) => {
Expand Down
138 changes: 138 additions & 0 deletions crates/router/src/services/email/assets/bizemailprod.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>Welcome to HyperSwitch!</title>
<body style="background-color: #ececec">
<div
id="wrapper"
style="
background-color: none;
margin: 0 auto;
text-align: center;
width: 90%;
-premailer-height: 200;
"
>
<table
align="center"
class="main-table"
style="
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #fff;
border: 0;
border-top: 5px solid #0165ef;
margin: 0 auto;
mso-table-lspace: 0;
mso-table-rspace: 0;
padding: 0 40;
text-align: center;
width: 100%;
"
bgcolor="#ffffff"
cellpadding="0"
cellspacing="0"
>
<tr>
<td
class="spacer-sm"
style="
-premailer-height: 20;
-premailer-width: 80%;
line-height: 10px;
margin: 0 auto;
padding: 0;
"
width="100%"
></td>
</tr>
<tr>
<td
class="spacer-sm"
style="
-premailer-height: 20;
-premailer-width: 80%;
line-height: 10px;
margin: 0 auto;
padding: 0;
"
width="100%"
></td>
</tr>
<tr>
<td
class="copy"
style="
color: #666;
font-family: Roboto, Helvetica, Arial, san-serif;
font-size: 14px;
text-align: left;
line-height: 20px;
margin-top: 20px;
padding: 15px;
"
>
<br />
<p>Hi Team,</p>
<p>
A Production Account Intent has been initiated by {username} -
please find more details below:
</p>
<ol>
<li><strong>Name:</strong> {username}</li>
<li><strong>Point of Contact Email (POC):</strong> {poc_email}</li>
<li><strong>Legal Business Name:</strong> {legal_business_name}</li>
<li><strong>Business Location:</strong> {business_location}</li>
<li><strong>Business Website:</strong> {business_website}</li>
</ol>
<br />
</td>
</tr>
<tr>
<td
class="spacer-sm"
style="
-premailer-height: 20;
-premailer-width: 80%;
line-height: 10px;
margin: 0 auto;
padding: 0;
"
width="100%"
></td>
</tr>

<tr>
<td
class="headline"
style="
color: #444;
font-family: Roboto, Helvetica, Arial, san-serif;
font-size: 18px;
font-weight: 100;
line-height: 36px;
margin: 0 auto;
padding: 0;
text-align: center;
"
align="center"
>
Regards,<br />
Hyperswitch Dashboard Team
</td>
</tr>
<tr>
<td
class="spacer-lg"
style="
-premailer-height: 75;
-premailer-width: 100%;
line-height: 30px;
margin: 0 auto;
padding: 0;
"
height="75"
width="100%"
></td>
</tr>
</table>
</div>
</body>
84 changes: 81 additions & 3 deletions crates/router/src/services/email/types.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use api_models::user::dashboard_metadata::ProdIntent;
use common_utils::errors::CustomResult;
use error_stack::ResultExt;
use external_services::email::{EmailContents, EmailData, EmailError};
use masking::{ExposeInterface, PeekInterface};
use masking::{ExposeInterface, PeekInterface, Secret};

use crate::{configs, consts};
use crate::{configs, consts, routes::AppState};
#[cfg(feature = "olap")]
use crate::{core::errors::UserErrors, services::jwt, types::domain};
use crate::{
core::errors::{UserErrors, UserResult},
services::jwt,
types::domain,
};

pub enum EmailBody {
Verify {
Expand All @@ -23,6 +28,13 @@ pub enum EmailBody {
link: String,
user_name: String,
},
BizEmailProd {
user_name: String,
poc_email: String,
legal_business_name: String,
business_location: String,
business_website: String,
},
ReconActivation {
user_name: String,
},
Expand Down Expand Up @@ -69,6 +81,22 @@ pub mod html {
username = user_name,
)
}
EmailBody::BizEmailProd {
user_name,
poc_email,
legal_business_name,
business_location,
business_website,
} => {
format!(
include_str!("assets/bizemailprod.html"),
poc_email = poc_email,
legal_business_name = legal_business_name,
business_location = business_location,
business_website = business_website,
username = user_name,
)
}
EmailBody::ProFeatureRequest {
feature_name,
merchant_id,
Expand Down Expand Up @@ -275,6 +303,56 @@ impl EmailData for ReconActivation {
}
}

pub struct BizEmailProd {
pub recipient_email: domain::UserEmail,
pub user_name: Secret<String>,
pub poc_email: Secret<String>,
pub legal_business_name: String,
pub business_location: String,
pub business_website: String,
pub settings: std::sync::Arc<configs::settings::Settings>,
pub subject: &'static str,
}

impl BizEmailProd {
pub fn new(state: &AppState, data: ProdIntent) -> UserResult<Self> {
Ok(Self {
recipient_email: (domain::UserEmail::new(
consts::user::BUSINESS_EMAIL.to_string().into(),
))?,
settings: state.conf.clone(),
subject: "New Prod Intent",
user_name: data.poc_name.unwrap_or_default().into(),
poc_email: data.poc_email.unwrap_or_default().into(),
legal_business_name: data.legal_business_name.unwrap_or_default(),
business_location: data
.business_location
.unwrap_or(common_enums::CountryAlpha2::AD)
.to_string(),
business_website: data.business_website.unwrap_or_default(),
})
}
}

#[async_trait::async_trait]
impl EmailData for BizEmailProd {
async fn get_email_data(&self) -> CustomResult<EmailContents, EmailError> {
let body = html::get_html_body(EmailBody::BizEmailProd {
user_name: self.user_name.clone().expose(),
poc_email: self.poc_email.clone().expose(),
legal_business_name: self.legal_business_name.clone(),
business_location: self.business_location.clone(),
business_website: self.business_website.clone(),
});

Ok(EmailContents {
subject: self.subject.to_string(),
body: external_services::email::IntermediateString::new(body),
recipient: self.recipient_email.clone().into_inner(),
})
}
}

pub struct ProFeatureRequest {
pub recipient_email: domain::UserEmail,
pub feature_name: String,
Expand Down
9 changes: 8 additions & 1 deletion crates/router/src/utils/user/dashboard_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{net::IpAddr, str::FromStr};

use actix_web::http::header::HeaderMap;
use api_models::user::dashboard_metadata::{
GetMetaDataRequest, GetMultipleMetaDataPayload, SetMetaDataRequest,
GetMetaDataRequest, GetMultipleMetaDataPayload, ProdIntent, SetMetaDataRequest,
};
use diesel_models::{
enums::DashboardMetadata as DBEnum,
Expand Down Expand Up @@ -276,3 +276,10 @@ pub fn parse_string_to_enums(query: String) -> UserResult<GetMultipleMetaDataPay
.attach_printable("Error Parsing to DashboardMetadata enums")?,
})
}

pub fn is_prod_email_required(data: &ProdIntent) -> bool {
!(data
.poc_email
.as_ref()
.map_or(true, |mail| mail.contains("juspay")))
}

0 comments on commit 94cd7b6

Please sign in to comment.