clankersupport 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +91 -0
- data/lib/clankersupport/railtie.rb +31 -0
- data/lib/clankersupport/version.rb +5 -0
- data/lib/clankersupport.rb +94 -0
- metadata +53 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a8af4f02b44610de78162c7b0b518d39ba5dce08d4e8a7f18baac209cc57c55a
|
|
4
|
+
data.tar.gz: e426d8afb55f8c158cd44f929945b5239632e283b775fb2003743351c59efa9f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7e6f04f2ccd0a58c7a54c563f2944e1e5efefd5af47f2604316b4bbee7b71f7e35e4a60612ba23e553353bed73deea10a6d1db3c00b436785504404ef3b28342
|
|
7
|
+
data.tar.gz: 9b2a64564e8910a89cda36c6ea6c5954665cb4272966c61a967dd190f8538aebc3d4a22eb0dc97750e9fd4bb4a6ae4a1cbf2685df55fb18af9ddcabb9dd38910
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present LLMGateway, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# clankersupport
|
|
2
|
+
|
|
3
|
+
Embed the [Clanker Support](https://clankersupport.com) AI-powered support agent in any Ruby web app. One helper renders the widget `<script>` tag — escaped, validated, and framework-friendly — so visitors get streaming answers from your knowledge base, human escalation, and operator replies, with zero backend work in your app.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
bundle add clankersupport
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
Grab your project's public key from the dashboard (Project → Embed), then render the tag into your layout:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
require "clankersupport"
|
|
15
|
+
|
|
16
|
+
tag = ClankerSupport.script_tag("pk_your_project_key")
|
|
17
|
+
# <script src="https://api.clankersupport.com/widget.js" data-project="pk_your_project_key" data-api="https://api.clankersupport.com" async></script>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The return value is a plain `String`. Plain ERB (outside Rails) doesn't autoescape, so `<%= tag %>` just works — no `raw` or `.html_safe` needed. Rails ERB *does* autoescape; use the built-in helper below, which handles that for you.
|
|
21
|
+
|
|
22
|
+
> The public key is safe to expose — it's the same key the plain `<script>` embed uses.
|
|
23
|
+
|
|
24
|
+
### Rails
|
|
25
|
+
|
|
26
|
+
The gem ships a Railtie that registers a view helper in ActionView. Set `CLANKER_PROJECT_KEY` in your environment and drop the helper into your layout:
|
|
27
|
+
|
|
28
|
+
```erb
|
|
29
|
+
<%# app/views/layouts/application.html.erb %>
|
|
30
|
+
<body>
|
|
31
|
+
<%= yield %>
|
|
32
|
+
<%= clanker_support_tag %>
|
|
33
|
+
</body>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or pass the key and options explicitly:
|
|
37
|
+
|
|
38
|
+
```erb
|
|
39
|
+
<%= clanker_support_tag "pk_your_project_key", theme: "auto", brand_color: "#4f46e5" %>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`clanker_support_tag` returns an `html_safe` string, so Rails renders it as markup.
|
|
43
|
+
|
|
44
|
+
### Sinatra
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
require "sinatra"
|
|
48
|
+
require "clankersupport"
|
|
49
|
+
|
|
50
|
+
get "/" do
|
|
51
|
+
erb :index, locals: { clanker_support: ClankerSupport.script_tag("pk_your_project_key") }
|
|
52
|
+
end
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```erb
|
|
56
|
+
<%# views/index.erb %>
|
|
57
|
+
<body>
|
|
58
|
+
<h1>Hello</h1>
|
|
59
|
+
<%= clanker_support %>
|
|
60
|
+
</body>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
(If you enable Sinatra's `:escape_html`, output it with `<%== clanker_support %>` instead.)
|
|
64
|
+
|
|
65
|
+
## Options
|
|
66
|
+
|
|
67
|
+
| Option | Default | Description |
|
|
68
|
+
| ---------------------- | ------------------------------ | ------------------------------------------------------------------ |
|
|
69
|
+
| `project_key` | required | The project's public widget key (dashboard → Project → Embed). |
|
|
70
|
+
| `api_url:` | `https://api.clankersupport.com` | API origin — point at your own deployment when self-hosting. |
|
|
71
|
+
| `brand_color:` | widget default | Launcher/header accent color, e.g. `"#4f46e5"`. |
|
|
72
|
+
| `mode:` | `"bubble"` | `"bubble"` (floating launcher) or `"inline"` (mounts in place). |
|
|
73
|
+
| `theme:` | `"light"` | `"light"`, `"dark"`, or `"auto"` (follow the OS). |
|
|
74
|
+
| `escalation_threshold:`| project default | Visitor messages before "Talk to a human" appears (positive Integer). |
|
|
75
|
+
|
|
76
|
+
Invalid values (empty key, unknown mode/theme, non-positive or non-Integer threshold) raise `ArgumentError` at render time, so misconfiguration fails in development instead of silently shipping a broken widget.
|
|
77
|
+
|
|
78
|
+
## Self-hosting
|
|
79
|
+
|
|
80
|
+
Clanker Support is open source ([theopenco/llmchat](https://github.com/theopenco/llmchat)). Point `api_url:` at your own deployment; the tag's `src` and `data-api` both follow it.
|
|
81
|
+
|
|
82
|
+
## Publishing (maintainers)
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
gem build clankersupport.gemspec
|
|
86
|
+
gem push clankersupport-1.0.0.gem
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
MIT
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Rails integration. This file is only required from lib/clankersupport.rb
|
|
4
|
+
# when Rails::Railtie is defined, and every constant reference below is
|
|
5
|
+
# guarded, so the gem loads fine without Rails.
|
|
6
|
+
|
|
7
|
+
module ClankerSupport
|
|
8
|
+
# View helper mixed into ActionView by the Railtie.
|
|
9
|
+
#
|
|
10
|
+
# <%= clanker_support_tag %> <%# uses ENV["CLANKER_PROJECT_KEY"] %>
|
|
11
|
+
# <%= clanker_support_tag "pk_abc123", theme: "auto" %>
|
|
12
|
+
module Helper
|
|
13
|
+
# Render the widget script tag, marked +html_safe+ so Rails' ERB
|
|
14
|
+
# autoescaping emits it as markup. The project key defaults to
|
|
15
|
+
# +ENV["CLANKER_PROJECT_KEY"]+.
|
|
16
|
+
def clanker_support_tag(project_key = nil, **options)
|
|
17
|
+
key = project_key || ENV["CLANKER_PROJECT_KEY"]
|
|
18
|
+
ClankerSupport.script_tag(key, **options).html_safe
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if defined?(Rails::Railtie)
|
|
23
|
+
class Railtie < Rails::Railtie
|
|
24
|
+
initializer "clankersupport.view_helper" do
|
|
25
|
+
ActiveSupport.on_load(:action_view) do
|
|
26
|
+
include ClankerSupport::Helper
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Render the Clanker Support widget embed for Ruby web apps.
|
|
4
|
+
#
|
|
5
|
+
# The widget itself is client-side JavaScript served by the Clanker Support
|
|
6
|
+
# API (+/widget.js+); a backend's job is only to emit the script tag with the
|
|
7
|
+
# right +data-*+ attributes. {ClankerSupport.script_tag} does that with
|
|
8
|
+
# HTML-attribute escaping, mirroring the snippet the dashboard's Embed page
|
|
9
|
+
# generates.
|
|
10
|
+
#
|
|
11
|
+
# require "clankersupport"
|
|
12
|
+
#
|
|
13
|
+
# tag = ClankerSupport.script_tag("pk_your_project_key")
|
|
14
|
+
#
|
|
15
|
+
# The return value is a plain +String+. In Rails, use the +clanker_support_tag+
|
|
16
|
+
# view helper (see ClankerSupport::Helper), which marks the tag +html_safe+.
|
|
17
|
+
|
|
18
|
+
require "cgi"
|
|
19
|
+
|
|
20
|
+
require_relative "clankersupport/version"
|
|
21
|
+
|
|
22
|
+
module ClankerSupport
|
|
23
|
+
DEFAULT_API_URL = "https://api.clankersupport.com"
|
|
24
|
+
|
|
25
|
+
# +data-mode+ values the widget understands. +bubble+ (the default) is the
|
|
26
|
+
# floating launcher; +inline+ mounts the panel in place.
|
|
27
|
+
MODES = ["bubble", "inline"].freeze
|
|
28
|
+
|
|
29
|
+
# +data-theme+ values the widget understands. Absent means +light+.
|
|
30
|
+
THEMES = ["light", "dark", "auto"].freeze
|
|
31
|
+
|
|
32
|
+
# Build the Clanker Support widget +<script>+ tag.
|
|
33
|
+
#
|
|
34
|
+
# @param project_key [String] the project's public widget key (dashboard →
|
|
35
|
+
# Project → Embed). Safe to expose — it's the same key the script embed uses.
|
|
36
|
+
# @param api_url [String] API origin. Point at your own deployment when
|
|
37
|
+
# self-hosting; trailing slashes are stripped.
|
|
38
|
+
# @param brand_color [String, nil] accent color for the launcher/header,
|
|
39
|
+
# e.g. "#4f46e5". Omitted → the widget default.
|
|
40
|
+
# @param mode [String, nil] "bubble" (floating launcher, default) or "inline".
|
|
41
|
+
# @param theme [String, nil] "light" (default), "dark", or "auto" (follow OS).
|
|
42
|
+
# @param escalation_threshold [Integer, nil] visitor messages before
|
|
43
|
+
# "Talk to a human" appears. Omitted → the project's configured default.
|
|
44
|
+
# @return [String]
|
|
45
|
+
# @raise [ArgumentError] on an empty project key, an unknown mode/theme, or
|
|
46
|
+
# a non-positive escalation threshold — misconfiguration should fail at
|
|
47
|
+
# render time in development, not silently ship a broken widget.
|
|
48
|
+
def self.script_tag(
|
|
49
|
+
project_key,
|
|
50
|
+
api_url: DEFAULT_API_URL,
|
|
51
|
+
brand_color: nil,
|
|
52
|
+
mode: nil,
|
|
53
|
+
theme: nil,
|
|
54
|
+
escalation_threshold: nil
|
|
55
|
+
)
|
|
56
|
+
key = project_key.to_s
|
|
57
|
+
raise ArgumentError, "project_key is required" if key.strip.empty?
|
|
58
|
+
if !mode.nil? && !MODES.include?(mode)
|
|
59
|
+
raise ArgumentError, "mode must be one of #{MODES.inspect}, got #{mode.inspect}"
|
|
60
|
+
end
|
|
61
|
+
if !theme.nil? && !THEMES.include?(theme)
|
|
62
|
+
raise ArgumentError, "theme must be one of #{THEMES.inspect}, got #{theme.inspect}"
|
|
63
|
+
end
|
|
64
|
+
if !escalation_threshold.nil?
|
|
65
|
+
unless escalation_threshold.is_a?(Integer) && escalation_threshold >= 1
|
|
66
|
+
raise ArgumentError,
|
|
67
|
+
"escalation_threshold must be a positive Integer, got #{escalation_threshold.inspect}"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
base = api_url.to_s.sub(%r{/+\z}, "")
|
|
72
|
+
parts = [
|
|
73
|
+
%(<script src="#{escape_attr(base)}/widget.js"),
|
|
74
|
+
%(data-project="#{escape_attr(key)}"),
|
|
75
|
+
%(data-api="#{escape_attr(base)}"),
|
|
76
|
+
]
|
|
77
|
+
parts << %(data-brand="#{escape_attr(brand_color)}") unless brand_color.nil?
|
|
78
|
+
parts << %(data-mode="#{escape_attr(mode)}") unless mode.nil?
|
|
79
|
+
parts << %(data-theme="#{escape_attr(theme)}") unless theme.nil?
|
|
80
|
+
unless escalation_threshold.nil?
|
|
81
|
+
parts << %(data-escalation-threshold="#{escalation_threshold}")
|
|
82
|
+
end
|
|
83
|
+
parts << "async></script>"
|
|
84
|
+
parts.join(" ")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# HTML-attribute escaping, mirroring the dashboard snippet generator.
|
|
88
|
+
def self.escape_attr(value)
|
|
89
|
+
CGI.escapeHTML(value.to_s)
|
|
90
|
+
end
|
|
91
|
+
private_class_method :escape_attr
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
require_relative "clankersupport/railtie" if defined?(Rails::Railtie)
|
metadata
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: clankersupport
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- The Open Company
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-07-18 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Renders the Clanker Support widget <script> tag — escaped, validated,
|
|
14
|
+
and framework-friendly — so visitors get streaming answers from your knowledge base,
|
|
15
|
+
human escalation, and operator replies, with zero backend work in your app. Includes
|
|
16
|
+
a Rails view helper (clanker_support_tag). Clanker Support is open source and self-hostable.
|
|
17
|
+
email:
|
|
18
|
+
- hello@clankersupport.com
|
|
19
|
+
executables: []
|
|
20
|
+
extensions: []
|
|
21
|
+
extra_rdoc_files: []
|
|
22
|
+
files:
|
|
23
|
+
- LICENSE
|
|
24
|
+
- README.md
|
|
25
|
+
- lib/clankersupport.rb
|
|
26
|
+
- lib/clankersupport/railtie.rb
|
|
27
|
+
- lib/clankersupport/version.rb
|
|
28
|
+
homepage: https://clankersupport.com
|
|
29
|
+
licenses:
|
|
30
|
+
- MIT
|
|
31
|
+
metadata:
|
|
32
|
+
source_code_uri: https://github.com/theopenco/llmchat
|
|
33
|
+
documentation_uri: https://docs.clankersupport.com
|
|
34
|
+
post_install_message:
|
|
35
|
+
rdoc_options: []
|
|
36
|
+
require_paths:
|
|
37
|
+
- lib
|
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '3.0'
|
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
requirements: []
|
|
49
|
+
rubygems_version: 3.5.22
|
|
50
|
+
signing_key:
|
|
51
|
+
specification_version: 4
|
|
52
|
+
summary: Embed the Clanker Support AI-powered support agent in any Ruby web app.
|
|
53
|
+
test_files: []
|