Ejemplo n.º 1
0
    def send_alert(self):
        '''
		This method sends alerts to people who need to get one via sms, phone, or email.
		'''
        logging.debug("Sending alert: %s" % self.id)
        try:
            oncall_users_raw = User.on_call(self.team)
            team_users = User.team_entities(self.team)
            if len(oncall_users_raw) > 0:
                oncall_users = []
                self.tries += 1
                self.lastAlertSent = datetime.datetime.now()
                self.save_alert()
                # grouping users into 2D arrays by state
                oncall_users = User.sort_by_state(oncall_users_raw)
                # filtering on call list with only ones to alert
                if "alert_escalation" in conf and conf['alert_escalation'] > 0:
                    escalate = float(conf['alert_escalation'])
                    num = int(math.ceil(self.tries / escalate))
                    if num == 0: num = 1
                    alert_users = oncall_users[:num]
                else:
                    # just grabbing the primary users (state == 1)
                    alert_users = oncall_users[0]
                # going through list of users (2-dimensional list) to send alerts to and send alerts
                for au in alert_users:
                    for u in au:
                        if "call_failover" in conf:
                            if conf['call_failover'] == 0:
                                twilio.make_call(u, self)
                            else:
                                # check to see if enough tries have been made to this user to switch to calls instead of SMS
                                if int(math.ceil(self.tries / float(
                                        u.state))) > conf['call_failover']:
                                    twilio.make_call(u, self)
                                else:
                                    twilio.send_sms(
                                        u, self.id,
                                        self.subject + "\n" + self.message)
                        else:
                            twilio.send_sms(u, self.id,
                                            self.subject + "\n" + self.message)
                # check if enough tries have been made to send a team notification via email
                if "team_failover" in conf and (
                        conf['team_failover'] == 0
                        or conf['team_failover'] >= self.tries):
                    for t in team_users:
                        e = Email.Email(t, self)
                        e.send_alert_email()
            else:
                #oops no one is on call at the moment. Fall back to a team alert via email
                logging.error("No one is currently on call")
                for t in team_users:
                    e = Email.Email(t, self)
                    e.send_alert_email()
        except Exception, e:
            logging.error(e.__str__())
Ejemplo n.º 2
0
	def send_alert(self):
		'''
		This method sends alerts to people who need to get one via sms, phone, or email.
		'''
		logging.debug("Sending alert: %s" % self.id)
		try:
			oncall_users_raw = User.on_call(self.team)
			team_users = User.team_entities(self.team)
			if len(oncall_users_raw) > 0:
				oncall_users = []
				self.tries += 1
				self.lastAlertSent = datetime.datetime.now()
				self.save_alert()
				# grouping users into 2D arrays by state
				oncall_users = User.sort_by_state(oncall_users_raw)
				# filtering on call list with only ones to alert
				if "alert_escalation" in conf and conf['alert_escalation'] > 0:
					escalate = float(conf['alert_escalation'])
					num = int(math.ceil(self.tries/escalate))
					if num == 0: num = 1
					alert_users = oncall_users[:num]
				else:
					# just grabbing the primary users (state == 1)
					alert_users = oncall_users[0]
				# going through list of users (2-dimensional list) to send alerts to and send alerts
				for au in alert_users:
					for u in au:
						if "call_failover" in conf:
							if conf['call_failover'] == 0:
								twilio.make_call(u, self)
							else:
								# check to see if enough tries have been made to this user to switch to calls instead of SMS
								if int(math.ceil(self.tries/float(u.state))) > conf['call_failover']:
									twilio.make_call(u, self)
								else:
									twilio.send_sms(u, self.id, self.subject + "\n" + self.message)
						else:
							twilio.send_sms(u, self.id, self.subject + "\n" + self.message)
				# check if enough tries have been made to send a team notification via email
				if "team_failover" in conf and (conf['team_failover'] == 0 or conf['team_failover'] >= self.tries):
					for t in team_users:
						e = Email.Email(t,self)
						e.send_alert_email()
			else:
				#oops no one is on call at the moment. Fall back to a team alert via email
				logging.error("No one is currently on call")
				for t in team_users:
					e = Email.Email(t,self)
					e.send_alert_email()					
		except Exception, e:
			logging.error(e.__str__())
Ejemplo n.º 3
0
    def POST(self, name):
        d = web.input(init="true", Digits=0)
        logging.info("Receiving phone call\n%s" % (d))
        web.header('Content-Type', 'text/xml')
        r = twilio.twiml.Response()
        # the message to say when a timeout occurs
        timeout_msg = "Sorry, didn't get any input from you. Goodbye."
        # check if this call was initialized by sending an alert
        if name == "alert":
            # the digit options to press
            digitOpts = '''
Press 1 to hear the message.
Press 2 to acknowledge this alert.
'''
            receiver = User.get_user_by_phone(d.To)
            alert = Alert.Alert(d.alert_id)
            # check if this is the first interaction for this call session
            if d.init.lower() == "true":
                with r.gather(
                        action="%s:%s/call/alert?alert_id=%s&init=false" %
                    (conf['server_address'], conf['port'], alert.id),
                        timeout=conf['call_timeout'],
                        method="POST",
                        numDigits="1") as g:
                    g.say(
                        '''Hello %s, a message from Oncall. An alert has been issued with subject "%s". %s.'''
                        % (receiver.name, alert.subject, digitOpts))
                r.say(timeout_msg)
            else:
                if int(d.Digits) == 1:
                    with r.gather(
                            action="%s:%s/call/alert?alert_id=%s&init=false" %
                        (conf['server_address'], conf['port'], alert.id),
                            timeout="30",
                            method="POST",
                            numDigits="1") as g:
                        g.say('''%s. %s''' % (alert.message, digitOpts))
                    r.say(timeout_msg)
                elif int(d.Digits) == 2:
                    if alert.ack_alert(receiver):
                        r.say(
                            "The alert has been acknowledged. Thank you and goodbye."
                        )
                        r.redirect(
                            url="%s:%s/call/alert?alert_id=%s&init=false" %
                            (conf['server_address'], conf['port'], alert.id))
                    else:
                        r.say(
                            "Sorry, failed to acknowledge the alert. Please try it via SMS"
                        )
                        r.redirect(
                            url="%s:%s/call/alert?alert_id=%s&init=false" %
                            (conf['server_address'], conf['port'], alert.id))
                elif d.Digits == 0:
                    with r.gather(
                            action="%s:%s/call/alert?alert_id=%s&init=false" %
                        (conf['server_address'], conf['port'], alert.id),
                            timeout="30",
                            method="POST",
                            numDigits="1") as g:
                        g.say('''%s''' % (digitOpts))
                    r.say(timeout_msg)
                else:
                    r.say(
                        "Sorry, didn't understand the digits you entered. Goodbye"
                    )
        else:
            requester = User.get_user_by_phone(d.From)
            # get the team that is associate with this phone number the user called
            team = twilio.twil_reverse_phone_num(d.To)
            # if caller is not a oncall user or they are, but calling a different team then they are in
            if requester == False or requester.team != team:
                if team == '':
                    r.say(
                        "Sorry, The phone number you called is not associated with any team. Please contact you system administrator for help."
                    )
                else:
                    # get the first user on call and forward the call to them
                    oncall_users = User.sort_by_state(User.on_call(team))
                    if len(oncall_users) > 0:
                        foundOncallUser = False
                        for userlist in oncall_users:
                            for u in userlist:
                                r.say("Calling %s." % u.name)
                                r.dial(number=u.phone)
                                foundOncallUser = True
                                break
                            if foundOncalluser == True: break
                    else:
                        r.say(
                            "Sorry, currently there is no one on call for %s. Please try again later."
                            % team)
            else:
                # the caller is calling the same team phone number as the team that they are on
                # check if d.Digits is the default value (meaning, either the caller hasn't pushed a button and this is the beginning of the call, or they hit 0 to start over
                if int(d.Digits) == 0:
                    if d.init.lower() == "true":
                        if requester.state > 0 and requester.state < 9:
                            oncall_status = "You are currently on call in spot %s" % (
                                requester.state)
                        else:
                            oncall_users = User.sort_by_state(
                                User.on_call(requester.team))
                            if len(oncall_users) > 0:
                                for userlist in oncall_users:
                                    for u in userlist:
                                        oncall_status = "Currenty, %s is on call" % (
                                            u.name)
                            else:
                                oncall_status = "Currenty, no one is on call"
                        with r.gather(action="%s:%s/call/event?init=false" %
                                      (conf['server_address'], conf['port']),
                                      timeout=conf['call_timeout'],
                                      method="POST",
                                      numDigits="1") as g:
                            g.say(
                                '''Hello %s. %s. Press 1 if you want to hear the present status of alerts. Press 2 to acknowledge the last alert sent to you. Press 3 to conference call everyone on call into this call.'''
                                % (requester.name, oncall_status))
                    else:
                        with r.gather(action="%s:%s/call/event?init=false" %
                                      (conf['server_address'], conf['port']),
                                      timeout=conf['call_timeout'],
                                      method="POST",
                                      numDigits="1") as g:
                            g.say(
                                '''Press 1 if you want to hear the present status of alerts. Press 2 to acknowledge the last alert sent to you. Press 3 to conference call everyone on call into this call.'''
                            )
                    r.say(timeout_msg)
                elif int(d.Digits) == 1:
                    # getting the status of alerts
                    r.say(oncall.run("alert status -f " + requester.phone))
                    r.redirect(url="%s:%s/call/event?init=false" %
                               (conf['server_address'], conf['port']))
                elif int(d.Digits) == 2:
                    # acking the last alert sent to the user calling
                    r.say(oncall.run("alert ack -f " + requester.phone))
                    r.redirect(url="%s:%s/call/event?init=false" %
                               (conf['server_address'], conf['port']))
                elif int(d.Digits) == 3:
                    # calling the other users on call
                    oncall_users_raw = User.on_call(requester.team)
                    for user in oncall_users_raw:
                        if user.phone == requester.phone: continue
                        r.say("Calling %s." % user.name)
                        r.dial(number=user.phone)
                else:
                    r.say(
                        "Sorry, number you pressed is not valid. Please try again."
                    )
        return r