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
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
module PagerTree::Integrations
|
|
2
2
|
class LogicMonitor::V3 < Integration
|
|
3
|
-
OPTIONS = [
|
|
3
|
+
OPTIONS = [
|
|
4
|
+
{key: :alert_acknowledged, type: :boolean, default: false},
|
|
5
|
+
{key: :logic_monitor_account_name, type: :string, default: nil},
|
|
6
|
+
{key: :access_id, type: :string, default: nil},
|
|
7
|
+
{key: :access_key, type: :string, default: nil},
|
|
8
|
+
{key: :bearer_token, type: :string, default: nil}
|
|
9
|
+
]
|
|
4
10
|
store_accessor :options, *OPTIONS.map { |x| x[:key] }.map(&:to_s), prefix: "option"
|
|
5
11
|
|
|
12
|
+
validates :option_alert_acknowledged, inclusion: {in: [true, false]}
|
|
13
|
+
validates :option_logic_monitor_account_name, presence: true, if: -> { option_alert_acknowledged == true }
|
|
14
|
+
validates :option_access_key, presence: true, if: -> { option_alert_acknowledged == true }
|
|
15
|
+
validates :option_access_id, presence: true, if: -> { option_alert_acknowledged == true }
|
|
16
|
+
validates :option_bearer_token, presence: true, if: -> { option_alert_acknowledged == true }
|
|
17
|
+
|
|
6
18
|
after_initialize do
|
|
19
|
+
self.option_alert_acknowledged = false if option_alert_acknowledged.nil?
|
|
7
20
|
end
|
|
8
21
|
|
|
9
22
|
def adapter_supports_incoming?
|
|
@@ -11,7 +24,15 @@ module PagerTree::Integrations
|
|
|
11
24
|
end
|
|
12
25
|
|
|
13
26
|
def adapter_supports_outgoing?
|
|
14
|
-
|
|
27
|
+
true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def adapter_outgoing_interest?(event_name)
|
|
31
|
+
try("option_#{event_name}") || false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def adapter_show_outgoing_webhook_delivery?
|
|
35
|
+
true
|
|
15
36
|
end
|
|
16
37
|
|
|
17
38
|
def adapter_incoming_can_defer?
|
|
@@ -19,7 +40,7 @@ module PagerTree::Integrations
|
|
|
19
40
|
end
|
|
20
41
|
|
|
21
42
|
def adapter_thirdparty_id
|
|
22
|
-
adapter_incoming_request_params.dig("
|
|
43
|
+
adapter_incoming_request_params.dig("internalid")
|
|
23
44
|
end
|
|
24
45
|
|
|
25
46
|
def adapter_action
|
|
@@ -27,6 +48,8 @@ module PagerTree::Integrations
|
|
|
27
48
|
case alert_status
|
|
28
49
|
when "active", "test"
|
|
29
50
|
:create
|
|
51
|
+
when "ack"
|
|
52
|
+
:acknowledge
|
|
30
53
|
when "clear"
|
|
31
54
|
:resolve
|
|
32
55
|
else
|
|
@@ -45,6 +68,15 @@ module PagerTree::Integrations
|
|
|
45
68
|
)
|
|
46
69
|
end
|
|
47
70
|
|
|
71
|
+
def adapter_process_outgoing
|
|
72
|
+
event = adapter_outgoing_event.event_name.to_s
|
|
73
|
+
|
|
74
|
+
# only send sync to logic monitor if logic monitor is the source
|
|
75
|
+
if event == "alert_acknowledged" && option_alert_acknowledged == true && adapter_outgoing_event.alert.source == self
|
|
76
|
+
_on_acknowledge
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
48
80
|
private
|
|
49
81
|
|
|
50
82
|
def _title
|
|
@@ -73,5 +105,163 @@ module PagerTree::Integrations
|
|
|
73
105
|
AdditionalDatum.new(format: "text", label: "Service", value: adapter_incoming_request_params.dig("service"))
|
|
74
106
|
]
|
|
75
107
|
end
|
|
108
|
+
|
|
109
|
+
def _on_acknowledge
|
|
110
|
+
lm_alert_id = adapter_outgoing_event.alert.thirdparty_id
|
|
111
|
+
acknowledger = adapter_outgoing_event.account_user&.name || name || "someone"
|
|
112
|
+
http_verb = "POST"
|
|
113
|
+
|
|
114
|
+
if adapter_outgoing_event.alert.source_log&.message&.dig("params", "alerttype") == "agentDownAlert"
|
|
115
|
+
# try to get the collector id
|
|
116
|
+
collector_id = lm_alert_id.gsub(/[^0-9]/, "")
|
|
117
|
+
resource_path = "/setting/collector/collectors/#{collector_id}/ackdown?v=2"
|
|
118
|
+
data = {comment: "Acknowledged by #{acknowledger}"}
|
|
119
|
+
send_request_with_bearer_token(resource_path, http_verb, data)
|
|
120
|
+
else
|
|
121
|
+
resource_path = "/alert/alerts/#{lm_alert_id}/ack"
|
|
122
|
+
data = {ackComment: "Acknowledged by #{acknowledger}"}
|
|
123
|
+
send_request_with_hmac(resource_path, http_verb, data)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# https://www.logicmonitor.com/support/rest-api-authentication
|
|
128
|
+
def send_request_with_hmac(resource_path, http_verb, data)
|
|
129
|
+
base_url = "https://#{option_logic_monitor_account_name}.logicmonitor.com/santaba/rest"
|
|
130
|
+
url = base_url + resource_path
|
|
131
|
+
timestamp_ms = Time.current.to_i * 1000
|
|
132
|
+
data_string = data.to_json
|
|
133
|
+
# https://gist.github.com/abeland/e09a559e243f70670f2f4da3fd0fdabd
|
|
134
|
+
signature = Base64.urlsafe_encode64(
|
|
135
|
+
OpenSSL::HMAC.hexdigest(
|
|
136
|
+
"SHA256",
|
|
137
|
+
option_access_key,
|
|
138
|
+
http_verb.upcase + timestamp_ms.to_s + data_string + resource_path
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
headers = {
|
|
142
|
+
"Content-Type" => "application/json",
|
|
143
|
+
"Authorization" => "LMv1 #{option_access_id}:#{signature}:#{timestamp_ms}"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# note outgoing webhook delivery only supports the post method
|
|
147
|
+
outgoing_webhook_delivery = OutgoingWebhookDelivery.factory(
|
|
148
|
+
resource: self,
|
|
149
|
+
url: url,
|
|
150
|
+
body: data,
|
|
151
|
+
options: {headers: headers}
|
|
152
|
+
)
|
|
153
|
+
outgoing_webhook_delivery.save!
|
|
154
|
+
outgoing_webhook_delivery.deliver_later
|
|
155
|
+
|
|
156
|
+
outgoing_webhook_delivery
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def send_request_with_bearer_token(resource_path, http_verb, data)
|
|
160
|
+
base_url = "https://#{option_logic_monitor_account_name}.logicmonitor.com/santaba/rest"
|
|
161
|
+
url = base_url + resource_path
|
|
162
|
+
headers = {
|
|
163
|
+
"Content-Type" => "application/json",
|
|
164
|
+
"Authorization" => "Bearer #{option_bearer_token}"
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
# note outgoing webhook delivery only supports the post method
|
|
168
|
+
outgoing_webhook_delivery = OutgoingWebhookDelivery.factory(
|
|
169
|
+
resource: self,
|
|
170
|
+
url: url,
|
|
171
|
+
body: data,
|
|
172
|
+
options: {headers: headers}
|
|
173
|
+
)
|
|
174
|
+
outgoing_webhook_delivery.save!
|
|
175
|
+
outgoing_webhook_delivery.deliver_later
|
|
176
|
+
|
|
177
|
+
outgoing_webhook_delivery
|
|
178
|
+
end
|
|
76
179
|
end
|
|
77
180
|
end
|
|
181
|
+
|
|
182
|
+
# https://www.logicmonitor.com/support/alerts/integrations/custom-http-delivery
|
|
183
|
+
# {
|
|
184
|
+
# "alertid": "LMS22",
|
|
185
|
+
# "alertstatus": "active",
|
|
186
|
+
# "datasource": "WinVolumeUsage-C:\",
|
|
187
|
+
# "datapoint": "PercentUsed",
|
|
188
|
+
# "date": "2014-05-02 14:21:40 PDT",
|
|
189
|
+
# "dsdesc": "Monitors space usage on logical volumes.",
|
|
190
|
+
# "dsidesc": null,
|
|
191
|
+
# "datapointdesc": "Percentage Used on the volume",
|
|
192
|
+
# "group": "group1,group2",
|
|
193
|
+
# "host": "opsgenie-test-server",
|
|
194
|
+
# "hostdesc": "Server used for testing OpsGenie integrations",
|
|
195
|
+
# "instance": "C:\",
|
|
196
|
+
# "level": "warning",
|
|
197
|
+
# "duration": "1465",
|
|
198
|
+
# "threshold": "10",
|
|
199
|
+
# "eventsource": "WinVolumeUsage-C:\",
|
|
200
|
+
# "eventlogfile": "Application",
|
|
201
|
+
# "eventtype": "information",
|
|
202
|
+
# "eventmsg": "Percentage used on the volume exceeded 80%",
|
|
203
|
+
# "eventlogmsg": "Remaining capacity(1456750MB) of volume C:\ is lower than 25%",
|
|
204
|
+
# "eventcode": "1847502394",
|
|
205
|
+
# "eventuser": "test-user",
|
|
206
|
+
# "value": "83",
|
|
207
|
+
# "batchdesc": "Monitors space usage on logical volumes everyday.",
|
|
208
|
+
# "hostips": "123.456.789.012",
|
|
209
|
+
# "hosturl": "https://opsgenie-test-server.net/",
|
|
210
|
+
# "service": "webservice",
|
|
211
|
+
# "alerttype": "error",
|
|
212
|
+
# "agent": "opsgenie-test-server",
|
|
213
|
+
# "checkpoint": "1879234",
|
|
214
|
+
# "hostinfo": null,
|
|
215
|
+
# "servicedetail": null,
|
|
216
|
+
# "serviceurl": "https://opsgenie-test-server.net/",
|
|
217
|
+
# "servicegroup": "Functional Testing",
|
|
218
|
+
# "clearvalue": "1"
|
|
219
|
+
# }
|
|
220
|
+
|
|
221
|
+
# {
|
|
222
|
+
# "service": "##SERVICE##",
|
|
223
|
+
# "alertid": "##ALERTID##",
|
|
224
|
+
# "alerttype": "##ALERTTYPE##",
|
|
225
|
+
# "alertstatus": "##ALERTSTATUS##",
|
|
226
|
+
# "level": "##LEVEL##",
|
|
227
|
+
# "host": "##HOST##",
|
|
228
|
+
# "datasource": "##DATASOURCE##",
|
|
229
|
+
# "eventsource": "##EVENTSOURCE##",
|
|
230
|
+
# "batchjob": "##BATCHJOB##",
|
|
231
|
+
# "group": "##GROUP##",
|
|
232
|
+
# "datapoint": "##DATAPOINT##",
|
|
233
|
+
# "start": "##START##",
|
|
234
|
+
# "finish": "##FINISH##",
|
|
235
|
+
# "duration": "##DURATION##",
|
|
236
|
+
# "value": "##VALUE##",
|
|
237
|
+
# "threshold": "##THRESHOLD##",
|
|
238
|
+
# "userdata": "##USERDATA##",
|
|
239
|
+
# "cmdline": "##CMDLINE##",
|
|
240
|
+
# "exitCode": "##EXITCODE##",
|
|
241
|
+
# "stdout": "##STDOUT##",
|
|
242
|
+
# "stderr": "##STDERR##",
|
|
243
|
+
# "agent": "##AGENT_DESCRIPTION##",
|
|
244
|
+
# "checkpoint": "##CHECKPOINT##",
|
|
245
|
+
# "datapointdesc": "##DPDESCRIPTION##",
|
|
246
|
+
# "hostdesc": "##HOSTDESCRIPTION##",
|
|
247
|
+
# "hostinfo": "##system.sysinfo##",
|
|
248
|
+
# "hostips": "##system.ips##",
|
|
249
|
+
# "hosturl": "##DEVICEURL##",
|
|
250
|
+
# "instance": "##INSTANCE##",
|
|
251
|
+
# "dsidesc": "##DSIDESCRIPTION##",
|
|
252
|
+
# "batchdesc": "##BJDESCRIPTION##",
|
|
253
|
+
# "dsdesc": "##DSDESCRIPTION##",
|
|
254
|
+
# "eventmsg": "##LIMITEDMESSAGE##",
|
|
255
|
+
# "eventlogmsg": "##MESSAGE##",
|
|
256
|
+
# "eventcode": "##EVENTCODE##",
|
|
257
|
+
# "eventtype": "##TYPE##",
|
|
258
|
+
# "eventuser": "##USER##",
|
|
259
|
+
# "eventlogfile": "##LOGFILE##",
|
|
260
|
+
# "eventsource": "##SOURCENAME##",
|
|
261
|
+
# "servicedetail": "##DETAIL##",
|
|
262
|
+
# "serviceurl": "##URL##",
|
|
263
|
+
# "servicegroup": "##SERVICEGROUP##",
|
|
264
|
+
# "date": "##DATE##",
|
|
265
|
+
# "clearvalue": "##CLEARVALUE##",
|
|
266
|
+
# "hostname": "##system.hostname##"
|
|
267
|
+
# }
|
|
@@ -10,7 +10,7 @@ module PagerTree::Integrations
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def adapter_should_block_incoming?(request)
|
|
13
|
-
|
|
13
|
+
option_token.present? && (request.params["token"] != option_token)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def adapter_supports_incoming?
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
module PagerTree::Integrations
|
|
2
|
+
class Meta::Workplace::V3 < Integration
|
|
3
|
+
OPTIONS = [
|
|
4
|
+
{key: :incoming_enabled, type: :boolean, default: false},
|
|
5
|
+
{key: :outgoing_enabled, type: :boolean, default: true},
|
|
6
|
+
{key: :access_token, type: :string, default: nil},
|
|
7
|
+
{key: :app_secret, type: :string, default: nil},
|
|
8
|
+
{key: :group_id, type: :string, default: nil},
|
|
9
|
+
{key: :outgoing_rules, type: :string, default: nil}
|
|
10
|
+
]
|
|
11
|
+
store_accessor :options, *OPTIONS.map { |x| x[:key] }.map(&:to_s), prefix: "option"
|
|
12
|
+
|
|
13
|
+
validates :option_incoming_enabled, inclusion: {in: [true, false]}
|
|
14
|
+
validates :option_outgoing_enabled, inclusion: {in: [true, false]}
|
|
15
|
+
validates :option_access_token, presence: true
|
|
16
|
+
# validates :option_app_secret, presence: true
|
|
17
|
+
validates :option_group_id, presence: true
|
|
18
|
+
|
|
19
|
+
after_initialize do
|
|
20
|
+
self.option_incoming_enabled = false if option_incoming_enabled.nil?
|
|
21
|
+
self.option_outgoing_enabled = true if option_outgoing_enabled.nil?
|
|
22
|
+
self.option_outgoing_rules ||= ""
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def endpoint
|
|
26
|
+
super + "/g"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def adapter_should_block_incoming?(request)
|
|
30
|
+
should_block = false
|
|
31
|
+
|
|
32
|
+
if option_app_secret.present? && request.headers["x-hub-signature-256"].present?
|
|
33
|
+
signature = request.headers["x-hub-signature-256"].delete_prefix("sha256=")
|
|
34
|
+
data = request.body.read
|
|
35
|
+
digest = OpenSSL::HMAC.hexdigest("SHA256", option_app_secret, data)
|
|
36
|
+
should_block = signature != digest
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
should_block
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def adapter_supports_incoming?
|
|
43
|
+
# TODO - change this to true once we are ready to support this. The code currently works, but we don't want to confuse our users.
|
|
44
|
+
# Let's work with them to see what they want the functionality to look like
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def adapter_supports_outgoing?
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def adapter_show_outgoing_webhook_delivery?
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def adapter_incoming_can_defer?
|
|
57
|
+
false
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def adapter_supports_title_template?
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def adapter_supports_description_template?
|
|
65
|
+
false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def adapter_thirdparty_id
|
|
69
|
+
[_entry&.dig("id"), _entry&.dig("time")].compact_blank.join("-")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def adapter_action
|
|
73
|
+
if option_incoming_enabled && adapter_incoming_request_params.dig("object") == "page" && _entry_changes&.dig("field") == "mention"
|
|
74
|
+
:create
|
|
75
|
+
else
|
|
76
|
+
:other
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def adapter_response_incoming
|
|
81
|
+
if adapter_incoming_request_params["hub.mode"] == "subscribe"
|
|
82
|
+
adapter_controller&.render(plain: adapter_incoming_request_params["hub.challenge"])
|
|
83
|
+
else
|
|
84
|
+
adapter_controller&.head(:ok)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def adapter_process_create
|
|
89
|
+
# send back an ok
|
|
90
|
+
post_id = _entry_changes&.dig("value", "post_id")
|
|
91
|
+
_post_comment(post_id, "Ok") if post_id.present?
|
|
92
|
+
|
|
93
|
+
Alert.new(
|
|
94
|
+
title: _title,
|
|
95
|
+
thirdparty_id: adapter_thirdparty_id
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def adapter_process_other
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def adapter_outgoing_interest?(event_name)
|
|
103
|
+
option_outgoing_enabled && [
|
|
104
|
+
"alert_assigned",
|
|
105
|
+
"alert_acknowledged",
|
|
106
|
+
"alert_rejected",
|
|
107
|
+
"alert_resolved",
|
|
108
|
+
"alert_dropped",
|
|
109
|
+
"alert_handoff",
|
|
110
|
+
"comment_created"
|
|
111
|
+
].include?(event_name.to_s)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def adapter_process_outgoing
|
|
115
|
+
event_type = adapter_outgoing_event.event_name.to_s
|
|
116
|
+
message = _generate_message(event_type)
|
|
117
|
+
|
|
118
|
+
return unless message.present?
|
|
119
|
+
|
|
120
|
+
if event_type == "alert_assigned"
|
|
121
|
+
_post_message(option_group_id, message)
|
|
122
|
+
else
|
|
123
|
+
post_id = _alert.meta["#{id}_meta_workplace_post_id"]
|
|
124
|
+
|
|
125
|
+
if post_id.blank?
|
|
126
|
+
outgoing_webhook_delivery_id = _alert.meta["#{id}_meta_workplace_outgoing_webhook_delivery_id"]
|
|
127
|
+
outgoing_webhook_delivery = OutgoingWebhookDelivery.find_by(id: outgoing_webhook_delivery_id)
|
|
128
|
+
post_id = begin
|
|
129
|
+
JSON.parse(outgoing_webhook_delivery.responses.first.dig("body"))["id"]
|
|
130
|
+
rescue
|
|
131
|
+
nil
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
if post_id.present?
|
|
135
|
+
_alert.meta["#{id}_meta_workplace_post_id"] = post_id
|
|
136
|
+
_alert.save!
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
_post_comment(post_id, message) if post_id.present?
|
|
141
|
+
end
|
|
142
|
+
rescue => e
|
|
143
|
+
Rails.logger.error "[Workplace] Error processing outgoing event: #{e.message}"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
# INCOMING
|
|
149
|
+
def _entry
|
|
150
|
+
@_entry ||= adapter_incoming_request_params&.dig("entry", 0)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def _entry_changes
|
|
154
|
+
@_entry_changes ||= _entry&.dig("changes", 0)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def _title
|
|
158
|
+
_entry_changes&.dig("value", "message")
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def _additional_datums
|
|
162
|
+
[]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# OUTGOING
|
|
166
|
+
def _alert
|
|
167
|
+
@_alert ||= adapter_outgoing_event.alert
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def _post_message(group_id, message)
|
|
171
|
+
# This operation needs to happen immediately because we need to attach the post_id to the alert
|
|
172
|
+
url = "https://graph.facebook.com/#{group_id}/feed?message=#{CGI.escape(message)}&formatting=MARKDOWN"
|
|
173
|
+
outgoing_webhook_delivery = _send_outgoing(url)
|
|
174
|
+
_alert.meta["#{id}_meta_workplace_outgoing_webhook_delivery_id"] = outgoing_webhook_delivery.id
|
|
175
|
+
_alert.save!
|
|
176
|
+
|
|
177
|
+
outgoing_webhook_delivery
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def _post_comment(post_id, message)
|
|
181
|
+
url = "https://graph.facebook.com/#{post_id}/comments?message=#{CGI.escape(message)}"
|
|
182
|
+
_send_outgoing(url)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def _send_outgoing(url)
|
|
186
|
+
outgoing_webhook_delivery = OutgoingWebhookDelivery.factory(
|
|
187
|
+
resource: self,
|
|
188
|
+
url: url,
|
|
189
|
+
options: {
|
|
190
|
+
headers: {
|
|
191
|
+
"Authorization" => "Bearer #{option_access_token}"
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
outgoing_webhook_delivery.save!
|
|
196
|
+
outgoing_webhook_delivery.deliver_later
|
|
197
|
+
|
|
198
|
+
outgoing_webhook_delivery
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def _generate_message(event_name)
|
|
202
|
+
case event_name
|
|
203
|
+
when "alert_assigned"
|
|
204
|
+
if _alert.incident?
|
|
205
|
+
"[Incident ##{_alert.tiny_id}](#{Rails.application.routes.url_helpers.try(:alert_url, _alert, script_name: "/#{_alert.account_id}")}) [#{_alert.incident_severity.upcase.dasherize}] #{_alert.incident_message} - #{_alert.title}"
|
|
206
|
+
else
|
|
207
|
+
"[Alert ##{_alert.tiny_id}](#{Rails.application.routes.url_helpers.try(:alert_url, _alert, script_name: "/#{_alert.account_id}")}) #{_alert.title}"
|
|
208
|
+
end
|
|
209
|
+
when "alert_acknowledged"
|
|
210
|
+
acknowledger = adapter_outgoing_event.account_user || adapter_outgoing_event.team
|
|
211
|
+
acknowledger&.name&.present? ? "Acknowledged by #{acknowledger.name}" : "Acknowledged"
|
|
212
|
+
when "alert_rejected"
|
|
213
|
+
rejecter = adapter_outgoing_event.account_user
|
|
214
|
+
rejecter&.name&.present? ? "Rejected by #{rejecter.name}" : "Rejected"
|
|
215
|
+
when "alert_resolved"
|
|
216
|
+
resolver = adapter_outgoing_event.account_user || adapter_outgoing_event.team
|
|
217
|
+
resolver&.name&.present? ? "Resolved by #{resolver.name}" : "Resolved"
|
|
218
|
+
when "alert_dropped"
|
|
219
|
+
"Dropped"
|
|
220
|
+
when "alert_handoff"
|
|
221
|
+
handoff = adapter_outgoing_event.handoff
|
|
222
|
+
"Handed off from #{handoff.source.name} to #{handoff.destination.name}"
|
|
223
|
+
when "comment_created"
|
|
224
|
+
comment = adapter_outgoing_event.comment
|
|
225
|
+
commenter = comment.account_user&.name || "PagerTree"
|
|
226
|
+
"#{commenter} commented: \"#{comment.body.to_plain_text}\""
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
@@ -19,16 +19,19 @@ module PagerTree::Integrations
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def adapter_thirdparty_id
|
|
22
|
-
adapter_incoming_request_params.dig("incident_id")
|
|
22
|
+
adapter_incoming_request_params.dig("incident_id") || adapter_incoming_request_params.dig("id")
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def adapter_action
|
|
26
26
|
event_type = adapter_incoming_request_params.dig("event_type")
|
|
27
27
|
current_state = adapter_incoming_request_params.dig("current_state")
|
|
28
|
+
state = adapter_incoming_request_params.dig("state")
|
|
28
29
|
|
|
29
|
-
if event_type == "INCIDENT_OPEN" || (event_type == "INCIDENT" && current_state == "open")
|
|
30
|
+
if event_type == "INCIDENT_OPEN" || (event_type == "INCIDENT" && current_state == "open") || (state == "CREATED" || state == "ACTIVATED")
|
|
30
31
|
:create
|
|
31
|
-
elsif event_type == "
|
|
32
|
+
elsif event_type == "INCIDENT_ACKNOWLEDGED" || (event_type == "INCIDENT" && current_state == "acknowledged")
|
|
33
|
+
:acknowledge
|
|
34
|
+
elsif event_type == "INCIDENT_RESOLVED" || (event_type == "INCIDENT" && current_state == "closed") || state == "CLOSED"
|
|
32
35
|
:resolve
|
|
33
36
|
else
|
|
34
37
|
:other
|
|
@@ -48,7 +51,7 @@ module PagerTree::Integrations
|
|
|
48
51
|
private
|
|
49
52
|
|
|
50
53
|
def _title
|
|
51
|
-
adapter_incoming_request_params.dig("condition_name")
|
|
54
|
+
adapter_incoming_request_params.dig("condition_name") || adapter_incoming_request_params.dig("title")
|
|
52
55
|
end
|
|
53
56
|
|
|
54
57
|
def _description
|
|
@@ -58,7 +61,8 @@ module PagerTree::Integrations
|
|
|
58
61
|
def _additional_datums
|
|
59
62
|
[
|
|
60
63
|
AdditionalDatum.new(format: "text", label: "Account Name", value: adapter_incoming_request_params.dig("account_name")),
|
|
61
|
-
AdditionalDatum.new(format: "
|
|
64
|
+
AdditionalDatum.new(format: "link", label: "Incident URL", value: adapter_incoming_request_params.dig("incident_url")),
|
|
65
|
+
AdditionalDatum.new(format: "link", label: "Issue URL", value: adapter_incoming_request_params.dig("issueUrl"))
|
|
62
66
|
]
|
|
63
67
|
end
|
|
64
68
|
end
|
|
@@ -5,6 +5,8 @@ module PagerTree::Integrations
|
|
|
5
5
|
extend ActiveModel::Callbacks
|
|
6
6
|
|
|
7
7
|
attr_accessor :event_name
|
|
8
|
+
attr_accessor :account_id
|
|
9
|
+
attr_accessor :item_id
|
|
8
10
|
attr_accessor :item
|
|
9
11
|
attr_accessor :changes
|
|
10
12
|
attr_accessor :outgoing_rules_data
|
|
@@ -12,6 +14,8 @@ module PagerTree::Integrations
|
|
|
12
14
|
attr_accessor :handoff
|
|
13
15
|
attr_accessor :team
|
|
14
16
|
attr_accessor :account_user
|
|
17
|
+
attr_accessor :comment
|
|
18
|
+
attr_accessor :event_reminder
|
|
15
19
|
|
|
16
20
|
define_model_callbacks :initialize
|
|
17
21
|
|
|
@@ -23,6 +27,8 @@ module PagerTree::Integrations
|
|
|
23
27
|
|
|
24
28
|
after_initialize do
|
|
25
29
|
self.event_name ||= nil
|
|
30
|
+
self.account_id ||= nil
|
|
31
|
+
self.item_id ||= nil
|
|
26
32
|
self.item ||= nil
|
|
27
33
|
self.changes ||= nil
|
|
28
34
|
self.outgoing_rules_data ||= {}
|
|
@@ -31,6 +37,8 @@ module PagerTree::Integrations
|
|
|
31
37
|
self.handoff ||= nil
|
|
32
38
|
self.team ||= nil
|
|
33
39
|
self.account_user ||= nil
|
|
40
|
+
self.comment ||= nil
|
|
41
|
+
self.event_reminder ||= nil
|
|
34
42
|
end
|
|
35
43
|
end
|
|
36
44
|
end
|