pager_tree-integrations 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 346fc5f836fd08b5e13984f0ead3c57af0bfb853c6c7bbe06eab9b9821693d47
4
- data.tar.gz: '09642e8b0aadff79bedeeec4a6508e0df60ace5ee8d5d751b9b881675bd5829c'
3
+ metadata.gz: 1232e60d15e2dce895e6cc02e391cb1ec4f0230bcb3642c65f7d2eebaf499666
4
+ data.tar.gz: 2b1b7bd0787d7d001127b0391ce02a25bb258e74f86609b128e488e90c9efae4
5
5
  SHA512:
6
- metadata.gz: 9ed77d1beebab497c91eebc46b0611beabf99fe463498aa993f53ff497d543f604b8ec8115276992d76dd877c665d13e1804786c60b94a08bb16581fe9d74f80
7
- data.tar.gz: 3f586f4688d333343ab300a79836947c29698d82372932a59e7ae2b5253fd6709bc9da57ef21fcc7c1e66f891ca034504bfbd997ad0f00321e2bb6713521c6d0
6
+ metadata.gz: 1d1efc213cc97634b6530653d5f06f14f79f80cf7df72c8f7130e890d968bfe74282cd95142dfc1fa4fbddd70c8634a538354049093f1b1617f9e6cd7f840df1
7
+ data.tar.gz: b2c8fea7246e9c3e00671b9fde25d0214fe254a28902056b4393e3623ee416113eb984e1b8d9f8b511c2e0b6f747513c1b3ed6c66f09ac416524c986005cb5ba
@@ -7,9 +7,20 @@ module PagerTree::Integrations
7
7
 
8
8
  @integration.adapter_source_log = @integration.logs.create!(level: :info, format: :json, message: params.to_unsafe_h) if @integration.try(:log_incoming_requests?)
9
9
  @integration.adapter_controller = self
10
+ @integration.adapter_incoming_request_params = params
10
11
  @integration.adapter_response_music
11
12
  end
12
13
 
14
+ def dropped
15
+ set_integration
16
+
17
+ @integration.adapter_source_log = @integration.logs.create!(level: :info, format: :json, message: params.to_unsafe_h) if @integration.try(:log_incoming_requests?)
18
+ @integration.adapter_controller = self
19
+ @integration.adapter_alert = @integration.alerts.find_by(thirdparty_id: params[:CallSid])
20
+ @integration.adapter_incoming_request_params = params
21
+ @integration.adapter_response_dropped
22
+ end
23
+
13
24
  def queue_status
14
25
  ::PagerTree::Integrations.deferred_request_class.constantize.perform_later_from_request!(request)
15
26
 
@@ -0,0 +1,17 @@
1
+ module PagerTree::Integrations
2
+ class LiveCallRouting::Twilio::V3Mailer < ::ApplicationMailer
3
+ # Subject can be set in your I18n file at config/locales/en.yml
4
+ # with the following lookup:
5
+ #
6
+ # en.live_call_routing.twilio.v3_mailer.call_recording.subject
7
+ #
8
+ def call_recording
9
+ @recording_url = params[:recording_url]
10
+ @alert = params[:alert]
11
+ @email = params[:email]
12
+ @from = params[:from]
13
+
14
+ mail(to: @email, subject: I18n.t("pager_tree.integrations.live_call_routing.twilio.v3_mailer.call_recording.subject", tiny_id: @alert.tiny_id, from: @from))
15
+ end
16
+ end
17
+ end
@@ -63,7 +63,7 @@ module PagerTree::Integrations
63
63
  private
64
64
 
65
65
  def _alert
66
- @_alert ||= adapter_outgoing_event.item
66
+ @_alert ||= adapter_outgoing_event.alert
67
67
  end
68
68
 
69
69
  def _blocks
@@ -63,7 +63,7 @@ module PagerTree::Integrations
63
63
  private
64
64
 
65
65
  def _alert
66
- @_alert ||= adapter_outgoing_event.item
66
+ @_alert ||= adapter_outgoing_event.alert
67
67
  end
68
68
 
69
69
  def _blocks
@@ -63,7 +63,7 @@ module PagerTree::Integrations
63
63
  private
64
64
 
65
65
  def _alert
66
- @_alert ||= adapter_outgoing_event.item
66
+ @_alert ||= adapter_outgoing_event.alert
67
67
  end
68
68
 
69
69
  def _blocks
@@ -58,6 +58,10 @@ module PagerTree::Integrations
58
58
 
59
59
  def adapter_process_other
60
60
  end
61
+
62
+ def adapter_will_route_alert?
63
+ false
64
+ end
61
65
  # END basic incoming functions
62
66
 
63
67
  # START basic outgoing functions
@@ -38,20 +38,24 @@ module PagerTree::Integrations
38
38
  voice: "man"
39
39
  }
40
40
 
41
- TWILIO_LIVECALL_CONNECT_NOW = "https://app.pagertree.com/assets/sounds/you-are-now-being-connected.mp3"
42
- TWILIO_LIVECALL_MUSIC = "http://com.twilio.sounds.music.s3.amazonaws.com/oldDog_-_endless_goodbye_%28instr.%29.mp3"
43
- TWILIO_LIVECALL_PLEASE_WAIT = "https://app.pagertree.com/assets/sounds/please-wait.mp3"
44
-
45
41
  def option_connect_now_media_url
46
- option_connect_now_media&.url || TWILIO_LIVECALL_CONNECT_NOW
42
+ option_connect_now_media.present? ? option_connect_now_media.url : URI.join(Rails.application.routes.url_helpers.root_url, "audios/you-are-now-being-connected.mp3").to_s
47
43
  end
48
44
 
49
45
  def option_music_media_url
50
- option_music_media&.url || TWILIO_LIVECALL_MUSIC
46
+ option_music_media.present? ? option_music_media.url : "http://com.twilio.sounds.music.s3.amazonaws.com/oldDog_-_endless_goodbye_%28instr.%29.mp3"
51
47
  end
52
48
 
53
49
  def option_please_wait_media_url
54
- option_please_wait_media&.url || TWILIO_LIVECALL_PLEASE_WAIT
50
+ option_please_wait_media.present? ? option_please_wait_media.url : URI.join(Rails.application.routes.url_helpers.root_url, "audios/please-wait.mp3").to_s
51
+ end
52
+
53
+ def option_no_answer_media_url
54
+ option_no_answer_media.present? ? option_no_answer_media.url : URI.join(Rails.application.routes.url_helpers.root_url, "audios/no-answer.mp3").to_s
55
+ end
56
+
57
+ def option_no_answer_thank_you_media_url
58
+ option_no_answer_thank_you_media.present? ? option_no_answer_thank_you_media.url : URI.join(Rails.application.routes.url_helpers.root_url, "audios/thanks-for-message.mp3").to_s
55
59
  end
56
60
 
57
61
  def option_record_emails=(x)
@@ -90,10 +94,18 @@ module PagerTree::Integrations
90
94
  true
91
95
  end
92
96
 
97
+ def adapter_outgoing_interest?(event_name)
98
+ ["alert_acknowledged", "alert_dropped"].include?(event_name) && adapter_alert.source_id == id
99
+ end
100
+
93
101
  def adapter_incoming_can_defer?
94
102
  false
95
103
  end
96
104
 
105
+ def adapter_will_route_alert?
106
+ true
107
+ end
108
+
97
109
  def adapter_action
98
110
  :create
99
111
  end
@@ -128,13 +140,19 @@ module PagerTree::Integrations
128
140
  end
129
141
 
130
142
  if selected_team
131
- adapter_alert.logs.create!(message: "Caller selected team '#{selected_team.name}'. Playing please wait media.")
132
- _twiml.play(url: option_please_wait_media&.url || TWILIO_LIVECALL_PLEASE_WAIT)
143
+ adapter_alert.logs.create!(message: "Caller selected team '#{selected_team.name}'.") if _teams_size > 1 || option_force_input
144
+
145
+ adapter_alert.logs.create!(message: "Play please wait media to caller.")
146
+ _twiml.play(url: option_please_wait_media_url)
133
147
  friendly_name = adapter_alert.id
134
148
 
135
149
  # create the queue and save it off
136
150
  queue = _client.queues.create(friendly_name: friendly_name)
137
151
  adapter_alert.meta["live_call_queue_sid"] = queue.sid
152
+
153
+ adapter_alert.destination_teams = [selected_team]
154
+
155
+ # save the alert
138
156
  adapter_alert.save!
139
157
 
140
158
  _twiml.enqueue(
@@ -144,6 +162,11 @@ module PagerTree::Integrations
144
162
  wait_url: PagerTree::Integrations::Engine.routes.url_helpers.music_live_call_routing_twilio_v3_path(id, thirdparty_id: _thirdparty_id),
145
163
  wait_url_method: "GET"
146
164
  )
165
+ adapter_alert.logs.create!(message: "Enqueue caller in Twilio queue '#{friendly_name}'.")
166
+
167
+ # kick off the alert workflow
168
+ adapter_alert.route_later
169
+ adapter_alert.logs.create!(message: "Successfully enqueued alert team workflow.")
147
170
  else
148
171
  adapter_alert.meta["live_call_repeat_count"] ||= 0
149
172
  adapter_alert.meta["live_call_repeat_count"] += 1
@@ -159,6 +182,7 @@ module PagerTree::Integrations
159
182
  end
160
183
  else
161
184
  adapter_alert.logs.create!(message: "Caller input bad input (too many times). Hangup.")
185
+ adapter_alert.resolve!(self)
162
186
  _twiml.say(message: "Too much invalid input. Goodbye.", **SPEAK_OPTIONS)
163
187
  _twiml.hangup
164
188
  end
@@ -193,15 +217,11 @@ module PagerTree::Integrations
193
217
  adapter_controller&.render(xml: _twiml.to_xml)
194
218
  end
195
219
 
196
- def response_dropped
220
+ def adapter_response_dropped
197
221
  recording_url = adapter_incoming_request_params.dig("RecordingUrl")
198
222
 
199
223
  if recording_url
200
- if option_no_answer_thank_you_media.present?
201
- _twiml.play(url: option_no_answer_thank_you_media.url)
202
- else
203
- _twiml.say(message: "Thank you for your message. Goodbye.")
204
- end
224
+ _twiml.play(url: option_no_answer_thank_you_media_url)
205
225
  _twiml.hangup
206
226
 
207
227
  adapter_alert.additional_data.push(AdditionalDatum.new(format: "link", label: "Voicemail", value: recording_url).to_h)
@@ -209,18 +229,18 @@ module PagerTree::Integrations
209
229
 
210
230
  adapter_alert.logs.create!(message: "Caller left a <a href='#{recording_url}' target='_blank'>voicemail</a>.")
211
231
 
212
- adapter_record_emails.each do |email|
213
- TwilioLiveCallRouting::V3Mailer.with(email: email, alert: alert).call_recording.deliver_later
232
+ option_record_emails.each do |email|
233
+ LiveCallRouting::Twilio::V3Mailer.with(email: email, alert: adapter_alert, from: adapter_incoming_request_params.dig("From"), recording_url: recording_url).call_recording.deliver_later
214
234
  end
215
- elsif record
235
+ elsif option_record
216
236
  _twiml.play(url: option_no_answer_media_url)
217
237
  _twiml.record(max_length: 60)
218
238
  else
219
- _twiml.say(message: "No one is available to answer this call. Goodbye.")
239
+ _twiml.say(message: "No one is available to answer this call. Goodbye.", **SPEAK_OPTIONS)
220
240
  _twiml.hangup
221
241
  end
222
242
 
223
- controller.render(xml: _twiml.to_xml)
243
+ adapter_controller.render(xml: _twiml.to_xml)
224
244
  end
225
245
 
226
246
  def adapter_process_queue_status_deferred
@@ -229,18 +249,20 @@ module PagerTree::Integrations
229
249
 
230
250
  if queue_result == "hangup"
231
251
  self.adapter_alert = alerts.find_by(thirdparty_id: _thirdparty_id)
252
+ adapter_alert.logs.create!(message: "Caller hungup while waiting in queue.")
253
+ adapter_alert.resolve!(self)
232
254
  queue_destroy
233
255
  end
234
256
 
235
257
  adapter_source_log&.save!
236
258
  end
237
259
 
238
- def perform_outgoing(**params)
239
- event = params[:event]
240
- if event == "alert.acknowledged"
241
- on_acknowledge
242
- elsif event == "alert.dropped"
243
- on_drop
260
+ def adapter_process_outgoing
261
+ event = adapter_outgoing_event.event_name.to_s
262
+ if event == "alert_acknowledged"
263
+ _on_acknowledge
264
+ elsif event == "alert_dropped"
265
+ _on_drop
244
266
  end
245
267
  end
246
268
 
@@ -269,7 +291,7 @@ module PagerTree::Integrations
269
291
  end
270
292
 
271
293
  def _call
272
- @_call ||= _client.calls(call_sid).fetch
294
+ @_call ||= _client.calls(adapter_alert.thirdparty_id).fetch
273
295
  end
274
296
 
275
297
  def _twiml
@@ -299,23 +321,44 @@ module PagerTree::Integrations
299
321
  nil
300
322
  end
301
323
 
302
- def on_acknowledge
324
+ def _on_acknowledge
303
325
  # log that we are going to transfer
304
- adapter_alert.logs.create!(message: "Attempting to transfer the call...")
326
+ adapter_alert.logs.create!(message: "The alert was acknowledged. Attempting to transfer the call...")
305
327
 
306
328
  # try to transfer the caller
307
- number = "+19402733696"
308
- _twiml.play(url: option_connect_now_media_url)
309
- _twiml.pause(length: 1)
310
- _twiml.dial(number: number, caller_id: _call.to, answer_on_bridge: true)
311
- _call.update(twiml: _twiml.to_xml)
312
-
313
- # log if we successfully transfered or failed
314
- adapter_alert.logs.create!(message: "Tranferring the call succeeded.")
329
+ account_user = adapter_outgoing_event.account_user
330
+ number = account_user.user.phone&.phone
331
+
332
+ adapter_alert.logs.create!(message: "Attempting to transfer the call to #{account_user.user.name} at #{number}...")
333
+
334
+ if number.present?
335
+ _twiml.play(url: option_connect_now_media_url)
336
+ _twiml.pause(length: 1)
337
+ _twiml.dial(number: number, caller_id: _call.to, answer_on_bridge: true)
338
+ _call.update(twiml: _twiml.to_xml)
339
+ # log if we successfully transfered or failed
340
+ adapter_alert.logs.create!(message: "Tranferring the call succeeded.")
341
+ else
342
+ _twiml.say(message: "Someone has acknowledged this call, but they do not have a phone number on file. Goodbye.")
343
+ _twiml.hangup
344
+ _call.update(twiml: _twiml.to_xml)
345
+ adapter_alert.logs.create!(message: "Tranferring the call failed. #{account_user.user.name} has no phone number on file.")
346
+ end
347
+ rescue ::Twilio::REST::RestError => e
348
+ # 21220 - Unable to update record. Call is not in-progress. Cannot redirect.
349
+ if e.code != 21220
350
+ adapter_alert.logs.create!(message: "Tranferring the call failed. #{e.message}")
351
+ end
315
352
  end
316
353
 
317
- def on_drop
318
- _call.update(url: PagerTree::Integrations::Engine.routes.url_helpers.dropped_twilio_live_call_routing_v3_url(id, thirdparty_id: thirdparty_id))
354
+ def _on_drop
355
+ # log that we are going to transer
356
+ adapter_alert.logs.create!(message: "The alert was dropped. Attempting to transfer the call...")
357
+ _call.update(url: PagerTree::Integrations::Engine.routes.url_helpers.dropped_live_call_routing_twilio_v3_url(id, thirdparty_id: adapter_alert.thirdparty_id))
358
+ music_live_call_routing_twilio_v3_path
359
+ adapter_alert.logs.create!(message: "Tranferring the call succeeded.")
360
+ rescue ::Twilio::REST::RestError => e
361
+ adapter_alert.logs.create!(message: "Tranferring the call failed. #{e.message}")
319
362
  end
320
363
 
321
364
  def queue_destroy
@@ -8,6 +8,10 @@ module PagerTree::Integrations
8
8
  attr_accessor :item
9
9
  attr_accessor :changes
10
10
  attr_accessor :outgoing_rules_data
11
+ attr_accessor :alert
12
+ attr_accessor :handoff
13
+ attr_accessor :team
14
+ attr_accessor :account_user
11
15
 
12
16
  define_model_callbacks :initialize
13
17
 
@@ -22,6 +26,11 @@ module PagerTree::Integrations
22
26
  self.item ||= nil
23
27
  self.changes ||= nil
24
28
  self.outgoing_rules_data ||= {}
29
+
30
+ self.alert ||= nil
31
+ self.handoff ||= nil
32
+ self.team ||= nil
33
+ self.account_user ||= nil
25
34
  end
26
35
  end
27
36
  end
@@ -71,7 +71,7 @@ module PagerTree::Integrations
71
71
  if self.option_template.present?
72
72
  begin
73
73
  body = JSON.parse(handlebars(self.option_template, {
74
- alert: adapter_outgoing_event.item.try(:v3_format) || adapter_outgoing_event.item,
74
+ alert: adapter_outgoing_event.alert.try(:v3_format) || adapter_outgoing_event.alert,
75
75
  event: {
76
76
  type: event_type
77
77
  }
@@ -84,7 +84,7 @@ module PagerTree::Integrations
84
84
  end
85
85
 
86
86
  body ||= {
87
- data: adapter_outgoing_event.item.try(:v3_format) || adapter_outgoing_event.item,
87
+ data: adapter_outgoing_event.alert.try(:v3_format) || adapter_outgoing_event.alert,
88
88
  type: event_type
89
89
  }
90
90
 
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <style>
6
+ /* Email styles need to be inline */
7
+ </style>
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <%= t(".body", tiny_id: @alert.tiny_id, from: @from) %>: <a href="<%=@recording_url%>"><%= @recording_url %></a>
@@ -0,0 +1 @@
1
+ <%= t(".body", tiny_id: @alert.tiny_id, from: @from) %>: <%= @recording_url %>
@@ -59,6 +59,10 @@ en:
59
59
  option_force_input_hint_html: "Force the caller to select a team (even if the integration only has one team)"
60
60
  option_record_hint_html: "Record a voicemail when no one acknowledges the call"
61
61
  option_record_emails_list_hint_html: "List of email addresses to notify when a voicemail has been recorded"
62
+ v3_mailer:
63
+ call_recording:
64
+ subject: "🎧 Alert #%{tiny_id} - New voicemail from %{from}"
65
+ body: "Alert #%{tiny_id} - New voicemail from %{from}"
62
66
  mattermost:
63
67
  outgoing_webhook:
64
68
  v3:
@@ -79,10 +83,10 @@ en:
79
83
  v3:
80
84
  form_options:
81
85
  option_token_hint_html: "The PagerTree-Token header can be used to authenticate requests (optional)"
82
- option_capture_additional_data_hint_html: "Capture additional data from the webhook (optional)"
86
+ option_capture_additional_data_hint_html: "Capture additional data from the webhook (optional)"
83
87
  # SCAFFOLD_INTEGRATION
84
88
 
85
-
89
+
86
90
  activerecord:
87
91
  attributes:
88
92
  "pager_tree/integrations/integration":
data/config/routes.rb CHANGED
@@ -5,6 +5,7 @@ PagerTree::Integrations::Engine.routes.draw do
5
5
  member do
6
6
  get :music
7
7
  post :queue_status
8
+ post :dropped
8
9
  end
9
10
  end
10
11
  end
@@ -1,5 +1,5 @@
1
1
  module PagerTree
2
2
  module Integrations
3
- VERSION = "1.1.2"
3
+ VERSION = "1.1.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pager_tree-integrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Austin Miller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-21 00:00:00.000000000 Z
11
+ date: 2022-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -85,6 +85,7 @@ files:
85
85
  - app/jobs/pager_tree/integrations/application_job.rb
86
86
  - app/jobs/pager_tree/integrations/outgoing_webhook_job.rb
87
87
  - app/mailers/pager_tree/integrations/application_mailer.rb
88
+ - app/mailers/pager_tree/integrations/live_call_routing/twilio/v3_mailer.rb
88
89
  - app/models/pager_tree/integrations/additional_datum.rb
89
90
  - app/models/pager_tree/integrations/alert.rb
90
91
  - app/models/pager_tree/integrations/apex_ping/v3.rb
@@ -137,6 +138,8 @@ files:
137
138
  - app/models/pager_tree/integrations/webhook/v3.rb
138
139
  - app/models/pager_tree/integrations/zendesk/v3.rb
139
140
  - app/views/layouts/pager_tree/integrations/application.html.erb
141
+ - app/views/layouts/pager_tree/integrations/live_call_routing/twilio/mailer.html.erb
142
+ - app/views/layouts/pager_tree/integrations/live_call_routing/twilio/mailer.text.erb
140
143
  - app/views/pager_tree/integrations/apex_ping/v3/_form_options.html.erb
141
144
  - app/views/pager_tree/integrations/apex_ping/v3/_show_options.html.erb
142
145
  - app/views/pager_tree/integrations/app_dynamics/v3/_form_options.html.erb
@@ -187,6 +190,8 @@ files:
187
190
  - app/views/pager_tree/integrations/kapacitor/v3/_show_options.html.erb
188
191
  - app/views/pager_tree/integrations/live_call_routing/twilio/v3/_form_options.html.erb
189
192
  - app/views/pager_tree/integrations/live_call_routing/twilio/v3/_show_options.html.erb
193
+ - app/views/pager_tree/integrations/live_call_routing/twilio/v3_mailer/call_recording.html.erb
194
+ - app/views/pager_tree/integrations/live_call_routing/twilio/v3_mailer/call_recording.text.erb
190
195
  - app/views/pager_tree/integrations/logic_monitor/v3/_form_options.html.erb
191
196
  - app/views/pager_tree/integrations/logic_monitor/v3/_show_options.html.erb
192
197
  - app/views/pager_tree/integrations/mattermost/outgoing_webhook/v3/_form_options.html.erb