mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
feat(dashboard_metadata): Add email alert for Prod Intent (#3482)
Co-authored-by: Mani Chandra Dulam <mani.dchandra@juspay.in> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
90a24625ce
commit
94cd7b6897
@ -1,2 +1,3 @@
|
||||
pub const MAX_NAME_LENGTH: usize = 70;
|
||||
pub const MAX_COMPANY_NAME_LENGTH: usize = 70;
|
||||
pub const BUSINESS_EMAIL: &str = "biz@hyperswitch.io";
|
||||
|
||||
@ -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,
|
||||
@ -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) => {
|
||||
|
||||
138
crates/router/src/services/email/assets/bizemailprod.html
Normal file
138
crates/router/src/services/email/assets/bizemailprod.html
Normal file
@ -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>
|
||||
@ -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 {
|
||||
@ -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,
|
||||
},
|
||||
@ -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,
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
@ -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")))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user