pager_tree-integrations 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 +201 -0
- data/README.md +61 -0
- data/Rakefile +8 -0
- data/app/assets/config/pager_tree_integrations_manifest.js +1 -0
- data/app/assets/stylesheets/pager_tree/integrations/application.css +15 -0
- data/app/controllers/pager_tree/integrations/application_controller.rb +6 -0
- data/app/controllers/pager_tree/integrations/live_call_routing/twilio/v3_controller.rb +49 -0
- data/app/helpers/pager_tree/integrations/application_helper.rb +9 -0
- data/app/jobs/pager_tree/integrations/application_job.rb +6 -0
- data/app/jobs/pager_tree/integrations/outgoing_webhook_job.rb +12 -0
- data/app/mailers/pager_tree/integrations/application_mailer.rb +8 -0
- data/app/models/pager_tree/integrations/additional_datum.rb +41 -0
- data/app/models/pager_tree/integrations/alert.rb +60 -0
- data/app/models/pager_tree/integrations/apex_ping/v3.rb +69 -0
- data/app/models/pager_tree/integrations/application_record.rb +7 -0
- data/app/models/pager_tree/integrations/email/v3.rb +150 -0
- data/app/models/pager_tree/integrations/integration.rb +130 -0
- data/app/models/pager_tree/integrations/live_call_routing/twilio/v3.rb +332 -0
- data/app/models/pager_tree/integrations/outgoing_event.rb +25 -0
- data/app/models/pager_tree/integrations/outgoing_webhook/v3.rb +75 -0
- data/app/models/pager_tree/integrations/outgoing_webhook_delivery/hook_relay.rb +98 -0
- data/app/models/pager_tree/integrations/outgoing_webhook_delivery.rb +22 -0
- data/app/views/layouts/pager_tree/integrations/application.html.erb +15 -0
- data/app/views/pager_tree/integrations/apex_ping/v3/_form_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/apex_ping/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/email/v3/_form_options.html.erb +11 -0
- data/app/views/pager_tree/integrations/email/v3/_show_options.html.erb +17 -0
- data/app/views/pager_tree/integrations/live_call_routing/twilio/v3/_form_options.html.erb +80 -0
- data/app/views/pager_tree/integrations/live_call_routing/twilio/v3/_show_options.html.erb +181 -0
- data/app/views/pager_tree/integrations/outgoing_webhook/v3/_form_options.html.erb +50 -0
- data/app/views/pager_tree/integrations/outgoing_webhook/v3/_show_options.html.erb +61 -0
- data/app/views/shared/_password_visibility_button.html.erb +8 -0
- data/config/locales/en.yml +87 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20220208195853_create_active_storage_tables.active_storage.rb +58 -0
- data/db/migrate/20220208195854_create_deferred_request_deferred_requests.deferred_request.rb +13 -0
- data/db/migrate/20220208195855_create_pager_tree_integrations_integrations.rb +10 -0
- data/db/migrate/20220215200426_create_pager_tree_integrations_outgoing_webhook_deliveries.rb +12 -0
- data/lib/generators/integration/USAGE +11 -0
- data/lib/generators/integration/integration_generator.rb +14 -0
- data/lib/generators/integration/templates/_form_options.html.erb.tt +8 -0
- data/lib/generators/integration/templates/_show_options.html.erb.tt +14 -0
- data/lib/generators/integration/templates/model.rb.tt +64 -0
- data/lib/generators/integration/templates/test.rb.tt +87 -0
- data/lib/pager_tree/integrations/engine.rb +11 -0
- data/lib/pager_tree/integrations/env.rb +36 -0
- data/lib/pager_tree/integrations/version.rb +5 -0
- data/lib/pager_tree/integrations.rb +29 -0
- data/lib/tasks/pager_tree/integrations_tasks.rake +4 -0
- metadata +152 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
module PagerTree::Integrations
|
2
|
+
class OutgoingWebhookDelivery::HookRelay < OutgoingWebhookDelivery
|
3
|
+
extend ::PagerTree::Integrations::Env
|
4
|
+
|
5
|
+
define_model_callbacks :deliver
|
6
|
+
|
7
|
+
def self.hook_relay_account_id
|
8
|
+
find_value_by_name(:hook_relay, :account_id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.hook_relay_hook_id
|
12
|
+
find_value_by_name(:hook_relay, :hook_id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.hook_relay_api_key
|
16
|
+
find_value_by_name(:hook_relay, :api_key)
|
17
|
+
end
|
18
|
+
|
19
|
+
def hook_relay_hook_url
|
20
|
+
"https://api.hookrelay.dev/hooks/#{OutgoingWebhookDelivery::HookRelay.hook_relay_account_id}/#{OutgoingWebhookDelivery::HookRelay.hook_relay_hook_id}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def hook_relay_delivery_url
|
24
|
+
"https://app.hookrelay.dev/api/v1/accounts/#{OutgoingWebhookDelivery::HookRelay.hook_relay_account_id}/hooks/#{OutgoingWebhookDelivery::HookRelay.hook_relay_hook_id}/deliveries/#{thirdparty_id}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def deliver_later
|
28
|
+
OutgoingWebhookJob.perform_later(id, :deliver)
|
29
|
+
end
|
30
|
+
|
31
|
+
def deliver
|
32
|
+
run_callbacks :deliver do
|
33
|
+
begin
|
34
|
+
hook_relay_options = {
|
35
|
+
headers: {
|
36
|
+
HR_TARGET_URL: url
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
pagertree_options = {
|
41
|
+
headers: {
|
42
|
+
Accept: "*/*",
|
43
|
+
'User-Agent': "pagertree outgoing webhook service; ref: #{resource&.id}; report: support@pagertree.com",
|
44
|
+
'Content-Type': "application/json"
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
auth_options = {}
|
49
|
+
if auth.is_a?(Hash) && (username = auth.dig(:username)).present? && (password = auth.dig(:password)).present?
|
50
|
+
auth_options = {
|
51
|
+
headers: {
|
52
|
+
Authorization: Base64.strict_encode64("#{username}:#{password}")
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
options = OutgoingWebhookDelivery::HTTP_OPTIONS
|
58
|
+
.deep_merge(hook_relay_options)
|
59
|
+
.deep_merge(pagertree_options)
|
60
|
+
.deep_merge(auth_options)
|
61
|
+
|
62
|
+
response = HTTParty.post(hook_relay_hook_url, body: body.to_json, **options)
|
63
|
+
|
64
|
+
self.thirdparty_id = response["id"]
|
65
|
+
self.status = :sent
|
66
|
+
rescue => exception
|
67
|
+
Rails.logger.error(exception)
|
68
|
+
self.status = :failure
|
69
|
+
end
|
70
|
+
save!
|
71
|
+
end # run_callbacks
|
72
|
+
end
|
73
|
+
|
74
|
+
def delivery
|
75
|
+
return @delivery if @delivery
|
76
|
+
return {} unless thirdparty_id
|
77
|
+
|
78
|
+
options = {
|
79
|
+
headers: {
|
80
|
+
'Content-Type': "application/json",
|
81
|
+
Authorization: "Bearer #{OutgoingWebhookDelivery::HookRelay.hook_relay_api_key}"
|
82
|
+
},
|
83
|
+
timeout: 15
|
84
|
+
}
|
85
|
+
|
86
|
+
@delivery = ::HTTParty.get(hook_relay_delivery_url, **options)
|
87
|
+
@delivery
|
88
|
+
end
|
89
|
+
|
90
|
+
def request
|
91
|
+
delivery&.dig("request")
|
92
|
+
end
|
93
|
+
|
94
|
+
def responses
|
95
|
+
delivery&.dig("responses") || []
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module PagerTree::Integrations
|
2
|
+
class OutgoingWebhookDelivery < PagerTree::Integrations.outgoing_webhook_delivery_parent_class.constantize
|
3
|
+
self.table_name = PagerTree::Integrations.outgoing_webhook_delivery_table_name
|
4
|
+
|
5
|
+
serialize :data, JSON
|
6
|
+
encrypts :data
|
7
|
+
|
8
|
+
store_accessor :data, *[:url, :body, :auth].map(&:to_s)
|
9
|
+
|
10
|
+
HTTP_OPTIONS = {
|
11
|
+
headers: {'Content-Type': "application/json"},
|
12
|
+
timeout: 15
|
13
|
+
}
|
14
|
+
|
15
|
+
belongs_to :resource, polymorphic: true
|
16
|
+
enum status: {queued: 0, sent: 1, success: 2, failure: 3, retrying: 4, cancelled: 5, stored: 6, insufficent_funds: 7}
|
17
|
+
|
18
|
+
def self.factory(**params)
|
19
|
+
PagerTree::Integrations.outgoing_webhook_delivery_factory_class.constantize.new(**params)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Pager tree integrations</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
|
8
|
+
<%= stylesheet_link_tag "pager_tree/integrations/application", media: "all" %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
|
12
|
+
<%= yield %>
|
13
|
+
|
14
|
+
</body>
|
15
|
+
</html>
|
File without changes
|
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<div class="form-group">
|
2
|
+
<%= form.label :option_allow_spam %>
|
3
|
+
<%= form.check_box :option_allow_spam, class: "form-checkbox" %>
|
4
|
+
<p class="form-hint"><%== t(".option_allow_spam_hint_html") %></p>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<div class="form-group">
|
8
|
+
<%= form.label :option_dedup_threads %>
|
9
|
+
<%= form.check_box :option_dedup_threads, class: "form-checkbox" %>
|
10
|
+
<p class="form-hint"><%== t(".option_dedup_threads_hint_html") %></p>
|
11
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="sm:col-span-1">
|
2
|
+
<dt class="text-sm font-medium text-gray-500">
|
3
|
+
<%= t("activerecord.attributes.pager_tree/integrations/email/v3.option_allow_spam") %>
|
4
|
+
</dt>
|
5
|
+
<dd class="mt-1 text-sm text-gray-900">
|
6
|
+
<%= render partial: "shared/components/badge_enabled", locals: { enabled: integration.option_allow_spam } %>
|
7
|
+
</dd>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<div class="sm:col-span-1">
|
11
|
+
<dt class="text-sm font-medium text-gray-500">
|
12
|
+
<%= t("activerecord.attributes.pager_tree/integrations/email/v3.option_dedup_threads") %>
|
13
|
+
</dt>
|
14
|
+
<dd class="mt-1 text-sm text-gray-900">
|
15
|
+
<%= render partial: "shared/components/badge_enabled", locals: { enabled: integration.option_dedup_threads } %>
|
16
|
+
</dd>
|
17
|
+
</div>
|
@@ -0,0 +1,80 @@
|
|
1
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
2
|
+
<div class="form-group">
|
3
|
+
<%= form.label :option_account_sid %>
|
4
|
+
<%= form.text_field :option_account_sid, class: "form-control" %>
|
5
|
+
<p class="form-hint"><%== t(".option_account_sid_hint_html") %></p>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<div class="form-group" data-controller="password-visibility">
|
9
|
+
<%= form.label :option_api_key %>
|
10
|
+
<%= form.password_field :option_api_key, value: form.object.option_api_key, class: "form-control", data: { password_visibility_target: "input"} %>
|
11
|
+
<div class="flex justify-between">
|
12
|
+
<p class="form-hint"><%== t(".option_api_key_hint_html") %></p>
|
13
|
+
<%= render partial: "shared/password_visibility_button" %>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div class="form-group" data-controller="password-visibility">
|
18
|
+
<%= form.label :option_api_secret %>
|
19
|
+
<%= form.password_field :option_api_secret, value: form.object.option_api_secret, class: "form-control", data: { password_visibility_target: "input"} %>
|
20
|
+
<div class="flex justify-between">
|
21
|
+
<p class="form-hint"><%== t(".option_api_secret_hint_html") %></p>
|
22
|
+
<%= render partial: "shared/password_visibility_button" %>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<div class="form-group">
|
27
|
+
<%= form.label :option_welcome_media %>
|
28
|
+
<%= form.file_field :option_welcome_media, accept: "audio/*", class: "file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-gray-50 file:text-gray-700 hover:file:bg-gray-100" %>
|
29
|
+
<p class="form-hint"><%== t(".option_welcome_media_hint_html") %></p>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<div class="form-group">
|
33
|
+
<%= form.label :option_please_wait_media %>
|
34
|
+
<%= form.file_field :option_please_wait_media, accept: "audio/*", class: "file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-gray-50 file:text-gray-700 hover:file:bg-gray-100" %>
|
35
|
+
<p class="form-hint"><%== t(".option_please_wait_media_hint_html") %></p>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<div class="form-group">
|
39
|
+
<%= form.label :option_music_media %>
|
40
|
+
<%= form.file_field :option_music_media, accept: "audio/*", class: "file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-gray-50 file:text-gray-700 hover:file:bg-gray-100" %>
|
41
|
+
<p class="form-hint"><%== t(".option_music_media_hint_html") %></p>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div class="form-group">
|
45
|
+
<%= form.label :option_connect_now_media %>
|
46
|
+
<%= form.file_field :option_connect_now_media, accept: "audio/*", class: "file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-gray-50 file:text-gray-700 hover:file:bg-gray-100" %>
|
47
|
+
<p class="form-hint"><%== t(".option_connect_now_media_hint_html") %></p>
|
48
|
+
</div>
|
49
|
+
|
50
|
+
<div class="form-group">
|
51
|
+
<%= form.label :option_no_answer_media %>
|
52
|
+
<%= form.file_field :option_no_answer_media, accept: "audio/*", class: "file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-gray-50 file:text-gray-700 hover:file:bg-gray-100" %>
|
53
|
+
<p class="form-hint"><%== t(".option_no_answer_media_hint_html") %></p>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<div class="form-group">
|
57
|
+
<%= form.label :option_no_answer_thank_you_media %>
|
58
|
+
<%= form.file_field :option_no_answer_thank_you_media, accept: "audio/*", class: "file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-gray-50 file:text-gray-700 hover:file:bg-gray-100" %>
|
59
|
+
<p class="form-hint"><%== t(".option_no_answer_thank_you_media_hint_html") %></p>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<div class="form-group">
|
63
|
+
<%= form.label :option_force_input %>
|
64
|
+
<%= form.check_box :option_force_input, class: "form-checkbox" %>
|
65
|
+
<p class="form-hint"><%== t(".option_force_input_hint_html") %></p>
|
66
|
+
</div>
|
67
|
+
|
68
|
+
<div class="form-group">
|
69
|
+
<%= form.label :option_record %>
|
70
|
+
<%= form.check_box :option_record, class: "form-checkbox" %>
|
71
|
+
<p class="form-hint"><%== t(".option_record_hint_html") %></p>
|
72
|
+
</div>
|
73
|
+
|
74
|
+
<div class="form-group" data-controller="tagify">
|
75
|
+
<%= form.label :option_record_emails_list %>
|
76
|
+
<%= form.text_field :option_record_emails_list, class: "form-control", data: { tagify_target: "input" } %>
|
77
|
+
<p class="form-hint"><%== t(".option_record_emails_list_hint_html") %></p>
|
78
|
+
</div>
|
79
|
+
|
80
|
+
</div>
|
@@ -0,0 +1,181 @@
|
|
1
|
+
<div class="sm:col-span-2">
|
2
|
+
<dt class="text-sm font-medium text-gray-500">
|
3
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_account_sid") %>
|
4
|
+
</dt>
|
5
|
+
<dd class="mt-1 text-sm text-gray-900">
|
6
|
+
<div class="flex items-center gap-2">
|
7
|
+
<p class="text-sm truncate">
|
8
|
+
<%= integration.option_account_sid %>
|
9
|
+
</p>
|
10
|
+
</div>
|
11
|
+
</dd>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div class="sm:col-span-1">
|
15
|
+
<dt class="text-sm font-medium text-gray-500">
|
16
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_api_key") %>
|
17
|
+
</dt>
|
18
|
+
<dd class="mt-1 text-sm text-gray-900">
|
19
|
+
<div class="flex items-center gap-2">
|
20
|
+
<p class="text-sm truncate">
|
21
|
+
<%= mask integration.option_api_key %>
|
22
|
+
</p>
|
23
|
+
</div>
|
24
|
+
</dd>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div class="sm:col-span-1">
|
28
|
+
<dt class="text-sm font-medium text-gray-500">
|
29
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_api_secret") %>
|
30
|
+
</dt>
|
31
|
+
<dd class="mt-1 text-sm text-gray-900">
|
32
|
+
<div class="flex items-center gap-2">
|
33
|
+
<p class="text-sm truncate">
|
34
|
+
<%= mask integration.option_api_secret %>
|
35
|
+
</p>
|
36
|
+
</div>
|
37
|
+
</dd>
|
38
|
+
</div>
|
39
|
+
|
40
|
+
<div class="sm:col-span-2">
|
41
|
+
<dt class="text-sm font-medium text-gray-500">
|
42
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_welcome_media") %>
|
43
|
+
</dt>
|
44
|
+
<dd class="mt-1 text-sm text-gray-900">
|
45
|
+
<div class="flex items-center gap-2">
|
46
|
+
<p class="text-sm truncate">
|
47
|
+
<% if integration.option_welcome_media.present? %>
|
48
|
+
<%= link_to integration.option_welcome_media.blob.filename, integration.option_welcome_media, target: "_blank" %>
|
49
|
+
<% else %>
|
50
|
+
(<%= t("pager_tree.integrations.common.none") %>)
|
51
|
+
<% end %>
|
52
|
+
</p>
|
53
|
+
<%= link_to t("delete"), main_app.integration_attachment_path(integration, integration.option_welcome_media.id), method: :delete, class: "btn btn-small btn-danger outline", data: { confirm: t("are_you_sure") } if integration.option_welcome_media.present? %>
|
54
|
+
</div>
|
55
|
+
</dd>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<div class="sm:col-span-2">
|
59
|
+
<dt class="text-sm font-medium text-gray-500">
|
60
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_please_wait_media") %>
|
61
|
+
</dt>
|
62
|
+
<dd class="mt-1 text-sm text-gray-900">
|
63
|
+
<div class="flex items-center gap-2">
|
64
|
+
<p class="text-sm truncate">
|
65
|
+
<% if integration.option_please_wait_media.present? %>
|
66
|
+
<%= link_to integration.option_please_wait_media.blob.filename, integration.option_please_wait_media, target: "_blank" %>
|
67
|
+
<% else %>
|
68
|
+
(<%= link_to t("pager_tree.integrations.common.default"), integration.option_please_wait_media_url, target: "_blank" %>)
|
69
|
+
<% end %>
|
70
|
+
</p>
|
71
|
+
<%= link_to t("delete"), main_app.integration_attachment_path(integration, integration.option_please_wait_media.id), method: :delete, class: "btn btn-small btn-danger outline", data: { confirm: t("are_you_sure") } if integration.option_please_wait_media.present? %>
|
72
|
+
</div>
|
73
|
+
</dd>
|
74
|
+
</div>
|
75
|
+
|
76
|
+
<div class="sm:col-span-2">
|
77
|
+
<dt class="text-sm font-medium text-gray-500">
|
78
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_music_media") %>
|
79
|
+
</dt>
|
80
|
+
<dd class="mt-1 text-sm text-gray-900">
|
81
|
+
<div class="flex items-center gap-2">
|
82
|
+
<p class="text-sm truncate">
|
83
|
+
<% if integration.option_music_media.present? %>
|
84
|
+
<%= link_to integration.option_music_media.blob.filename, integration.option_music_media, target: "_blank" %>
|
85
|
+
<% else %>
|
86
|
+
(<%= link_to t("pager_tree.integrations.common.default"), integration.option_music_media_url, target: "_blank" %>)
|
87
|
+
<% end %>
|
88
|
+
</p>
|
89
|
+
<%= link_to t("delete"), main_app.integration_attachment_path(integration, integration.option_music_media.id), method: :delete, class: "btn btn-small btn-danger outline", data: { confirm: t("are_you_sure") } if integration.option_music_media.present? %>
|
90
|
+
</div>
|
91
|
+
</dd>
|
92
|
+
</div>
|
93
|
+
|
94
|
+
<div class="sm:col-span-2">
|
95
|
+
<dt class="text-sm font-medium text-gray-500">
|
96
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_connect_now_media") %>
|
97
|
+
</dt>
|
98
|
+
<dd class="mt-1 text-sm text-gray-900">
|
99
|
+
<div class="flex items-center gap-2">
|
100
|
+
<p class="text-sm truncate">
|
101
|
+
<% if integration.option_connect_now_media.present? %>
|
102
|
+
<%= link_to integration.option_connect_now_media.blob.filename, integration.option_connect_now_media, target: "_blank" %>
|
103
|
+
<% else %>
|
104
|
+
(<%= link_to t("pager_tree.integrations.common.default"), integration.option_connect_now_media_url, target: "_blank" %>)
|
105
|
+
<% end %>
|
106
|
+
</p>
|
107
|
+
<%= link_to t("delete"), main_app.integration_attachment_path(integration, integration.option_connect_now_media.id), method: :delete, class: "btn btn-small btn-danger outline", data: { confirm: t("are_you_sure") } if integration.option_connect_now_media.present? %>
|
108
|
+
</div>
|
109
|
+
</dd>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
<div class="sm:col-span-2">
|
113
|
+
<dt class="text-sm font-medium text-gray-500">
|
114
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_record") %>
|
115
|
+
</dt>
|
116
|
+
<dd class="mt-1 text-sm text-gray-900">
|
117
|
+
<%= render partial: "shared/components/badge_enabled", locals: { enabled: integration.option_record } %>
|
118
|
+
</dd>
|
119
|
+
</div>
|
120
|
+
|
121
|
+
<div class="sm:col-span-2">
|
122
|
+
<dt class="text-sm font-medium text-gray-500">
|
123
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_no_answer_media") %>
|
124
|
+
</dt>
|
125
|
+
<dd class="mt-1 text-sm text-gray-900">
|
126
|
+
<div class="flex items-center gap-2">
|
127
|
+
<p class="text-sm truncate">
|
128
|
+
<% if integration.option_no_answer_media.present? %>
|
129
|
+
<%= link_to integration.option_no_answer_media.blob.filename, integration.option_no_answer_media, target: "_blank" %>
|
130
|
+
<% else %>
|
131
|
+
(<%= t("pager_tree.integrations.common.default") %>)
|
132
|
+
<% end %>
|
133
|
+
</p>
|
134
|
+
</div>
|
135
|
+
</dd>
|
136
|
+
</div>
|
137
|
+
|
138
|
+
<div class="sm:col-span-2">
|
139
|
+
<dt class="text-sm font-medium text-gray-500">
|
140
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_no_answer_thank_you_media") %>
|
141
|
+
</dt>
|
142
|
+
<dd class="mt-1 text-sm text-gray-900">
|
143
|
+
<div class="flex items-center gap-2">
|
144
|
+
<p class="text-sm truncate">
|
145
|
+
<% if integration.option_no_answer_thank_you_media.present? %>
|
146
|
+
<%= link_to integration.option_no_answer_thank_you_media.blob.filename, integration.option_no_answer_thank_you_media, target: "_blank" %>
|
147
|
+
<% else %>
|
148
|
+
(<%= t("pager_tree.integrations.common.default") %>)
|
149
|
+
<% end %>
|
150
|
+
</p>
|
151
|
+
</div>
|
152
|
+
</dd>
|
153
|
+
</div>
|
154
|
+
|
155
|
+
<div class="sm:col-span-2">
|
156
|
+
<dt class="text-sm font-medium text-gray-500">
|
157
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_record_emails_list") %>
|
158
|
+
</dt>
|
159
|
+
<dd class="mt-1 text-sm text-gray-900">
|
160
|
+
<div class="flex items-center gap-2">
|
161
|
+
<% integration.option_record_emails.each do |email| %>
|
162
|
+
<p class="text-sm truncate">
|
163
|
+
<%= link_to email, "mailto:#{email}" %>
|
164
|
+
</p>
|
165
|
+
<% end %>
|
166
|
+
<p class="hidden only:flex text-sm truncate">
|
167
|
+
(<%= t("pager_tree.integrations.common.none") %>)
|
168
|
+
</p>
|
169
|
+
</div>
|
170
|
+
</dd>
|
171
|
+
</div>
|
172
|
+
|
173
|
+
<div class="sm:col-span-1">
|
174
|
+
<dt class="text-sm font-medium text-gray-500">
|
175
|
+
<%= t("activerecord.attributes.pager_tree/integrations/live_call_routing/twilio/v3.option_force_input") %>
|
176
|
+
</dt>
|
177
|
+
<dd class="mt-1 text-sm text-gray-900">
|
178
|
+
<%= render partial: "shared/components/badge_enabled", locals: { enabled: integration.option_force_input } %>
|
179
|
+
</dd>
|
180
|
+
</div>
|
181
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
2
|
+
<div class="form-group">
|
3
|
+
<%= form.label :option_webhook_url %>
|
4
|
+
<%= form.text_field :option_webhook_url, class: "form-control" %>
|
5
|
+
<p class="form-hint"><%== t(".option_webhook_url_hint_html") %></p>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<div class="form-group">
|
9
|
+
<%= form.label :option_username %>
|
10
|
+
<%= form.text_field :option_username, class: "form-control" %>
|
11
|
+
<p class="form-hint"><%== t(".option_username_hint_html") %></p>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div class="form-group">
|
15
|
+
<%= form.label :option_password %>
|
16
|
+
<%= form.text_field :option_password, class: "form-control" %>
|
17
|
+
<p class="form-hint"><%== t(".option_password_hint_html") %></p>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<%
|
21
|
+
opts = [
|
22
|
+
:alert_created,
|
23
|
+
:alert_open,
|
24
|
+
:alert_acknowledged,
|
25
|
+
:alert_rejected,
|
26
|
+
:alert_timeout,
|
27
|
+
:alert_resolved,
|
28
|
+
:alert_dropped,
|
29
|
+
:alert_handoff,
|
30
|
+
:send_linked
|
31
|
+
]
|
32
|
+
%>
|
33
|
+
<% opts.each do |opt| %>
|
34
|
+
<div class="form-group">
|
35
|
+
<%= form.label "option_#{opt.to_s}".to_sym %>
|
36
|
+
<%= form.check_box "option_#{opt.to_s}".to_sym, class: "form-checkbox" %>
|
37
|
+
<p class="form-hint"><%== t(".option_#{opt.to_s}_hint_html") %></p>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
40
|
+
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<div class="grid grid-cols-1 gap-4">
|
44
|
+
<%= tag.div class: "form-group", data: {controller: "code-editor", code_editor_language_value: "handlebars", code_editor_read_only_value: false } do %>
|
45
|
+
<%= form.label :option_template %>
|
46
|
+
<%= form.hidden_field :option_template, class: "form-control", data: {code_editor_target: "form"} %>
|
47
|
+
<%= tag.div class: "h-96", data: {code_editor_target: "editor"} do %><%= form.object.option_template %><% end %>
|
48
|
+
<p class="form-hint"><%== t(".option_template_hint_html") %></p>
|
49
|
+
<% end %>
|
50
|
+
</div>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
<div class="sm:col-span-2">
|
2
|
+
<dt class="text-sm font-medium text-gray-500">
|
3
|
+
<%= t("activerecord.attributes.pager_tree/integrations/outgoing_webhook/v3.option_webhook_url") %>
|
4
|
+
</dt>
|
5
|
+
<dd class="mt-1 text-sm text-gray-900">
|
6
|
+
<div class="flex items-center gap-2">
|
7
|
+
<p class="text-sm truncate">
|
8
|
+
<%= integration.option_webhook_url %>
|
9
|
+
</p>
|
10
|
+
</div>
|
11
|
+
</dd>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div class="sm:col-span-1">
|
15
|
+
<dt class="text-sm font-medium text-gray-500">
|
16
|
+
<%= t("activerecord.attributes.pager_tree/integrations/outgoing_webhook/v3.option_username") %>
|
17
|
+
</dt>
|
18
|
+
<dd class="mt-1 text-sm text-gray-900">
|
19
|
+
<div class="flex items-center gap-2">
|
20
|
+
<p class="text-sm truncate">
|
21
|
+
<%= mask integration.option_username %>
|
22
|
+
</p>
|
23
|
+
</div>
|
24
|
+
</dd>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div class="sm:col-span-1">
|
28
|
+
<dt class="text-sm font-medium text-gray-500">
|
29
|
+
<%= t("activerecord.attributes.pager_tree/integrations/outgoing_webhook/v3.option_password") %>
|
30
|
+
</dt>
|
31
|
+
<dd class="mt-1 text-sm text-gray-900">
|
32
|
+
<div class="flex items-center gap-2">
|
33
|
+
<p class="text-sm truncate">
|
34
|
+
<%= mask integration.option_password %>
|
35
|
+
</p>
|
36
|
+
</div>
|
37
|
+
</dd>
|
38
|
+
</div>
|
39
|
+
|
40
|
+
<%
|
41
|
+
opts = [
|
42
|
+
:alert_created,
|
43
|
+
:alert_open,
|
44
|
+
:alert_acknowledged,
|
45
|
+
:alert_rejected,
|
46
|
+
:alert_timeout,
|
47
|
+
:alert_resolved,
|
48
|
+
:alert_dropped,
|
49
|
+
:alert_handoff,
|
50
|
+
]
|
51
|
+
%>
|
52
|
+
<% opts.each do |opt| %>
|
53
|
+
<div class="sm:col-span-1">
|
54
|
+
<dt class="text-sm font-medium text-gray-500">
|
55
|
+
<%= t("activerecord.attributes.pager_tree/integrations/outgoing_webhook/v3.option_#{opt.to_s}") %>
|
56
|
+
</dt>
|
57
|
+
<dd class="mt-1 text-sm text-gray-900">
|
58
|
+
<%= render partial: "shared/components/badge_enabled", locals: { enabled: integration.send("option_#{opt.to_s}") } %>
|
59
|
+
</dd>
|
60
|
+
</div>
|
61
|
+
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div class="password-visibility-toggle">
|
2
|
+
<%= tag.button data: { action: "password-visibility#toggle", password_visibility_target: "icon"} do %>
|
3
|
+
<%= fa_icon "eye" %>
|
4
|
+
<% end %>
|
5
|
+
<%= tag.button class: "hidden", data: { action: "password-visibility#toggle", password_visibility_target: "icon"} do %>
|
6
|
+
<%= fa_icon "eye-slash" %>
|
7
|
+
<% end %>
|
8
|
+
</div>
|
@@ -0,0 +1,87 @@
|
|
1
|
+
en:
|
2
|
+
pager_tree:
|
3
|
+
integrations:
|
4
|
+
common:
|
5
|
+
default: "default"
|
6
|
+
none: "none"
|
7
|
+
apex_ping:
|
8
|
+
v3:
|
9
|
+
form_options:
|
10
|
+
email:
|
11
|
+
v3:
|
12
|
+
form_options:
|
13
|
+
option_allow_spam_hint_html: "Allow emails marked as SPAM to create alerts"
|
14
|
+
option_dedup_threads_hint_html: "Ignore emails from same thread (ex: Prevents new alerts for replys on emails (aka: RE:RE:RE...))"
|
15
|
+
live_call_routing:
|
16
|
+
twilio:
|
17
|
+
v3:
|
18
|
+
form_options:
|
19
|
+
option_account_sid_hint_html: "Twilio Account SID"
|
20
|
+
option_api_key_hint_html: "Twilio API Key"
|
21
|
+
option_api_secret_hint_html: "Twilio API Secret"
|
22
|
+
option_welcome_media_hint_html: "A recording that will be played first to caller (ex: \"Hello, you have reached the Devop's on-call support line.\")"
|
23
|
+
option_please_wait_media_hint_html: "A recording to be played before wait music music (default: <a href='https://app.pagertree.com/assets/sounds/please-wait.mp3' target='_blank'>Please wait while you are being connected.</a>)"
|
24
|
+
option_music_media_hint_html: "A recording or wait music to be played while the caller waits for someone to acknowledge the alert (default: <a href='http://com.twilio.sounds.music.s3.amazonaws.com/oldDog_-_endless_goodbye_%28instr.%29.mp3' target='_blank'>Endless Goodbye</a>)"
|
25
|
+
option_connect_now_media_hint_html: "A recording played before connecting the caller to the acknowledger (default: <a href='https://app.pagertree.com/assets/sounds/you-are-now-being-connected.mp3' target='_blank'>You are now being connected.</a>)"
|
26
|
+
option_no_answer_media_hint_html: "A recording to be played when no one answers"
|
27
|
+
option_no_answer_thank_you_media_hint_html: "A recording played after the caller leaves a voicemail"
|
28
|
+
option_force_input_hint_html: "Force the caller to select a team (even if the integration only has one team)"
|
29
|
+
option_record_hint_html: "Record a voicemail when no one acknowledges the call"
|
30
|
+
option_record_emails_list_hint_html: "List of email addresses to notify when a voicemail has been recorded"
|
31
|
+
outgoing_webhook:
|
32
|
+
v3:
|
33
|
+
form_options:
|
34
|
+
option_webhook_url_hint_html: "URL to POST to"
|
35
|
+
option_username_hint_html: "Basic auth username (optional)"
|
36
|
+
option_password_hint_html: "Basic auth password (optional)"
|
37
|
+
option_alert_created_hint_html: "Send when the alert is created (before its routed)"
|
38
|
+
option_alert_open_hint_html: "Send when the alert is marked open (it has been routed)"
|
39
|
+
option_alert_acknowledged_hint_html: "Send when a user has acknowledged the alert"
|
40
|
+
option_alert_rejected_hint_html: "Send when a user has rejected the alert"
|
41
|
+
option_alert_timeout_hint_html: "Send when the alert has timed out a layer"
|
42
|
+
option_alert_resolved_hint_html: "Send when the alert is marked resolved"
|
43
|
+
option_alert_dropped_hint_html: "Send when the alert is dropped"
|
44
|
+
option_alert_handoff_hint_html: "Send when the alert has been handed off"
|
45
|
+
option_template_hint_html: "A handlebars template describing the body that should be posted. See <a href='https://pagertree.com/knowledge-base/outgoing-webhooks/#custom-format' target='_blank'>docs</a> for details."
|
46
|
+
option_send_linked_hint_html: "Send linked data (source, source_log, user, team)"
|
47
|
+
# SCAFFOLD_INTEGRATION
|
48
|
+
|
49
|
+
|
50
|
+
activerecord:
|
51
|
+
attributes:
|
52
|
+
"pager_tree/integrations/integration":
|
53
|
+
option_title_template_enabled: "Title Template"
|
54
|
+
option_description_template_enabled: "Description Template"
|
55
|
+
"pager_tree/integrations/apex_ping/v3":
|
56
|
+
option_api_key: "API Key"
|
57
|
+
"pager_tree/integrations/email/v3":
|
58
|
+
option_allow_spam: "Allow Spam"
|
59
|
+
option_dedup_threads: "Dedup Threads"
|
60
|
+
"pager_tree/integrations/outgoing_webhook/v3":
|
61
|
+
option_webhook_url: "URL"
|
62
|
+
option_username: "Username"
|
63
|
+
option_password: "Password"
|
64
|
+
option_alert_created: "alert.created"
|
65
|
+
option_alert_open: "alert.open"
|
66
|
+
option_alert_acknowledged: "alert.acknowledged"
|
67
|
+
option_alert_rejected: "alert.rejected"
|
68
|
+
option_alert_timeout: "alert.timeout"
|
69
|
+
option_alert_resolved: "alert.resolved"
|
70
|
+
option_alert_dropped: "alert.dropped"
|
71
|
+
option_alert_handoff: "alert.handoff"
|
72
|
+
option_template: "JSON Template"
|
73
|
+
option_send_linked: "Send Linked"
|
74
|
+
"pager_tree/integrations/live_call_routing/twilio/v3":
|
75
|
+
option_account_sid: "Twilio Account SID"
|
76
|
+
option_api_key: "Twilio API Key"
|
77
|
+
option_api_secret: "Twilio API Secret"
|
78
|
+
option_welcome_media: "Welcome Recording"
|
79
|
+
option_please_wait_media: "Before Wait Music Recording"
|
80
|
+
option_music_media: "Wait Music Recording"
|
81
|
+
option_connect_now_media: "Before Connect Recording"
|
82
|
+
option_no_answer_media: "Voicemail Greeting Recording"
|
83
|
+
option_no_answer_thank_you_media: "After Voicemail Recording"
|
84
|
+
option_force_input: "Force Caller Input"
|
85
|
+
option_record: "Voicemail"
|
86
|
+
option_record_emails_list: "Voicemail Emails"
|
87
|
+
# SCAFFOLD_ACTIVE_RECORD
|
data/config/routes.rb
ADDED