Skip to content

Instantly share code, notes, and snippets.

/Incident._coffee Secret
Created Jan 20, 2016

Embed
What would you like to do?
moment = require 'moment'
queue = require '../ctrl/queue'
randos = require '../ctrl/randos'
utils = require '../ctrl/utils'
Model = require './Model'
class Incident extends Model
constructor: (data) ->
_l.extend @, data
if @id then @hid = utils.getHashId @id
# Ensure segments are ordered correctly
@segments = if @segments?.length then _l.sortBy(@segments, 'id') else []
@segment0 = if @segments.length then @segments[0] else null
@segmentN = if @resolution_id then _l.find(@segments, {id: @resolution_id}) else null
# Create Twilio urls
@noAnswerUrl = "/api/twilio/incident/#{@hid}/no_answer"
@voicemailUrl = "/api/twilio/incident/#{@hid}/voicemail"
getIncompleteSegments: ->
return _l(@segments)
.chain()
.reject({incoming: true})
.reject({completed: true})
.reject((s) ->
return s.id is @segments[0].id
)
.value()
# Gets the list owner (if they're a participant), the inciter, and
# the resolver (if it's been resolved)
getMainCast: ->
participants = @getParticipants()
cast = _l.extend {},
owner: _l.find(participants, {user_id: @list.owner_id}) or null
resolved: !!@resolution_id
resolver: _l.find(participants, {user_id: @segmentN?.user_id}) or null
if @segment0.user_id
cast.inciter = _l.find(participants, {user_id: @segment0.user_id})
else
cast.inciter = _l.find(participants, {user_id: @segment0.rando_id})
cast
getParticipants: (except) ->
users = _l(@segments).pluck('user').compact().uniq('user_id').compact().value()
# Add list member data (call, email, sms _enabled) for each user
for user, i in users
member = _l.find(@list.members, {user_id: user.user_id}) or {}
_l.extend users[i],
call_enabled: member.call_enabled
email_enabled: member.email_enabled
sms_enabled: member.sms_enabled
randos = _l(@segments).pluck('rando').compact().uniq('rando_id').compact().value()
# Remove someone?
if except?.user_id
users = _l.reject users, {user_id: except.user_id}
else if except?.rando_id
randos = _l.reject randos, {rando_id: except.rando_id}
# Return
users.concat(randos)
getParticipantsByChannel: (type, except) ->
participants = @getParticipants except
users = []
randos =[]
switch type
when 'email'
users = _l.filter participants, (obj) ->
obj.user_id and obj.email and obj.email_enabled
randos = _l.filter participants, (obj) ->
!!obj.rando_id and obj.email
when 'sms'
users = _l.filter participants, (obj) ->
!!obj.user_id and (obj.phone and obj.sms_enabled)
randos = _l.filter participants, (obj) ->
!!obj.rando_id and obj.phone
else
console.error "Unrecognized contact 'channel' #{type}"
users.concat(randos)
# Gets ALL responders who could be contacted, optionally excluding one user
getResponders: (except_user_id=null) ->
_l.reject @list.members, {user_id: except_user_id}
# Get responders who have a phone number and "call_enabled: true"
getRespondersToCall: (parent_segment=null, tier=null) ->
responders = @getResponders except_user_id
# Get members for the given tier
responders = _l(responders)
.chain()
.filter({call_enabled: true})
.filter((r) ->
if tier isnt undefined
return r.tier is tier
else
return true
)
.filter((r)->
!!utils.formatPhone(r.phone)
)
.value()
# Unless this is the first segment,
unless @segments.length is 1
if @segment0.rando # If a rando initiated, call them too
responders.push @segment0.rando
#log "incident.getRespondersToCall returning #{responders.length}", responders
return responders
# Get responders who have a phone number and "call_enabled: true"
getRespondersToCall: (except_user_id=null, tier=null) ->
responders = @getResponders except_user_id
# Get members for the given tier
responders = _l(responders)
.chain()
.filter({call_enabled: true})
.filter((r) ->
if tier isnt undefined
return r.tier is tier
else
return true
)
.filter((r)->
!!utils.formatPhone(r.phone)
)
.value()
# If a rando initiated, call them too
if @segment0.rando
responders.push @segment0.rando
#log "incident.getRespondersToCall returning #{responders.length}", responders
return responders
# Checks for list_members above the segment's current tier.
canEscalate: ->
maxSegmentTier = _l(@segments).pluck('tier').max()
maxMemberTier = _l(@list.members).pluck('tier').max()
(maxMemberTier > maxSegmentTier)
userCanEscalate: (user_id) ->
@userCanResolve user_id
userCanResolve: (user_id) ->
user_ids = _l(@list.members).pluck('user_id').compact().uniq().value()
user_ids.push @list.owner_id
user_id in user_ids
_queueNotification: (type, data, _) ->
try
queue.put {type, data}, _
catch e
console.error "Incident._queueNotification(`#{type}`), ERROR QUEUEING MESSAGE (2009898)", e, data
queueCreationNotification: (_) ->
@_queueNotification 'new_incident', {incident_id: @id}, _
queueIncomingCallNotification: (segment_id, _) ->
@_queueNotification 'incoming_call', {
incident_id: @id
segment_id: segment_id
}, _
queueIncomingEmailNotification: (segment_id, _) ->
@_queueNotification 'incoming_email', {
incident_id: @id
segment_id: segment_id
}, _
queueIncomingSmsNotification: (actor, segment_id, _) ->
@_queueNotification 'incoming_sms', {
incident_id: @id
segment_id: segment_id
user_id: actor.user_id
rando_id: actor.rando_id
}, _
queueEscalate: (_, seconds=0) ->
try
@_queueNotification 'escalate', {
incident_id: @id
updated_at: @updated_at
}, _, seconds
knex('incidents').where({id: @id}).update({updated_at: @updated_at}).then _, _
catch e
console.error "ERROR: Incident.queueEscalate(#{@id}), (1691486)", e
queueResolved: (_) ->
@_queueNotification 'resolved', {incident_id: @id}, _
queueAutoresolve: (_, seconds=0) ->
try
@_queueNotification 'autoresolve', {
incident_id: @id
updated_at: @updated_at
}, _, seconds
knex('incidents').where({id: @id}).update({updated_at: @updated_at}).then _, _
catch e
console.error "ERROR: Incident.queueAutoResolve(#{@id}), (7119563)", e
module.exports = Incident
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.