mirror of
https://github.com/chatwoot/chatwoot.git
synced 2026-06-04 21:02:35 +08:00
Stop the onboarding flow from writing the user's company website into `accounts.domain`. That column is reserved for the inbound email domain used to construct reply-to addresses (`reply+<uuid>@<domain>`), and silently overloading it from onboarding was breaking email continuity for accounts whose domain MX didn't point at Chatwoot's inbound — customer replies were going to an unreachable address. The website value now lives in `custom_attributes.website`, which is what the rest of the app already treats as the "company website" field.
76 lines
2.1 KiB
Ruby
76 lines
2.1 KiB
Ruby
class Onboarding::WebWidgetCreationService
|
|
DEFAULT_WIDGET_COLOR = '#1f93ff'.freeze
|
|
# context.dev descriptions and LLM completions are unbounded; bound the
|
|
# stored tagline so a long string doesn't render as a wall of text in the
|
|
# widget UI (and so backends that enforce varchar limits don't raise).
|
|
WELCOME_TAGLINE_MAX_LENGTH = 255
|
|
|
|
def initialize(account, user)
|
|
@account = account
|
|
@user = user
|
|
end
|
|
|
|
def perform
|
|
existing = existing_web_widget_inbox
|
|
if existing
|
|
Rails.logger.info "[WidgetCreation] Reusing existing web widget inbox #{existing.id} for account #{@account.id}"
|
|
return existing
|
|
end
|
|
|
|
if website_url.blank?
|
|
Rails.logger.info "[WidgetCreation] Skipping for account #{@account.id}: no website_url available"
|
|
return nil
|
|
end
|
|
|
|
attrs = channel_attributes
|
|
|
|
ActiveRecord::Base.transaction do
|
|
channel = @account.web_widgets.create!(attrs)
|
|
inbox = @account.inboxes.create!(name: @account.name, channel: channel)
|
|
InboxMember.find_or_create_by!(inbox: inbox, user: @user)
|
|
inbox
|
|
end
|
|
rescue StandardError => e
|
|
Rails.logger.error "[WidgetCreation] #{e.message}"
|
|
nil
|
|
end
|
|
|
|
private
|
|
|
|
def existing_web_widget_inbox
|
|
@account.inboxes.find_by(channel_type: 'Channel::WebWidget')
|
|
end
|
|
|
|
def channel_attributes
|
|
{
|
|
website_url: website_url,
|
|
widget_color: widget_color,
|
|
welcome_title: welcome_title,
|
|
welcome_tagline: welcome_tagline_text&.truncate(WELCOME_TAGLINE_MAX_LENGTH)
|
|
}
|
|
end
|
|
|
|
def brand_info
|
|
@brand_info ||= (@account.custom_attributes['brand_info'] || {}).deep_symbolize_keys
|
|
end
|
|
|
|
def website_url
|
|
@account.custom_attributes['website'].presence || brand_info[:domain].presence
|
|
end
|
|
|
|
def widget_color
|
|
hex = brand_info[:colors]&.first&.dig(:hex)
|
|
hex.to_s.match?(/\A#\h{6}\z/) ? hex : DEFAULT_WIDGET_COLOR
|
|
end
|
|
|
|
def welcome_title
|
|
brand_info[:title].presence || @account.name
|
|
end
|
|
|
|
def welcome_tagline_text
|
|
brand_info[:slogan].presence || brand_info[:description].presence
|
|
end
|
|
end
|
|
|
|
Onboarding::WebWidgetCreationService.prepend_mod_with('Onboarding::WebWidgetCreationService')
|