From 1ba1177cad3ec33a979344e1ff8424352d49a8df Mon Sep 17 00:00:00 2001 From: Hitesh Ghuge <41512916+hiteshghuge@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:08:56 +0530 Subject: [PATCH] - Handling email template issue (#1266) * - Handling email template issue for below cases * Invite * accept invite * Update role * Ownership transfer * - Handling email template issue for below cases * Invite * accept invite * Update role * Ownership transfer --------- Co-authored-by: hghuge --- kairon/api/app/routers/user.py | 26 ++++++++------ kairon/shared/account/processor.py | 6 ++-- kairon/shared/utils.py | 15 ++++---- template/emails/memberAddAccept.html | 2 +- template/emails/memberAddConfirmation.html | 2 +- tests/unit_test/utility_test.py | 40 +++++++++++++--------- 6 files changed, 54 insertions(+), 37 deletions(-) diff --git a/kairon/api/app/routers/user.py b/kairon/api/app/routers/user.py index 0423b338d..a395ad5cb 100644 --- a/kairon/api/app/routers/user.py +++ b/kairon/api/app/routers/user.py @@ -71,9 +71,11 @@ async def allow_bot_for_user( current_user.get_user(), current_user.account, allow_bot.role) if Utility.email_conf["email"]["enable"]: + accessor_name = AccountProcessor.get_user(allow_bot.email, raise_error=False) background_tasks.add_task(MailUtility.format_and_send_mail, mail_type='add_member', email=allow_bot.email, url=url, first_name=f'{current_user.first_name} {current_user.last_name}', - bot_name=bot_name, role=allow_bot.role) + bot_name=bot_name, role=allow_bot.role.value, + accessor_name=f"{accessor_name.get('first_name')} {accessor_name.get('last_name')}") return Response(message='An invitation has been sent to the user') else: return {"message": "User added"} @@ -88,11 +90,12 @@ async def accept_bot_collaboration_invite_with_token_validation( Accepts a bot collaboration invitation sent via mail. """ bot_admin, bot_name, accessor_email, role = AccountProcessor.validate_request_and_accept_bot_access_invite(token.data, bot) - user = AccountProcessor.get_user(bot_admin) + accessor_name = AccountProcessor.get_user(accessor_email, raise_error=False) + first_name = AccountProcessor.get_user(bot_admin, raise_error=False).get("first_name") if Utility.email_conf["email"]["enable"]: background_tasks.add_task(MailUtility.format_and_send_mail, mail_type='add_member_confirmation', email=bot_admin, - first_name=bot_admin, accessor_email=accessor_email, - bot_name=bot_name, role=role, member_confirm=user['first_name']) + first_name=first_name, accessor_email=accessor_email, + bot_name=bot_name, role=role, accessor_name=f"{accessor_name.get('first_name')} {accessor_name.get('last_name')}") return {"message": "Invitation accepted"} @@ -106,9 +109,11 @@ async def accept_bot_collaboration_invite( Accepts a bot collaboration invitation for logged in user. """ bot_admin, bot_name, accessor_email, role = AccountProcessor.accept_bot_access_invite(bot, current_user.get_user()) + accessor_name = AccountProcessor.get_user(accessor_email, raise_error=False).get("first_name") + first_name = AccountProcessor.get_user(bot_admin, raise_error=False).get("first_name") if Utility.email_conf["email"]["enable"]: background_tasks.add_task(MailUtility.format_and_send_mail, mail_type='add_member_confirmation', email=bot_admin, - first_name=bot_admin, accessor_email=accessor_email, + first_name=first_name, accessor_email=accessor_email, accessor_name=accessor_name, bot_name=bot_name, role=role) return {"message": "Invitation accepted"} @@ -127,9 +132,9 @@ async def update_bot_access_for_user( ) if Utility.email_conf["email"]["enable"]: background_tasks.add_task(MailUtility.format_and_send_mail, mail_type='update_role_member_mail', - email=allow_bot.email, first_name=f'{current_user.first_name} {current_user.last_name}', + email=allow_bot.email, first_name=member_name, bot_name=bot_name, new_role=allow_bot.role, status=allow_bot.activity_status, - member_name=member_name) + member_name=member_name, modifier_name=f'{current_user.first_name} {current_user.last_name}') background_tasks.add_task(MailUtility.format_and_send_mail, mail_type='update_role_owner_mail', email=owner_email, member_email=allow_bot.email, bot_name=bot_name, new_role=allow_bot.role, first_name=f'{current_user.first_name} {current_user.last_name}', @@ -147,13 +152,14 @@ async def transfer_ownership( Transfers ownership to provided user. """ bot_name = AccountProcessor.transfer_ownership(current_user.account, bot, current_user.get_user(), request_data.data) + accessor_name = AccountProcessor.get_user(request_data.data, raise_error=False) if Utility.email_conf["email"]["enable"]: background_tasks.add_task(MailUtility.format_and_send_mail, mail_type='update_role_member_mail', email=request_data.data, bot_name=bot_name, new_role=ACCESS_ROLES.OWNER.value, - first_name=f'{current_user.first_name} {current_user.last_name}', - status=ACTIVITY_STATUS.ACTIVE.value) + first_name=f"{accessor_name.get('first_name')} {accessor_name.get('last_name')}", + status=ACTIVITY_STATUS.ACTIVE.value, modifier_name=f'{current_user.first_name} {current_user.last_name}') background_tasks.add_task(MailUtility.format_and_send_mail, mail_type='transfer_ownership_mail', - email=current_user.get_user(), member_email=current_user.get_user(), + email=current_user.get_user(), new_owner_mail=request_data.data, bot_name=bot_name, new_role=ACCESS_ROLES.OWNER.value, first_name=f'{current_user.first_name} {current_user.last_name}') return Response(message='Ownership transferred') diff --git a/kairon/shared/account/processor.py b/kairon/shared/account/processor.py index beed3ac87..ebf6fa9f8 100644 --- a/kairon/shared/account/processor.py +++ b/kairon/shared/account/processor.py @@ -708,12 +708,13 @@ def add_user( ) @staticmethod - def get_user(email: str, is_login_request: bool = False): + def get_user(email: str, is_login_request: bool = False, raise_error: bool = True): """ fetch user details :param email: user login id :param is_login_request: logs invalid logins if true + :param raise_error: logs raise error saying **User does not exist!** if true :return: user details """ try: @@ -729,7 +730,8 @@ def get_user(email: str, is_login_request: bool = False): UserActivityLogger.add_log( a_type=UserActivityType.invalid_login.value, email=email, data={"username": email} ) - raise DoesNotExist("User does not exist!") + if raise_error: + raise DoesNotExist("User does not exist!") @staticmethod def get_user_details(email: str, is_login_request: bool = False): diff --git a/kairon/shared/utils.py b/kairon/shared/utils.py index 24a6eaa58..625ebad88 100644 --- a/kairon/shared/utils.py +++ b/kairon/shared/utils.py @@ -2586,6 +2586,7 @@ def __handle_add_member(**kwargs): first_name = kwargs.get("first_name") url = kwargs.get("url") body = Utility.email_conf["email"]["templates"]["add_member_invitation"] + body = body.replace("INVITED_PERSON_NAME", kwargs.get("accessor_name", "buddy")) body = body.replace("BOT_NAME", kwargs.get("bot_name", "")) body = body.replace("BOT_OWNER_NAME", first_name.capitalize()) body = body.replace("ACCESS_TYPE", kwargs.get("role", "")) @@ -2599,13 +2600,12 @@ def __handle_add_member_confirmation(**kwargs): body = Utility.email_conf["email"]["templates"]["add_member_confirmation"] body = body.replace("BOT_NAME", kwargs.get("bot_name", "")) body = body.replace("ACCESS_TYPE", kwargs.get("role", "")) - body = body.replace("INVITED_PERSON_NAME", kwargs.get("accessor_email", "")) - body = body.replace("NAME", kwargs.get("member_confirm", "").capitalize()) + body = body.replace("INVITED_PERSON_NAME", kwargs.get("accessor_name", "").capitalize()) subject = Utility.email_conf["email"]["templates"][ "add_member_confirmation_subject" ] subject = subject.replace( - "INVITED_PERSON_NAME", kwargs.get("accessor_email", "") + "INVITED_PERSON_NAME", kwargs.get("accessor_name", "").capitalize() ) return body, subject @@ -2620,8 +2620,9 @@ def __handle_update_role_member_mail(**kwargs): body = body.replace("BOT_NAME", kwargs.get("bot_name", "")) body = body.replace("NEW_ROLE", kwargs.get("new_role", "")) body = body.replace("STATUS", kwargs.get("status", "")) - body = body.replace("MODIFIER_NAME", first_name.capitalize()) - body = body.replace("NAME", kwargs.get("member_name", "").capitalize()) + body = body.replace("ACCESS_TYPE", kwargs.get("new_role", "")) + body = body.replace("MODIFIER_NAME", kwargs.get("modifier_name", "").capitalize()) + body = body.replace("FIRST_NAME", first_name.capitalize()) subject = Utility.email_conf["email"]["templates"]["update_role_subject"] subject = subject.replace("BOT_NAME", kwargs.get("bot_name", "")) return body, subject @@ -2639,7 +2640,7 @@ def __handle_update_role_owner_mail(**kwargs): body = body.replace("NEW_ROLE", kwargs.get("new_role", "")) body = body.replace("STATUS", kwargs.get("status", "")) body = body.replace("MODIFIER_NAME", first_name.capitalize()) - body = body.replace("NAME", kwargs.get("owner_name", "").capitalize()) + body = body.replace("FIRST_NAME", kwargs.get("owner_name", "").capitalize()) subject = Utility.email_conf["email"]["templates"]["update_role_subject"] subject = subject.replace("BOT_NAME", kwargs.get("bot_name", "")) return body, subject @@ -2652,7 +2653,7 @@ def __handle_transfer_ownership_mail(**kwargs): "MAIL_BODY_HERE", Utility.email_conf["email"]["templates"]["transfer_ownership_mail_body"], ) - body = body.replace("MEMBER_EMAIL", kwargs.get("member_email", "")) + body = body.replace("MEMBER_EMAIL", kwargs.get("new_owner_mail", "")) body = body.replace("BOT_NAME", kwargs.get("bot_name", "")) body = body.replace("NEW_ROLE", kwargs.get("new_role", "")) body = body.replace("MODIFIER_NAME", first_name.capitalize()) diff --git a/template/emails/memberAddAccept.html b/template/emails/memberAddAccept.html index c7f03a46f..5da56b65e 100644 --- a/template/emails/memberAddAccept.html +++ b/template/emails/memberAddAccept.html @@ -147,7 +147,7 @@

font-size: 15px; padding: 16px 0; "> -

Hi FIRST_NAME,

+

Hi INVITED_PERSON_NAME,

You have been invited to collaborate on BOT_NAME bot by BOT_OWNER_NAME. Please click the link below to accept the invitation and sign in using USER_EMAIL to access newly diff --git a/template/emails/memberAddConfirmation.html b/template/emails/memberAddConfirmation.html index bb509d81f..4803b5fa4 100644 --- a/template/emails/memberAddConfirmation.html +++ b/template/emails/memberAddConfirmation.html @@ -147,7 +147,7 @@

font-size: 15px; padding: 16px 0; "> -

Hi,

+

Hi FIRST_NAME,

INVITED_PERSON_NAME has accepted the invite to collaborate on your bot BOT_NAME as a ACCESS_TYPE. diff --git a/tests/unit_test/utility_test.py b/tests/unit_test/utility_test.py index 92632d148..5910f13bb 100644 --- a/tests/unit_test/utility_test.py +++ b/tests/unit_test/utility_test.py @@ -851,6 +851,7 @@ async def test_handle_add_member(self, validate_and_send_mail_mock): url = "https://www.testurl.com" bot_name = "test_bot" role = "test_role" + accessor_name = "buddy" base_url = Utility.environment["app"]["frontend_url"] Utility.email_conf["email"]["templates"]["add_member_invitation"] = ( open("template/emails/memberAddAccept.html", "rb").read().decode() @@ -867,6 +868,7 @@ async def test_handle_add_member(self, validate_and_send_mail_mock): .replace("USER_EMAIL", email) .replace("VERIFICATION_LINK", url) .replace("BASE_URL", base_url) + .replace("INVITED_PERSON_NAME", accessor_name) ) expected_subject = Utility.email_conf["email"]["templates"][ "add_member_subject" @@ -890,7 +892,7 @@ async def test_handle_add_member(self, validate_and_send_mail_mock): async def test_handle_add_member_confirmation(self, validate_and_send_mail_mock): mail_type = "add_member_confirmation" email = "sampletest@gmail.com" - first_name = "sample" + accessor_name = "sample" bot_name = "test_bot" role = "test_role" accessor_email = "test@gmail.com" @@ -905,9 +907,8 @@ async def test_handle_add_member_confirmation(self, validate_and_send_mail_mock) expected_body = ( expected_body.replace("BOT_NAME", bot_name) .replace("ACCESS_TYPE", role) - .replace("INVITED_PERSON_NAME", accessor_email) - .replace("NAME", member_confirm.capitalize()) - .replace("FIRST_NAME", first_name) + .replace("INVITED_PERSON_NAME", accessor_name.capitalize()) + .replace("FIRST_NAME", member_confirm) .replace("USER_EMAIL", email) .replace("BASE_URL", base_url) ) @@ -915,17 +916,18 @@ async def test_handle_add_member_confirmation(self, validate_and_send_mail_mock) "add_member_confirmation_subject" ] expected_subject = expected_subject.replace( - "INVITED_PERSON_NAME", accessor_email + "INVITED_PERSON_NAME", accessor_name.capitalize() ) await MailUtility.format_and_send_mail( mail_type=mail_type, email=email, - first_name=first_name, bot_name=bot_name, role=role, + first_name=member_confirm, accessor_email=accessor_email, member_confirm=member_confirm, + accessor_name=accessor_name ) validate_and_send_mail_mock.assert_called_once_with( email, expected_subject, expected_body @@ -940,6 +942,7 @@ async def test_handle_update_role_member_mail(self, validate_and_send_mail_mock) bot_name = "test_bot" new_role = "test_role" status = "test_status" + modifier_name = "test_name" member_name = "test_name" base_url = Utility.environment["app"]["frontend_url"] Utility.email_conf["email"]["templates"]["update_role"] = ( @@ -956,11 +959,11 @@ async def test_handle_update_role_member_mail(self, validate_and_send_mail_mock) .replace("BOT_NAME", bot_name) .replace("NEW_ROLE", new_role) .replace("STATUS", status) - .replace("MODIFIER_NAME", first_name.capitalize()) - .replace("NAME", member_name.capitalize()) - .replace("FIRST_NAME", first_name) + .replace("MODIFIER_NAME", modifier_name.capitalize()) + .replace("FIRST_NAME", first_name.capitalize()) .replace("USER_EMAIL", email) .replace("BASE_URL", base_url) + .replace("ACCESS_TYPE", new_role) ) expected_subject = Utility.email_conf["email"]["templates"][ "update_role_subject" @@ -975,6 +978,7 @@ async def test_handle_update_role_member_mail(self, validate_and_send_mail_mock) bot_name=bot_name, new_role=new_role, member_name=member_name, + modifier_name=modifier_name ) validate_and_send_mail_mock.assert_called_once_with( email, expected_subject, expected_body @@ -1006,7 +1010,7 @@ async def test_handle_update_role_owner_mail(self, validate_and_send_mail_mock): .replace("NEW_ROLE", new_role) .replace("STATUS", status) .replace("MODIFIER_NAME", first_name.capitalize()) - .replace("NAME", owner_name.capitalize()) + .replace("FIRST_NAME", owner_name.capitalize()) .replace("FIRST_NAME", first_name) .replace("USER_EMAIL", email) .replace("BASE_URL", base_url) @@ -1071,6 +1075,7 @@ async def test_handle_transfer_ownership_mail(self, validate_and_send_mail_mock) bot_name=bot_name, new_role=new_role, member_email=member_email, + new_owner_mail=member_email ) validate_and_send_mail_mock.assert_called_once_with( email, expected_subject, expected_body @@ -3875,6 +3880,7 @@ async def test_handle_first_name_add_member_email_template(self, validate_and_se access_url = "http://localhost:3000" bot_owner_name = "Sample" accessor_email = "test@gmail.com" + accessor_name = "buddy" member_confirm = "test_name" base_url = Utility.environment["app"]["frontend_url"] Utility.email_conf["email"]["templates"]["add_member"] = ( @@ -3891,6 +3897,7 @@ async def test_handle_first_name_add_member_email_template(self, validate_and_se .replace("BASE_URL", base_url) .replace("ACCESS_URL", access_url) .replace("BOT_OWNER_NAME", bot_owner_name) + .replace("INVITED_PERSON_NAME", accessor_name) ) expected_subject = Utility.email_conf["email"]["templates"][ "add_member_subject" @@ -3918,12 +3925,13 @@ async def test_handle_first_name_add_member_email_template(self, validate_and_se async def test_handle_first_name_member_update_email_template(self, validate_and_send_mail_mock): mail_type = "update_role_member_mail" email = "sampletest@gmail.com" - first_name = "FIRST_" + first_name = "sample" bot_name = "test_bot" new_role = "test_role" status = "test_status" - owner_name = "BOT_OWNER_" member_email = "test@gmail.com" + modifier_name = "test_name" + base_url = Utility.environment["app"]["frontend_url"] Utility.email_conf["email"]["templates"]["update_role_member_mail"] = ( open("template/emails/memberUpdateRole.html", "rb").read().decode() @@ -3937,12 +3945,12 @@ async def test_handle_first_name_member_update_email_template(self, validate_and .replace("MEMBER_EMAIL", member_email) .replace("BOT_NAME", bot_name) .replace("NEW_ROLE", new_role) + .replace("ACCESS_TYPE", new_role) .replace("STATUS", status) - .replace("MODIFIER_NAME", first_name.capitalize()) - .replace("FIRST_NAME", first_name) + .replace("MODIFIER_NAME", modifier_name.capitalize()) + .replace("FIRST_NAME", first_name.capitalize()) .replace("USER_EMAIL", email) .replace("BASE_URL", base_url) - .replace("BOT_OWNER_NAME", owner_name) ) expected_subject = Utility.email_conf["email"]["templates"][ @@ -3956,9 +3964,9 @@ async def test_handle_first_name_member_update_email_template(self, validate_and status=status, bot_name=bot_name, new_role=new_role, - owner_name=owner_name, member_email=member_email, base_url=base_url, + modifier_name=modifier_name ) validate_and_send_mail_mock.assert_called_once_with( email, expected_subject, expected_body