135 lines
5.3 KiB
Ruby
135 lines
5.3 KiB
Ruby
class SuperAdmin::AppConfigsController < SuperAdmin::ApplicationController
|
|
before_action :set_config
|
|
before_action :allowed_configs
|
|
def show
|
|
# ref: https://github.com/rubocop/rubocop/issues/7767
|
|
# rubocop:disable Style/HashTransformValues
|
|
@app_config = InstallationConfig.where(name: @allowed_configs)
|
|
.pluck(:name, :serialized_value)
|
|
.map { |name, serialized_value| [name, serialized_value['value']] }
|
|
.to_h
|
|
# rubocop:enable Style/HashTransformValues
|
|
@installation_configs = ConfigLoader.new.general_configs.each_with_object({}) do |config_hash, result|
|
|
result[config_hash['name']] = config_hash.except('name')
|
|
end
|
|
populate_captain_config_metadata if @config == 'captain'
|
|
end
|
|
|
|
def create
|
|
errors = []
|
|
params['app_config'].each do |key, value|
|
|
next unless @allowed_configs.include?(key)
|
|
|
|
i = InstallationConfig.where(name: key).first_or_create(value: value, locked: false)
|
|
i.value = app_config_value(key, value)
|
|
errors.concat(i.errors.full_messages) unless i.save
|
|
end
|
|
|
|
if errors.any?
|
|
redirect_to super_admin_app_config_path(config: @config), alert: errors.join(', ')
|
|
else
|
|
redirect_to super_admin_settings_path, flash: success_flash
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def set_config
|
|
@config = params[:config] || 'general'
|
|
end
|
|
|
|
def allowed_configs
|
|
mapping = {
|
|
'facebook' => %w[FB_APP_ID FB_VERIFY_TOKEN FB_APP_SECRET IG_VERIFY_TOKEN FACEBOOK_API_VERSION ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT],
|
|
'shopify' => %w[SHOPIFY_CLIENT_ID SHOPIFY_CLIENT_SECRET],
|
|
'microsoft' => %w[AZURE_APP_ID AZURE_APP_SECRET],
|
|
'email' => %w[MAILER_INBOUND_EMAIL_DOMAIN ACCOUNT_EMAILS_LIMIT ACCOUNT_EMAILS_PLAN_LIMITS],
|
|
'linear' => %w[LINEAR_CLIENT_ID LINEAR_CLIENT_SECRET],
|
|
'slack' => %w[SLACK_CLIENT_ID SLACK_CLIENT_SECRET],
|
|
'instagram' => %w[INSTAGRAM_APP_ID INSTAGRAM_APP_SECRET INSTAGRAM_VERIFY_TOKEN INSTAGRAM_API_VERSION ENABLE_INSTAGRAM_CHANNEL_HUMAN_AGENT],
|
|
'tiktok' => %w[TIKTOK_APP_ID TIKTOK_APP_SECRET TIKTOK_API_VERSION],
|
|
'whatsapp_embedded' => %w[WHATSAPP_APP_ID WHATSAPP_APP_SECRET WHATSAPP_CONFIGURATION_ID WHATSAPP_API_VERSION],
|
|
'notion' => %w[NOTION_CLIENT_ID NOTION_CLIENT_SECRET],
|
|
'google' => %w[GOOGLE_OAUTH_CLIENT_ID GOOGLE_OAUTH_CLIENT_SECRET GOOGLE_OAUTH_REDIRECT_URI ENABLE_GOOGLE_OAUTH_LOGIN],
|
|
'captain' => captain_config_options
|
|
}
|
|
|
|
@allowed_configs = mapping.fetch(
|
|
@config,
|
|
%w[ENABLE_ACCOUNT_SIGNUP FIREBASE_PROJECT_ID FIREBASE_CREDENTIALS WEBHOOK_TIMEOUT MAXIMUM_FILE_UPLOAD_SIZE WIDGET_TOKEN_EXPIRY]
|
|
)
|
|
end
|
|
|
|
def success_notice
|
|
message = "#{@config.titleize} settings updated successfully"
|
|
return message unless restart_required_config_saved?
|
|
|
|
"#{message.delete_suffix('.')}. Restart Chatwoot web and worker processes to apply this change everywhere."
|
|
end
|
|
|
|
def success_flash
|
|
restart_required_config_saved? ? { success: success_notice } : { notice: success_notice }
|
|
end
|
|
|
|
def restart_required_config_saved?
|
|
saved_keys = params.fetch('app_config', {}).keys
|
|
saved_keys.intersect?(InstallationConfig::RESTART_REQUIRED_CONFIG_KEYS) ||
|
|
saved_keys.intersect?(Llm::Config.provider_config_keys(captain_provider))
|
|
end
|
|
|
|
def captain_config_options
|
|
Llm::Config.provider_config_keys(captain_provider)
|
|
end
|
|
|
|
def populate_captain_config_metadata
|
|
@app_config[Llm::ProviderConfig::PROVIDER_CONFIG_KEY] = captain_provider
|
|
|
|
populate_provider_metadata
|
|
populate_model_metadata
|
|
populate_provider_field_metadata
|
|
end
|
|
|
|
def populate_provider_metadata
|
|
@installation_configs[Llm::ProviderConfig::PROVIDER_CONFIG_KEY] = {
|
|
'display_title' => 'LLM Provider',
|
|
'description' => 'Provider used by Captain AI for chat and generation features.',
|
|
'type' => 'select',
|
|
'options' => Llm::Config.provider_options
|
|
}
|
|
end
|
|
|
|
def populate_model_metadata
|
|
@installation_configs[Llm::ProviderConfig::MODEL_CONFIG_KEY] = {
|
|
'display_title' => 'LLM Model',
|
|
'description' => "Default #{Llm::Config.provider_options[captain_provider]} model used by Captain AI.",
|
|
'type' => 'select',
|
|
'options' => Llm::Models.provider_default_model_options(captain_provider)
|
|
}
|
|
end
|
|
|
|
def populate_provider_field_metadata
|
|
Llm::Config.provider_config_options(captain_provider).each do |option, config_key|
|
|
@installation_configs[config_key] ||= {
|
|
'display_title' => option.to_s.humanize.titleize,
|
|
'description' => "RubyLLM #{option} configuration.",
|
|
'type' => option.to_s.end_with?('api_key', 'secret_key', 'session_token', 'service_account_key', 'auth_token') ? 'secret' : 'text',
|
|
'provider' => captain_provider
|
|
}
|
|
end
|
|
end
|
|
|
|
def captain_provider
|
|
requested_provider = params.dig(:app_config, Llm::ProviderConfig::PROVIDER_CONFIG_KEY).presence || params[:provider].presence
|
|
return requested_provider if Llm::Config.provider_options.key?(requested_provider)
|
|
|
|
Llm::Config.current_provider
|
|
end
|
|
|
|
def app_config_value(key, value)
|
|
return value unless @config == 'captain' && key == Llm::ProviderConfig::MODEL_CONFIG_KEY
|
|
return value if Llm::Models.provider_default_model_options(captain_provider).key?(value)
|
|
end
|
|
end
|
|
|
|
SuperAdmin::AppConfigsController.prepend_mod_with('SuperAdmin::AppConfigsController')
|