Class: Testimonials::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/testimonials/configuration.rb

Overview

Host-tunable settings. Everything has a safe default, so a fresh install works with zero configuration; the hooks below let an app decide who gets prompted, who can triage, and how submissions are attributed.

Constant Summary collapse

DEFAULT_ADMIN_LAYOUT =

The gem's own dashboard layout. Compared against, so DashboardController can tell "the host left this alone" from "the host chose this".

'testimonials/application'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/testimonials/configuration.rb', line 138

def initialize
  @app_name = nil
  @enabled = ->(_request) { true }
  @authorize_admin = ->(_request) { Rails.env.development? }
  @admin_layout = DEFAULT_ADMIN_LAYOUT
  @base_controller_class = 'ActionController::Base'
  @current_user = ->(_request) {}
  @tenant = ->(_request) {}
  @user_display = lambda { |user|
    { name: user.try(:name), email: user.try(:email) }
  }
  @questions = nil
  @video = true
  @max_video_seconds = 120
  @max_video_size = 50 * 1024 * 1024
  @avatars = true
  @max_avatar_size = 5 * 1024 * 1024
  @storage_service = nil
  @reprompt_after = 90 * 24 * 60 * 60
  @max_prompts = 3
  @prompt_events = true
  @consent_text = nil
  @public_collection = true
  @public_api = false
  @nps = true
  @nps_reprompt_after = 90 * 24 * 60 * 60
  @on_submit = ->(_record) {}
  @on_detractor = ->(_nps_response) {}
  @rate_limit = { to: 5, within: 60 }
  @mount_path = '/testimonials'
end

Instance Attribute Details

#admin_layoutObject

Layout used by the built-in dashboard. Override this to render Testimonials inside your app's admin shell, e.g. "admin/application". The lighter of the two ways to adopt a host's chrome; see base_controller_class for the other.



28
29
30
# File 'lib/testimonials/configuration.rb', line 28

def admin_layout
  @admin_layout
end

#app_nameObject

Shown in the widget ("Enjoying %app?") and interpolated into the default questions. nil resolves to the Rails application name.



14
15
16
# File 'lib/testimonials/configuration.rb', line 14

def app_name
  @app_name
end

#authorize_adminObject

Per-request gate for the built-in dashboard. Defaults to development only — override it before deploying, e.g. with an admin check.



22
23
24
# File 'lib/testimonials/configuration.rb', line 22

def authorize_admin
  @authorize_admin
end

#avatarsObject

Headshot upload for guests on the public collection page. Requires Active Storage.



78
79
80
# File 'lib/testimonials/configuration.rb', line 78

def avatars
  @avatars
end

#base_controller_classObject

The controller the DASHBOARD inherits from, as a String so it resolves lazily rather than at config time. Default: a plain 'ActionController::Base', where authorize_admin is the only gate.

Name the controller your own admin already inherits from and the dashboard adopts that whole stack — layout, helpers, authentication, and any request context your before_actions set up (a Current attribute the layout reads, say). admin_layout covers only the layout, which leaves a host layout calling its own helpers to raise NameError under the engine's isolated namespace.

Only the dashboard uses it. The widget's endpoints stay on the engine's own public controller, so an admin base controller here can never demand a staff session from a member leaving a review.



44
45
46
# File 'lib/testimonials/configuration.rb', line 44

def base_controller_class
  @base_controller_class
end

Consent line stored verbatim with each submission. nil uses the localized default.



105
106
107
# File 'lib/testimonials/configuration.rb', line 105

def consent_text
  @consent_text
end

#current_userObject

Resolve the current user for attribution (optional). Return an object responding to #id, or nil. Receives the request.



48
49
50
# File 'lib/testimonials/configuration.rb', line 48

def current_user
  @current_user
end

#enabledObject

Per-request gate for the widget and the submission endpoints. Return false to hide the widget and reject submissions for this request.



18
19
20
# File 'lib/testimonials/configuration.rb', line 18

def enabled
  @enabled
end

#max_avatar_sizeObject

Returns the value of attribute max_avatar_size.



79
80
81
# File 'lib/testimonials/configuration.rb', line 79

def max_avatar_size
  @max_avatar_size
end

#max_promptsObject

Auto-prompt throttling. A user who dismissed the widget is not auto-prompted again within reprompt_after; a user auto-prompted max_prompts times without submitting is never auto-prompted again; a user who submitted a testimonial is done for good. Explicit opens (clicking your link) always work.



92
93
94
# File 'lib/testimonials/configuration.rb', line 92

def max_prompts
  @max_prompts
end

#max_video_secondsObject

Returns the value of attribute max_video_seconds.



74
75
76
# File 'lib/testimonials/configuration.rb', line 74

def max_video_seconds
  @max_video_seconds
end

#max_video_sizeObject

Returns the value of attribute max_video_size.



74
75
76
# File 'lib/testimonials/configuration.rb', line 74

def max_video_size
  @max_video_size
end

#mount_pathObject

Where the engine is mounted. The widget posts to paths under it, so keep this in sync with the mount line in your routes.



136
137
138
# File 'lib/testimonials/configuration.rb', line 136

def mount_path
  @mount_path
end

#npsObject

NPS surveys ("How likely are you to recommend…", 0–10). Promoters (9–10) are offered the testimonial form right after scoring.



117
118
119
# File 'lib/testimonials/configuration.rb', line 117

def nps
  @nps
end

#nps_reprompt_afterObject

Returns the value of attribute nps_reprompt_after.



118
119
120
# File 'lib/testimonials/configuration.rb', line 118

def nps_reprompt_after
  @nps_reprompt_after
end

#on_detractorObject

Called with each NPS response scored 0–6. Route it into your feedback tool, e.g. create a FeedbackEngine::Feedback from nps.comment.



127
128
129
# File 'lib/testimonials/configuration.rb', line 127

def on_detractor
  @on_detractor
end

#on_submitObject

Called with each saved Testimonials::Testimonial or Testimonials::NpsResponse — notify Slack, send an email. Runs inline after save; keep it fast or hand off to a job.



123
124
125
# File 'lib/testimonials/configuration.rb', line 123

def on_submit
  @on_submit
end

#prompt_eventsObject

The throttling ledger itself (testimonials_prompt_events). Off means no per-user prompt history is written — and therefore no auto-prompts: testimonial_prompt! stops opening the widget, because a prompt that can't be throttled would reopen on every page. Explicit opens — your own button, data-testimonial-prompt, window.Testimonials.open(), the public pages — are unaffected. For apps that only ever open the widget on a click; --skip-prompt-events writes it at install time.



101
102
103
# File 'lib/testimonials/configuration.rb', line 101

def prompt_events
  @prompt_events
end

#public_apiObject

Unauthenticated read access to the JSON API (approved + consented records only). OFF by default: the API then answers only for admins.



113
114
115
# File 'lib/testimonials/configuration.rb', line 113

def public_api
  @public_api
end

#public_collectionObject

The standalone collection page at "##mount_path/new" — for links you send to customers outside the app. ON by default; set false to 404 it.



109
110
111
# File 'lib/testimonials/configuration.rb', line 109

def public_collection
  @public_collection
end

#questionsObject

Guiding prompts shown above the message field and while recording — they fight blank-page paralysis, they are not form fields. nil uses the gem's built-in localized questions (testimonials.questions, with %app interpolated). Override with an array of literal strings, or a callable for host-side i18n: -> { I18n.t("myapp.review_questions") }. An empty array hides the section.



70
71
72
# File 'lib/testimonials/configuration.rb', line 70

def questions
  @questions
end

#rate_limitObject

Per-IP throttle for the public endpoints, as keyword arguments for Rails' rate limiter (Rails 7.2+; ignored on 7.1). Read once when the controller loads — set it in an initializer. nil disables throttling.



132
133
134
# File 'lib/testimonials/configuration.rb', line 132

def rate_limit
  @rate_limit
end

#reprompt_afterObject

Auto-prompt throttling. A user who dismissed the widget is not auto-prompted again within reprompt_after; a user auto-prompted max_prompts times without submitting is never auto-prompted again; a user who submitted a testimonial is done for good. Explicit opens (clicking your link) always work.



92
93
94
# File 'lib/testimonials/configuration.rb', line 92

def reprompt_after
  @reprompt_after
end

#storage_serviceObject

The Active Storage service that stores uploads — video, its poster frame, guest avatars — as a service name from the host's config/storage.yml (e.g. a dedicated bucket or folder). nil, the default, uses the environment's default service.



85
86
87
# File 'lib/testimonials/configuration.rb', line 85

def storage_service
  @storage_service
end

#tenantObject

Resolve the current tenant (optional, for multi-tenant apps). Return an opaque key — a GlobalID, an id, a subdomain, a slug — or nil. Receives the request; shaped exactly like current_user/authorize_admin. nil (the default) is a single, global collection: today's behavior, unchanged. Testimonials, NPS, the dashboard and the read API all scope to whatever this returns. The recommended key is a GlobalID (record.to_gid.to_s), which also matches the has_testimonials model concern.



57
58
59
# File 'lib/testimonials/configuration.rb', line 57

def tenant
  @tenant
end

#user_displayObject

Turn a resolved user into the attribution stored with a submission. Return a hash with :name, :email, and optionally :title_company. Receives whatever #current_user returned.



62
63
64
# File 'lib/testimonials/configuration.rb', line 62

def user_display
  @user_display
end

#videoObject

Video testimonials (recording and upload). Requires Active Storage.



73
74
75
# File 'lib/testimonials/configuration.rb', line 73

def video
  @video
end

Instance Method Details

#avatars_enabled?Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/testimonials/configuration.rb', line 180

def avatars_enabled?
  avatars && defined?(::ActiveStorage) ? true : false
end

#events_endpointObject



172
# File 'lib/testimonials/configuration.rb', line 172

def events_endpoint = "#{mount_path.chomp('/')}/events"

#nps_endpointObject



171
# File 'lib/testimonials/configuration.rb', line 171

def nps_endpoint = "#{mount_path.chomp('/')}/nps"

#testimonials_endpointObject



170
# File 'lib/testimonials/configuration.rb', line 170

def testimonials_endpoint = mount_path.chomp('/')

#video_enabled?Boolean

Video and avatars need Active Storage — both the config switch and the host actually having it loaded.

Returns:

  • (Boolean)


176
177
178
# File 'lib/testimonials/configuration.rb', line 176

def video_enabled?
  video && defined?(::ActiveStorage) ? true : false
end