pager_tree-integrations 1.1.6 → 1.1.7
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 +4 -4
- data/app/controllers/pager_tree/integrations/live_call_routing/twilio/v3_controller.rb +20 -0
- data/app/jobs/pager_tree/integrations/live_call_routing/twilio/v3/max_wait_time_job.rb +13 -0
- data/app/models/pager_tree/integrations/additional_datum.rb +2 -2
- data/app/models/pager_tree/integrations/alert.rb +2 -2
- data/app/models/pager_tree/integrations/aws_cloudwatch/v3.rb +15 -5
- data/app/models/pager_tree/integrations/boolean_store_accessor.rb +2 -2
- data/app/models/pager_tree/integrations/channel/hangouts/v3.rb +23 -2
- data/app/models/pager_tree/integrations/channel/mattermost/v3.rb +4 -0
- data/app/models/pager_tree/integrations/channel/microsoft_teams/v3.rb +74 -29
- data/app/models/pager_tree/integrations/channel/microsoft_teams/v4.rb +261 -0
- data/app/models/pager_tree/integrations/channel/slack/v3.rb +30 -3
- data/app/models/pager_tree/integrations/cloudflare/v3.rb +75 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3.rb +206 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/datadog.json +12 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/datadog.yaml +30 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/generic_rules_definition.json +9 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/generic_rules_example.yaml +27 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/grafana.json +25 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/grafana.yaml +33 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/new_relic.json +40 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/new_relic.yaml +32 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/pingdom.json +30 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/pingdom.yaml +23 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/sns_cloudwatch.json +12 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/sns_cloudwatch.yaml +48 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/sns_health_event.json +21 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/sns_health_event.yaml +43 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/sns_lambda_monitor.json +31 -0
- data/app/models/pager_tree/integrations/custom_webhook/v3_examples/sns_lambda_monitor.yaml +24 -0
- data/app/models/pager_tree/integrations/datadog/v3.rb +10 -3
- data/app/models/pager_tree/integrations/dynatrace/v3.rb +67 -0
- data/app/models/pager_tree/integrations/echoes_hq/v3.rb +138 -0
- data/app/models/pager_tree/integrations/elast_alert/v3.rb +24 -0
- data/app/models/pager_tree/integrations/email/v3.rb +272 -22
- data/app/models/pager_tree/integrations/email/v3_examples/example.yml +24 -0
- data/app/models/pager_tree/integrations/form/v3.rb +15 -3
- data/app/models/pager_tree/integrations/freshdesk/v3.rb +7 -5
- data/app/models/pager_tree/integrations/freshservice/v3.rb +7 -5
- data/app/models/pager_tree/integrations/grafana/v3.rb +2 -2
- data/app/models/pager_tree/integrations/hetrix_tools/v3.rb +160 -0
- data/app/models/pager_tree/integrations/honeybadger/v3.rb +1 -1
- data/app/models/pager_tree/integrations/hydrozen/v3.rb +6 -0
- data/app/models/pager_tree/integrations/integration.rb +52 -9
- data/app/models/pager_tree/integrations/jira_server/v3.rb +12 -2
- data/app/models/pager_tree/integrations/kapacitor/v3.rb +1 -1
- data/app/models/pager_tree/integrations/live_call_routing/twilio/v3.rb +257 -22
- data/app/models/pager_tree/integrations/logic_monitor/v3.rb +193 -3
- data/app/models/pager_tree/integrations/mattermost/outgoing_webhook/v3.rb +1 -1
- data/app/models/pager_tree/integrations/meta/workplace/v3.rb +230 -0
- data/app/models/pager_tree/integrations/new_relic/v3.rb +9 -5
- data/app/models/pager_tree/integrations/outgoing_event.rb +8 -0
- data/app/models/pager_tree/integrations/outgoing_webhook/v3.rb +108 -13
- data/app/models/pager_tree/integrations/outgoing_webhook_delivery/hook_relay.rb +43 -33
- data/app/models/pager_tree/integrations/outgoing_webhook_delivery.rb +6 -5
- data/app/models/pager_tree/integrations/prtg/v3.rb +2 -1
- data/app/models/pager_tree/integrations/pulsetic/v3.rb +70 -0
- data/app/models/pager_tree/integrations/scom/pagertree.ps1 +153 -0
- data/app/models/pager_tree/integrations/scom/v3.rb +58 -0
- data/app/models/pager_tree/integrations/sentry/v3.rb +477 -0
- data/app/models/pager_tree/integrations/server_guard24/v3.rb +1 -1
- data/app/models/pager_tree/integrations/sixty_six_uptime/v3.rb +118 -0
- data/app/models/pager_tree/integrations/slack/webhook/v3.rb +1 -1
- data/app/models/pager_tree/integrations/solar_winds/v3.rb +66 -2
- data/app/models/pager_tree/integrations/status_gator/v3.rb +69 -0
- data/app/models/pager_tree/integrations/uptime_kuma/v3.rb +76 -0
- data/app/models/pager_tree/integrations/uptime_robot/v3.rb +6 -0
- data/app/models/pager_tree/integrations/webhook/v3.rb +25 -7
- data/app/models/pager_tree/integrations/zabbix/v3.rb +95 -0
- data/app/models/pager_tree/integrations/zendesk/v3.rb +2 -0
- data/app/views/pager_tree/integrations/channel/hangouts/v3/_form_options.html.erb +7 -0
- data/app/views/pager_tree/integrations/channel/hangouts/v3/_show_options.html.erb +10 -0
- data/app/views/pager_tree/integrations/channel/microsoft_teams/v3/_form_options.html.erb +7 -0
- data/app/views/pager_tree/integrations/channel/microsoft_teams/v3/_show_options.html.erb +14 -0
- data/app/views/pager_tree/integrations/channel/microsoft_teams/v4/_form_options.html.erb +41 -0
- data/app/views/pager_tree/integrations/channel/microsoft_teams/v4/_show_options.html.erb +54 -0
- data/app/views/pager_tree/integrations/channel/slack/v3/_form_options.html.erb +6 -3
- data/app/views/pager_tree/integrations/channel/slack/v3/_show_options.html.erb +1 -1
- data/app/views/pager_tree/integrations/cloudflare/v3/_form_options.html.erb +7 -0
- data/app/views/pager_tree/integrations/cloudflare/v3/_show_options.html.erb +12 -0
- data/app/views/pager_tree/integrations/custom_webhook/v3/_form_options.html.erb +8 -0
- data/app/views/pager_tree/integrations/custom_webhook/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/datadog/v3/_form_options.html.erb +7 -0
- data/app/views/pager_tree/integrations/datadog/v3/_show_options.html.erb +12 -0
- data/app/views/pager_tree/integrations/dynatrace/v3/_form_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/dynatrace/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/echoes_hq/v3/_form_options.html.erb +10 -0
- data/app/views/pager_tree/integrations/echoes_hq/v3/_show_options.html.erb +12 -0
- data/app/views/pager_tree/integrations/email/v3/_form_options.html.erb +41 -11
- data/app/views/pager_tree/integrations/email/v3/_show_options.html.erb +18 -0
- data/app/views/pager_tree/integrations/form/v3/_form_options.html.erb +1 -5
- data/app/views/pager_tree/integrations/hetrix_tools/v3/_form_options.html.erb +7 -0
- data/app/views/pager_tree/integrations/hetrix_tools/v3/_show_options.html.erb +12 -0
- data/app/views/pager_tree/integrations/hydrozen/v3/_form_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/hydrozen/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/live_call_routing/twilio/v3/_form_options.html.erb +44 -31
- data/app/views/pager_tree/integrations/live_call_routing/twilio/v3/_show_options.html.erb +93 -8
- data/app/views/pager_tree/integrations/logic_monitor/v3/_form_options.html.erb +31 -0
- data/app/views/pager_tree/integrations/logic_monitor/v3/_show_options.html.erb +60 -0
- data/app/views/pager_tree/integrations/meta/workplace/v3/_form_options.html.erb +44 -0
- data/app/views/pager_tree/integrations/meta/workplace/v3/_show_options.html.erb +68 -0
- data/app/views/pager_tree/integrations/outgoing_webhook/v3/_form_options.html.erb +17 -3
- data/app/views/pager_tree/integrations/outgoing_webhook/v3/_show_options.html.erb +20 -0
- data/app/views/pager_tree/integrations/pulsetic/v3/_form_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/pulsetic/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/scom/v3/_form_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/scom/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/sentry/v3/_form_options.html.erb +9 -0
- data/app/views/pager_tree/integrations/sentry/v3/_show_options.html.erb +15 -0
- data/app/views/pager_tree/integrations/sixty_six_uptime/v3/_form_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/sixty_six_uptime/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/solar_winds/v3/_form_options.html.erb +40 -0
- data/app/views/pager_tree/integrations/solar_winds/v3/_show_options.html.erb +66 -0
- data/app/views/pager_tree/integrations/status_gator/v3/_form_options.html.erb +13 -0
- data/app/views/pager_tree/integrations/status_gator/v3/_show_options.html.erb +24 -0
- data/app/views/pager_tree/integrations/uptime_kuma/v3/_form_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/uptime_kuma/v3/_show_options.html.erb +0 -0
- data/app/views/pager_tree/integrations/webhook/v3/_form_options.html.erb +8 -0
- data/app/views/pager_tree/integrations/webhook/v3/_show_options.html.erb +15 -0
- data/app/views/pager_tree/integrations/zabbix/v3/_form_options.html.erb +7 -0
- data/app/views/pager_tree/integrations/zabbix/v3/_show_options.html.erb +12 -0
- data/config/locales/en.yml +158 -10
- data/config/routes.rb +1 -0
- data/lib/pager_tree/integrations/format_converters/yaml_json_converter.rb +67 -0
- data/lib/pager_tree/integrations/version.rb +1 -1
- data/lib/pager_tree/integrations.rb +11 -3
- metadata +84 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e60138a7eaeb7128332e9d7f95da9b65ad6dd06261ee1a2ee65a0ad31fe976d0
|
|
4
|
+
data.tar.gz: 3f53f3781b4b97087d229235d4daf839cbccb05be9b0ba39ea51aa95c7648494
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c5f3e96aff985e486fd6375c6273ec7d433f011ab3164c0d611070cb1449c830c9c2a7a480e0ae1c4678e82440376c0a86cd26c93c54c76c42ca85634379325
|
|
7
|
+
data.tar.gz: 58ee61238c88f38785392782373f359c1af77b6173d28b45a8292dc13d406f63f31ea116e2682aa61711b33f16d2bc26cd3d5f0bb41f1c6338cef016b4093ea5
|
|
@@ -27,6 +27,12 @@ module PagerTree::Integrations
|
|
|
27
27
|
head :ok
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def call_status
|
|
31
|
+
::PagerTree::Integrations.deferred_request_class.constantize.perform_later_from_request!(request)
|
|
32
|
+
|
|
33
|
+
head :ok
|
|
34
|
+
end
|
|
35
|
+
|
|
30
36
|
def queue_status_deferred(deferred_request)
|
|
31
37
|
params = deferred_request.params
|
|
32
38
|
|
|
@@ -42,6 +48,20 @@ module PagerTree::Integrations
|
|
|
42
48
|
@integration.adapter_process_queue_status_deferred
|
|
43
49
|
end
|
|
44
50
|
|
|
51
|
+
def call_status_deferred(deferred_request)
|
|
52
|
+
params = deferred_request.params
|
|
53
|
+
|
|
54
|
+
id = params.dig("id")
|
|
55
|
+
@integration = find_integration(id)
|
|
56
|
+
|
|
57
|
+
deferred_request.account_id = @integration.account_id
|
|
58
|
+
@integration.adapter_source_log = @integration.logs.create!(level: :info, format: :json, message: deferred_request.request) if @integration.log_incoming_requests?
|
|
59
|
+
@integration.adapter_incoming_request_params = params
|
|
60
|
+
@integration.adapter_incoming_deferred_request = deferred_request
|
|
61
|
+
|
|
62
|
+
@integration.adapter_process_call_status_deferred
|
|
63
|
+
end
|
|
64
|
+
|
|
45
65
|
private
|
|
46
66
|
|
|
47
67
|
def set_integration
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class PagerTree::Integrations::LiveCallRouting::Twilio::V3::MaxWaitTimeJob < ApplicationJob
|
|
2
|
+
queue_as :default
|
|
3
|
+
|
|
4
|
+
def perform(*args)
|
|
5
|
+
integration_id = args[0]
|
|
6
|
+
alert_id = args[1]
|
|
7
|
+
|
|
8
|
+
integration = Integration.find(integration_id)
|
|
9
|
+
integration.max_wait_time_reached!(alert_id)
|
|
10
|
+
rescue => e
|
|
11
|
+
Rails.logger.error("MaxWaitTimeJob failed: #{e.message}")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -47,12 +47,12 @@ module PagerTree::Integrations
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def incident?
|
|
50
|
-
ActiveModel::Type::Boolean.new.cast(
|
|
50
|
+
ActiveModel::Type::Boolean.new.cast(incident)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def push_additional_data(additional_datum)
|
|
54
54
|
if additional_datum.valid?
|
|
55
|
-
|
|
55
|
+
additional_data.push(additional_datum.to_h)
|
|
56
56
|
true
|
|
57
57
|
else
|
|
58
58
|
false
|
|
@@ -12,7 +12,7 @@ module PagerTree::Integrations
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def adapter_should_block_incoming?(request)
|
|
15
|
-
|
|
15
|
+
false
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def adapter_thirdparty_id
|
|
@@ -41,19 +41,29 @@ module PagerTree::Integrations
|
|
|
41
41
|
|
|
42
42
|
def adapter_process_other
|
|
43
43
|
if _type == "SubscriptionConfirmation" || _type == "UnsubscribeConfirmation"
|
|
44
|
-
url =
|
|
44
|
+
url = _sns_notification.dig("SubscribeURL")
|
|
45
45
|
HTTParty.get(url) if url
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
private
|
|
50
50
|
|
|
51
|
+
# the sns notification is sent with a text/plain but the text is formatted as json
|
|
52
|
+
# need parse the text into json
|
|
53
|
+
def _sns_notification
|
|
54
|
+
@_sns_notification ||= begin
|
|
55
|
+
JSON.parse(adapter_incoming_deferred_request.body).with_indifferent_access
|
|
56
|
+
rescue
|
|
57
|
+
{}
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
51
61
|
def _type
|
|
52
|
-
@_type ||=
|
|
62
|
+
@_type ||= _sns_notification.dig("Type")
|
|
53
63
|
end
|
|
54
64
|
|
|
55
65
|
def _message
|
|
56
|
-
@_message ||=
|
|
66
|
+
@_message ||= _sns_notification.dig("Message")
|
|
57
67
|
end
|
|
58
68
|
|
|
59
69
|
def _json
|
|
@@ -67,7 +77,7 @@ module PagerTree::Integrations
|
|
|
67
77
|
|
|
68
78
|
def _thirdparty_id
|
|
69
79
|
[
|
|
70
|
-
|
|
80
|
+
_sns_notification.dig("TopicArn"),
|
|
71
81
|
_json.dig("AlarmName")
|
|
72
82
|
].join(":")
|
|
73
83
|
end
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
#
|
|
26
26
|
module PagerTree::Integrations::BooleanStoreAccessor
|
|
27
27
|
def boolean_store_accessor(attr_name)
|
|
28
|
-
define_method "#{attr_name}="
|
|
28
|
+
define_method :"#{attr_name}=" do |value|
|
|
29
29
|
values = ["1", true]
|
|
30
30
|
super(values.include?(value))
|
|
31
31
|
end
|
|
@@ -35,7 +35,7 @@ module PagerTree::Integrations::BooleanStoreAccessor
|
|
|
35
35
|
!values.include?(super())
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
define_method "#{attr_name}?"
|
|
38
|
+
define_method :"#{attr_name}?" do
|
|
39
39
|
send(attr_name)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -3,9 +3,11 @@ module PagerTree::Integrations
|
|
|
3
3
|
OPTIONS = [
|
|
4
4
|
{key: :incoming_webhook_url, type: :string, default: nil},
|
|
5
5
|
{key: :alert_open, type: :boolean, default: false},
|
|
6
|
+
{key: :alert_assigned, type: :boolean, default: false},
|
|
6
7
|
{key: :alert_acknowledged, type: :boolean, default: false},
|
|
7
8
|
{key: :alert_resolved, type: :boolean, default: false},
|
|
8
9
|
{key: :alert_dropped, type: :boolean, default: false},
|
|
10
|
+
{key: :thread_same_alert, type: :boolean, default: false},
|
|
9
11
|
{key: :outgoing_rules, type: :string, default: nil}
|
|
10
12
|
]
|
|
11
13
|
store_accessor :options, *OPTIONS.map { |x| x[:key] }.map(&:to_s), prefix: "option"
|
|
@@ -15,9 +17,11 @@ module PagerTree::Integrations
|
|
|
15
17
|
after_initialize do
|
|
16
18
|
self.option_incoming_webhook_url ||= nil
|
|
17
19
|
self.option_alert_open ||= false
|
|
20
|
+
self.option_alert_assigned ||= false
|
|
18
21
|
self.option_alert_acknowledged ||= false
|
|
19
22
|
self.option_alert_resolved ||= false
|
|
20
23
|
self.option_alert_dropped ||= false
|
|
24
|
+
self.option_thread_same_alert ||= false
|
|
21
25
|
self.option_outgoing_rules ||= ""
|
|
22
26
|
end
|
|
23
27
|
|
|
@@ -41,14 +45,31 @@ module PagerTree::Integrations
|
|
|
41
45
|
false
|
|
42
46
|
end
|
|
43
47
|
|
|
48
|
+
def adapter_supports_auto_aggregate?
|
|
49
|
+
false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def adapter_supports_auto_resolve?
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
44
56
|
def adapter_outgoing_interest?(event_name)
|
|
45
57
|
try("option_#{event_name}") || false
|
|
46
58
|
end
|
|
47
59
|
|
|
48
60
|
def adapter_process_outgoing
|
|
49
|
-
url = adapter_outgoing_event.outgoing_rules_data.dig("webhook_url") ||
|
|
61
|
+
url = adapter_outgoing_event.outgoing_rules_data.dig("webhook_url") || option_incoming_webhook_url
|
|
50
62
|
body = _blocks.merge(adapter_outgoing_event.outgoing_rules_data.except("webhook_url"))
|
|
51
63
|
|
|
64
|
+
if option_thread_same_alert == true
|
|
65
|
+
body[:thread] = {threadKey: _alert.id}
|
|
66
|
+
|
|
67
|
+
uri = URI(url)
|
|
68
|
+
uri_params = URI.decode_www_form(uri.query || "").to_h.merge({messageReplyOption: "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"})
|
|
69
|
+
uri.query = URI.encode_www_form(uri_params)
|
|
70
|
+
url = uri.to_s
|
|
71
|
+
end
|
|
72
|
+
|
|
52
73
|
outgoing_webhook_delivery = OutgoingWebhookDelivery.factory(
|
|
53
74
|
resource: self,
|
|
54
75
|
url: url,
|
|
@@ -131,7 +152,7 @@ module PagerTree::Integrations
|
|
|
131
152
|
text: "VIEW IN PAGERTREE",
|
|
132
153
|
onClick: {
|
|
133
154
|
openLink: {
|
|
134
|
-
url:
|
|
155
|
+
url: Rails.application.routes.url_helpers.try(:alert_url, _alert, script_name: "/#{_alert.account_id}")
|
|
135
156
|
}
|
|
136
157
|
}
|
|
137
158
|
}
|
|
@@ -2,5 +2,9 @@ module PagerTree::Integrations
|
|
|
2
2
|
class Channel::Mattermost::V3 < Channel::Slack::V3
|
|
3
3
|
# we can just piggy back the Channel::Slack::V3 since Mattermost is a clone of Slack
|
|
4
4
|
# both integrations have the same exact functionality
|
|
5
|
+
|
|
6
|
+
def _alert_created_at_timestamp_formatted
|
|
7
|
+
_alert.created_at.utc.iso8601.to_s
|
|
8
|
+
end
|
|
5
9
|
end
|
|
6
10
|
end
|
|
@@ -6,11 +6,14 @@ module PagerTree::Integrations
|
|
|
6
6
|
{key: :alert_acknowledged, type: :boolean, default: false},
|
|
7
7
|
{key: :alert_resolved, type: :boolean, default: false},
|
|
8
8
|
{key: :alert_dropped, type: :boolean, default: false},
|
|
9
|
-
{key: :outgoing_rules, type: :string, default: nil}
|
|
9
|
+
{key: :outgoing_rules, type: :string, default: nil},
|
|
10
|
+
{key: :time_zone, type: :string, default: nil},
|
|
11
|
+
{key: :compact_message, type: :boolean, default: false}
|
|
10
12
|
]
|
|
11
13
|
store_accessor :options, *OPTIONS.map { |x| x[:key] }.map(&:to_s), prefix: "option"
|
|
12
14
|
|
|
13
15
|
validates :option_incoming_webhook_url, presence: true, url: {no_local: true}
|
|
16
|
+
validate :validate_time_zone_exists
|
|
14
17
|
|
|
15
18
|
after_initialize do
|
|
16
19
|
self.option_incoming_webhook_url ||= nil
|
|
@@ -19,6 +22,12 @@ module PagerTree::Integrations
|
|
|
19
22
|
self.option_alert_resolved ||= false
|
|
20
23
|
self.option_alert_dropped ||= false
|
|
21
24
|
self.option_outgoing_rules ||= ""
|
|
25
|
+
self.option_time_zone ||= "UTC"
|
|
26
|
+
self.option_compact_message ||= false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def converts_to
|
|
30
|
+
"PagerTree::Integrations::Channel::MicrosoftTeams::V4"
|
|
22
31
|
end
|
|
23
32
|
|
|
24
33
|
def adapter_supports_incoming?
|
|
@@ -41,12 +50,20 @@ module PagerTree::Integrations
|
|
|
41
50
|
false
|
|
42
51
|
end
|
|
43
52
|
|
|
53
|
+
def adapter_supports_auto_aggregate?
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def adapter_supports_auto_resolve?
|
|
58
|
+
false
|
|
59
|
+
end
|
|
60
|
+
|
|
44
61
|
def adapter_outgoing_interest?(event_name)
|
|
45
62
|
try("option_#{event_name}") || false
|
|
46
63
|
end
|
|
47
64
|
|
|
48
65
|
def adapter_process_outgoing
|
|
49
|
-
url = adapter_outgoing_event.outgoing_rules_data.dig("webhook_url") ||
|
|
66
|
+
url = adapter_outgoing_event.outgoing_rules_data.dig("webhook_url") || option_incoming_webhook_url
|
|
50
67
|
body = _blocks.merge(adapter_outgoing_event.outgoing_rules_data.except("webhook_url"))
|
|
51
68
|
|
|
52
69
|
outgoing_webhook_delivery = OutgoingWebhookDelivery.factory(
|
|
@@ -67,6 +84,12 @@ module PagerTree::Integrations
|
|
|
67
84
|
end
|
|
68
85
|
|
|
69
86
|
def _blocks
|
|
87
|
+
facts = if option_compact_message
|
|
88
|
+
_compact_facts
|
|
89
|
+
else
|
|
90
|
+
_full_facts
|
|
91
|
+
end
|
|
92
|
+
|
|
70
93
|
{
|
|
71
94
|
"@type": "MessageCard",
|
|
72
95
|
"@context": "http://schema.org/extensions",
|
|
@@ -74,33 +97,8 @@ module PagerTree::Integrations
|
|
|
74
97
|
summary: _title,
|
|
75
98
|
sections: [{
|
|
76
99
|
activityTitle: _title,
|
|
77
|
-
activitySubtitle: _alert.description&.try(:to_plain_text),
|
|
78
|
-
facts:
|
|
79
|
-
{
|
|
80
|
-
name: "Status",
|
|
81
|
-
value: _alert.status.upcase
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: "Urgency",
|
|
85
|
-
value: _alert.urgency.upcase
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: "Created",
|
|
89
|
-
value: _alert.created_at.utc
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
name: "Source",
|
|
93
|
-
value: _alert.source&.name
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: "Destinations",
|
|
97
|
-
value: _alert.alert_destinations&.map { |d| d.destination.name }&.join(", ")
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: "User",
|
|
101
|
-
value: _alert.alert_responders&.where(role: :incident_commander)&.includes(account_user: :user)&.first&.account_user&.name
|
|
102
|
-
}
|
|
103
|
-
],
|
|
100
|
+
activitySubtitle: option_compact_message ? nil : _alert.description&.try(:to_plain_text),
|
|
101
|
+
facts: facts,
|
|
104
102
|
markdown: true
|
|
105
103
|
}],
|
|
106
104
|
potentialAction: [
|
|
@@ -116,6 +114,48 @@ module PagerTree::Integrations
|
|
|
116
114
|
}
|
|
117
115
|
end
|
|
118
116
|
|
|
117
|
+
def _compact_facts
|
|
118
|
+
[
|
|
119
|
+
{
|
|
120
|
+
name: "Status",
|
|
121
|
+
value: _alert.status.upcase
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "User",
|
|
125
|
+
value: _alert.alert_responders&.where(role: :incident_commander)&.includes(account_user: :user)&.first&.account_user&.name
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def _full_facts
|
|
131
|
+
[
|
|
132
|
+
{
|
|
133
|
+
name: "Status",
|
|
134
|
+
value: _alert.status.upcase
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "Urgency",
|
|
138
|
+
value: _alert.urgency.upcase
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "Created",
|
|
142
|
+
value: _alert.created_at.in_time_zone(option_time_zone).iso8601
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "Source",
|
|
146
|
+
value: _alert.source&.name
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "Destinations",
|
|
150
|
+
value: _alert.alert_destinations&.map { |d| d.destination.name }&.join(", ")
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "User",
|
|
154
|
+
value: _alert.alert_responders&.where(role: :incident_commander)&.includes(account_user: :user)&.first&.account_user&.name
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
end
|
|
158
|
+
|
|
119
159
|
def _title
|
|
120
160
|
return @_title if @_title.present?
|
|
121
161
|
|
|
@@ -138,5 +178,10 @@ module PagerTree::Integrations
|
|
|
138
178
|
"#555555"
|
|
139
179
|
end
|
|
140
180
|
end
|
|
181
|
+
|
|
182
|
+
def validate_time_zone_exists
|
|
183
|
+
return if option_time_zone.present? && ActiveSupport::TimeZone[option_time_zone].present?
|
|
184
|
+
errors.add(:option_time_zone, "does not exist")
|
|
185
|
+
end
|
|
141
186
|
end
|
|
142
187
|
end
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
module PagerTree::Integrations
|
|
2
|
+
class Channel::MicrosoftTeams::V4 < Integration
|
|
3
|
+
OPTIONS = [
|
|
4
|
+
{key: :incoming_webhook_url, type: :string, default: nil},
|
|
5
|
+
{key: :alert_open, type: :boolean, default: false},
|
|
6
|
+
{key: :alert_acknowledged, type: :boolean, default: false},
|
|
7
|
+
{key: :alert_resolved, type: :boolean, default: false},
|
|
8
|
+
{key: :alert_dropped, type: :boolean, default: false},
|
|
9
|
+
{key: :outgoing_rules, type: :string, default: nil},
|
|
10
|
+
{key: :time_zone, type: :string, default: nil},
|
|
11
|
+
{key: :compact_message, type: :boolean, default: false}
|
|
12
|
+
]
|
|
13
|
+
store_accessor :options, *OPTIONS.map { |x| x[:key] }.map(&:to_s), prefix: "option"
|
|
14
|
+
|
|
15
|
+
validates :option_incoming_webhook_url, presence: true, url: {no_local: true}
|
|
16
|
+
validate :validate_time_zone_exists
|
|
17
|
+
|
|
18
|
+
after_initialize do
|
|
19
|
+
self.option_incoming_webhook_url ||= nil
|
|
20
|
+
self.option_alert_open ||= false
|
|
21
|
+
self.option_alert_acknowledged ||= false
|
|
22
|
+
self.option_alert_resolved ||= false
|
|
23
|
+
self.option_alert_dropped ||= false
|
|
24
|
+
self.option_outgoing_rules ||= ""
|
|
25
|
+
self.option_time_zone ||= "UTC"
|
|
26
|
+
self.option_compact_message ||= false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def adapter_supports_incoming?
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def adapter_supports_outgoing?
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def adapter_show_outgoing_webhook_delivery?
|
|
38
|
+
true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def adapter_supports_title_template?
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def adapter_supports_description_template?
|
|
46
|
+
false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def adapter_supports_auto_aggregate?
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def adapter_supports_auto_resolve?
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def adapter_outgoing_interest?(event_name)
|
|
58
|
+
try("option_#{event_name}") || false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def adapter_process_outgoing
|
|
62
|
+
url = adapter_outgoing_event.outgoing_rules_data.dig("webhook_url") || option_incoming_webhook_url
|
|
63
|
+
body = _blocks.merge(adapter_outgoing_event.outgoing_rules_data.except("webhook_url"))
|
|
64
|
+
|
|
65
|
+
outgoing_webhook_delivery = OutgoingWebhookDelivery.factory(
|
|
66
|
+
resource: self,
|
|
67
|
+
url: url,
|
|
68
|
+
body: body
|
|
69
|
+
)
|
|
70
|
+
outgoing_webhook_delivery.save!
|
|
71
|
+
outgoing_webhook_delivery.deliver_later
|
|
72
|
+
|
|
73
|
+
outgoing_webhook_delivery
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def _alert
|
|
79
|
+
@_alert ||= adapter_outgoing_event.alert
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def _blocks
|
|
83
|
+
body = if option_compact_message
|
|
84
|
+
_compact_body
|
|
85
|
+
else
|
|
86
|
+
_full_body
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
{
|
|
90
|
+
type: "message",
|
|
91
|
+
attachments: [
|
|
92
|
+
{
|
|
93
|
+
contentType: "application/vnd.microsoft.card.adaptive",
|
|
94
|
+
contentUrl: nil,
|
|
95
|
+
content: {
|
|
96
|
+
type: "AdaptiveCard",
|
|
97
|
+
body: body,
|
|
98
|
+
actions: [
|
|
99
|
+
{
|
|
100
|
+
type: "Action.OpenUrl",
|
|
101
|
+
title: "View",
|
|
102
|
+
url: Rails.application.routes.url_helpers.try(:alert_url, _alert, script_name: "/#{_alert.account_id}"),
|
|
103
|
+
style: "positive"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
|
107
|
+
version: "1.2"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def _compact_body
|
|
115
|
+
[
|
|
116
|
+
{
|
|
117
|
+
type: "Container",
|
|
118
|
+
backgroundImage: _color,
|
|
119
|
+
items: [
|
|
120
|
+
{
|
|
121
|
+
type: "TextBlock",
|
|
122
|
+
size: "Large",
|
|
123
|
+
weight: "Bolder",
|
|
124
|
+
text: _title
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
type: "FactSet",
|
|
128
|
+
facts: [
|
|
129
|
+
{
|
|
130
|
+
title: "Status:",
|
|
131
|
+
value: _alert.status&.upcase
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
title: "User:",
|
|
135
|
+
value: _alert.alert_responders&.where(role: :incident_commander)&.includes(account_user: :user)&.first&.account_user&.name
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
spacing: "ExtraSmall"
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def _full_body
|
|
146
|
+
[
|
|
147
|
+
{
|
|
148
|
+
type: "Container",
|
|
149
|
+
backgroundImage: _color,
|
|
150
|
+
items: [
|
|
151
|
+
{
|
|
152
|
+
type: "TextBlock",
|
|
153
|
+
size: "Large",
|
|
154
|
+
weight: "Bolder",
|
|
155
|
+
text: _title
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
type: "ColumnSet",
|
|
159
|
+
columns: [
|
|
160
|
+
{
|
|
161
|
+
type: "Column",
|
|
162
|
+
items: [
|
|
163
|
+
{
|
|
164
|
+
type: "TextBlock",
|
|
165
|
+
weight: "Bolder",
|
|
166
|
+
text: _title,
|
|
167
|
+
wrap: true
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: "TextBlock",
|
|
171
|
+
spacing: "None",
|
|
172
|
+
text: "Created #{_alert.created_at.in_time_zone(option_time_zone).iso8601}",
|
|
173
|
+
wrap: true
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
width: "stretch"
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
type: "Container",
|
|
184
|
+
items: [
|
|
185
|
+
{
|
|
186
|
+
type: "FactSet",
|
|
187
|
+
facts: [
|
|
188
|
+
{
|
|
189
|
+
title: "Status:",
|
|
190
|
+
value: _alert.status&.upcase
|
|
191
|
+
}, {
|
|
192
|
+
title: "Urgency:",
|
|
193
|
+
value: _alert.urgency&.upcase
|
|
194
|
+
}, {
|
|
195
|
+
title: "Source:",
|
|
196
|
+
value: _alert.source&.name
|
|
197
|
+
}, {
|
|
198
|
+
title: "Destinations:",
|
|
199
|
+
value: _alert.alert_destinations&.map { |d| d.destination.name }&.join(", ")
|
|
200
|
+
}, {
|
|
201
|
+
title: "User:",
|
|
202
|
+
value: _alert.alert_responders&.where(role: :incident_commander)&.includes(account_user: :user)&.first&.account_user&.name
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
spacing: "None"
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
spacing: "Medium"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
type: "Container",
|
|
212
|
+
items: [
|
|
213
|
+
{
|
|
214
|
+
type: "TextBlock",
|
|
215
|
+
text: _alert.description&.try(:to_plain_text),
|
|
216
|
+
wrap: true,
|
|
217
|
+
separator: true,
|
|
218
|
+
maxLines: 24
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
type: "FactSet",
|
|
222
|
+
facts: _alert.additional_data&.map { |ad| {title: ad["label"], value: Array(ad["value"]).join(", ")} } || [],
|
|
223
|
+
spacing: "Medium",
|
|
224
|
+
separator: true
|
|
225
|
+
}
|
|
226
|
+
],
|
|
227
|
+
spacing: "Medium",
|
|
228
|
+
separator: true
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def _title
|
|
234
|
+
return @_title if @_title.present?
|
|
235
|
+
|
|
236
|
+
@_title = if _alert.incident?
|
|
237
|
+
"Incident ##{_alert.tiny_id} [#{_alert.incident_severity.upcase.dasherize}] #{_alert.incident_message} - #{_alert.title}"
|
|
238
|
+
else
|
|
239
|
+
"Alert ##{_alert.tiny_id} #{_alert.title}"
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def _color
|
|
244
|
+
case _alert.status
|
|
245
|
+
when "open", "dropped"
|
|
246
|
+
"https://pagertree.com/assets/img/icon/red-square.png"
|
|
247
|
+
when "acknowledged"
|
|
248
|
+
"https://pagertree.com/assets/img/icon/yellow-square.png"
|
|
249
|
+
when "resolved"
|
|
250
|
+
"https://pagertree.com/assets/img/icon/green-square.png"
|
|
251
|
+
else
|
|
252
|
+
"https://pagertree.com/assets/img/icon/grey-square.png"
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def validate_time_zone_exists
|
|
257
|
+
return if option_time_zone.present? && ActiveSupport::TimeZone[option_time_zone].present?
|
|
258
|
+
errors.add(:option_time_zone, "does not exist")
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|