feat(cloud): Add support for viewing status of SSL in custom domains (#12011)

# Pull Request Template

## Description

Fixes
[CW-4620](https://linear.app/chatwoot/issue/CW-4620/rethinking-custom-domains-in-chatwoot)

<img width="642" height="187" alt="Screenshot 2025-07-29 at 8 17 44 PM"
src="https://github.com/user-attachments/assets/ad2f5dac-4b27-4dce-93ca-6cbba74443fb"
/>


## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?



## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
Co-authored-by: Pranav <pranavrajs@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
Sivin Varghese
2025-07-30 23:22:47 +05:30
committed by GitHub
parent 97f1825a14
commit d9900e50a0
31 changed files with 874 additions and 106 deletions

View File

@@ -0,0 +1,41 @@
class PortalInstructionsMailer < ApplicationMailer
def send_cname_instructions(portal:, recipient_email:)
return unless smtp_config_set_or_development?
return if target_domain.blank?
@portal = portal
@cname_record = generate_cname_record
send_mail_with_liquid(
to: recipient_email,
subject: I18n.t('portals.send_instructions.subject', custom_domain: @portal.custom_domain)
)
end
private
def liquid_locals
{ cname_record: @cname_record }
end
def generate_cname_record
"#{@portal.custom_domain} CNAME #{target_domain}"
end
def target_domain
helpcenter_url = ENV.fetch('HELPCENTER_URL', '')
frontend_url = ENV.fetch('FRONTEND_URL', '')
return extract_hostname(helpcenter_url) if helpcenter_url.present?
return extract_hostname(frontend_url) if frontend_url.present?
''
end
def extract_hostname(url)
uri = URI.parse(url)
uri.host
rescue URI::InvalidURIError
url.gsub(%r{https?://}, '').split('/').first
end
end