def run(self, campaign_id): """ This task retrieves the next outbound call to be made for a given campaign, and will create a new callrequest and schedule a task to process those calls **Attributes**: * ``campaign_id`` - Campaign ID """ logger = self.get_logger() logger.info("TASK :: pending_call_processing = %d" % campaign_id) debug_query(0) try: obj_campaign = Campaign.objects\ .select_related('user__userprofile__dialersetting', 'aleg_gateway', 'content_type')\ .get(id=campaign_id) except: logger.error("Can't find this campaign") return False # TODO : Control the Speed # if there is many task pending we should slow down frequency = obj_campaign.frequency # default 10 calls per minutes debug_query(1) #TODO: move this logic of setting call_type after CallRequest post_save # Default call_type call_type = CALLREQUEST_TYPE.ALLOW_RETRY # Check campaign's maxretry if obj_campaign.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY # Check user's dialer setting maxretry try: obj_campaign.user.userprofile.dialersetting if obj_campaign.user.userprofile.dialersetting.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY except ObjectDoesNotExist: logger.error("Can't find user's dialersetting") return False debug_query(2) # Speed # Check if the other tasks send for this campaign finished to be ran # Get the subscriber of this campaign # get_pending_subscriber get Max 1000 records if settings.HEARTBEAT_MIN == 1: # 1 task per minute callfrequency = frequency # task run only once per minute, so we can assign frequency else: callfrequency = int(frequency / settings.HEARTBEAT_MIN) + 1 # 1000 per minutes #callfrequency = int(frequency) + 1 # 1000 per minutes (list_subscriber, no_subscriber) = obj_campaign\ .get_pending_subscriber_update(callfrequency, SUBSCRIBER_STATUS.IN_PROCESS) logger.info("##subscriber=%d campaign_id=%d callfreq=%d freq=%d" % (no_subscriber, campaign_id, callfrequency, frequency)) debug_query(3) if no_subscriber == 0: return False # Set time to wait for balanced dispatching of calls time_to_wait = (60.0 / settings.HEARTBEAT_MIN) / no_subscriber count = 0 loopnow = datetime.utcnow() loopnow + timedelta(seconds=1.55) for elem_camp_subscriber in list_subscriber: # Loop on Subscriber and start the initcall's task count = count + 1 second_towait = floor(count * time_to_wait) # ms_addtowait now used anymore, replaced by async eta ms_addtowait = (count * time_to_wait) - second_towait eta_delta = loopnow + timedelta(seconds=(count * time_to_wait)) # as we use eta_delta ms_addtowait is set to 0 ms_addtowait = 0 logger.info("Init CallRequest in %d seconds (cmpg:%d,subscr:%d:eta_delta:%s)" % (second_towait, campaign_id, elem_camp_subscriber.id, eta_delta)) phone_number = elem_camp_subscriber.duplicate_contact debug_query(4) #Verify that the contact is authorized if not obj_campaign.is_authorized_contact(obj_campaign.user.userprofile.dialersetting, phone_number): logger.error("Error : Contact not authorized") elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() continue #Verify that the contact is not in the DNC list if obj_campaign.dnc: res_dnc = DNCContact.objects.filter(dnc_id=obj_campaign.dnc_id, phone_number=phone_number) if res_dnc: logger.error("Contact (%s) in DNC list" % phone_number) elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() continue else: logger.debug("Contact (%s) not in DNC list" % phone_number) debug_query(5) #TODO: idea to speed up, create bluck of 10(Y) and then send a list # of callrequest_id to init_callrequest # Create Callrequest new_callrequest = Callrequest( status=CALLREQUEST_STATUS.PENDING, call_type=call_type, call_time=datetime.utcnow().replace(tzinfo=utc), timeout=obj_campaign.calltimeout, callerid=obj_campaign.callerid, caller_name=obj_campaign.caller_name, phone_number=phone_number, campaign=obj_campaign, aleg_gateway=obj_campaign.aleg_gateway, content_type=obj_campaign.content_type, object_id=obj_campaign.object_id, user=obj_campaign.user, extra_data=obj_campaign.extra_data, timelimit=obj_campaign.callmaxduration, subscriber=elem_camp_subscriber) new_callrequest.save() debug_query(6) second_towait = second_towait + settings.DELAY_OUTBOUND init_callrequest.apply_async( args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait], # countdown=second_towait) eta=eta_delta) # Shell_plus # from dialer_cdr.tasks import init_callrequest # from datetime import datetime # new_callrequest_id = 112 # obj_campaign_id = 3 # countdown = 1 # init_callrequest.apply_async(args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait], countdown=1) debug_query(7) return True
def run(self, **kwargs): logger.info("TASK :: alarmrequest_dispatcher") # Select AlarmRequest where date >= now() - 60 minutes start_time = datetime.utcnow().replace(tzinfo=utc) + relativedelta(minutes=-60) alarmreq_list = AlarmRequest.objects.filter(date__gte=start_time, status=ALARMREQUEST_STATUS.PENDING) no_alarmreq = alarmreq_list.count() if no_alarmreq == 0: logger.error("alarmrequest_dispatcher - no alarmreq found!") return False # Set time to wait for balanced dispatching of calls #time_to_wait = int(60 / DIV_MIN) / no_subscriber time_to_wait = 6.0 / no_alarmreq count = 0 # Browse all the AlarmRequest found for obj_alarmreq in alarmreq_list: # Loop on AlarmRequest and start to the initcall's task count = count + 1 second_towait = floor(count * time_to_wait) ms_addtowait = (count * time_to_wait) - second_towait logger.info("Init CallRequest for AlarmRequest in %d seconds (alarmreq:%d)" % (second_towait, obj_alarmreq.id)) if obj_alarmreq.alarm.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY else: call_type = CALLREQUEST_TYPE.ALLOW_RETRY try: caluser_profile = CalendarUserProfile.objects.get(user=obj_alarmreq.alarm.event.creator) except CalendarUserProfile.DoesNotExist: logger.error("Error retrieving CalendarUserProfile") return False #manager_profile = UserProfile.objects.get(user=caluser_profile.manager) # manager_profile = caluser_profile.manager.get_profile() # manager_profile.dialersetting # Use manager_profile.dialersetting to retrieve some settings # TODO: build settings for this calltimeout = caluser_profile.calendar_setting.call_timeout callmaxduration = 60 * 60 callerid = caluser_profile.calendar_setting.callerid caller_name = caluser_profile.calendar_setting.caller_name aleg_gateway = caluser_profile.calendar_setting.aleg_gateway content_type = ContentType.objects.get(model__in=["survey"]) object_id = caluser_profile.calendar_setting.survey_id # Create Callrequest to track the call task new_callrequest = Callrequest( status=CALLREQUEST_STATUS.PENDING, call_type=call_type, call_time=datetime.utcnow().replace(tzinfo=utc), timeout=calltimeout, callerid=callerid, caller_name=caller_name, phone_number=obj_alarmreq.alarm.alarm_phonenumber, alarm_request_id=obj_alarmreq.id, aleg_gateway=aleg_gateway, content_type=content_type, object_id=object_id, user=caluser_profile.manager, extra_data='', timelimit=callmaxduration) new_callrequest.save() init_callrequest.apply_async( args=[new_callrequest.id, None, callmaxduration, ms_addtowait, obj_alarmreq.id], countdown=second_towait) obj_alarmreq.callrequest = new_callrequest obj_alarmreq.status = ALARMREQUEST_STATUS.IN_PROCESS obj_alarmreq.save() # Increment num_attempt obj_alarmreq.alarm.num_attempt = obj_alarmreq.alarm.num_attempt + 1 obj_alarmreq.alarm.save()
def create(self, request=None, **kwargs): """POST method of Hangupcall API""" logger.debug('Hangupcall API authentication called!') auth_result = self._meta.authentication.is_authenticated(request) if not auth_result is True: raise ImmediateHttpResponse(response=http.HttpUnauthorized()) auth_result = self._meta.authorization.is_authorized(request, object) errors = self._meta.validation.is_valid(request) if not errors: opt_request_uuid = request.POST.get('RequestUUID') opt_hangup_cause = request.POST.get('HangupCause') try: callrequest = Callrequest.objects.get( request_uuid=opt_request_uuid) except: logger.debug('Hangupcall Error cannot find the Callrequest!') try: obj_subscriber = CampaignSubscriber.objects.get( id=callrequest.campaign_subscriber.id) if opt_hangup_cause == 'NORMAL_CLEARING': obj_subscriber.status = 5 # Complete else: obj_subscriber.status = 4 # Fail obj_subscriber.save() except: logger.debug('Hangupcall Error cannot find the ' 'Campaignsubscriber!') # 2 / FAILURE ; 3 / RETRY ; 4 / SUCCESS if opt_hangup_cause == 'NORMAL_CLEARING': callrequest.status = 4 # Success else: callrequest.status = 2 # Failure callrequest.hangup_cause = opt_hangup_cause #save callrequest & campaignsubscriber callrequest.save() data = {} for element in CDR_VARIABLES: if not request.POST.get('variable_%s' % element): data[element] = None else: data[element] = request.POST.get('variable_%s' % element) from_plivo = request.POST.get('From') to_plivo = request.POST.get('To') create_voipcall(obj_callrequest=callrequest, plivo_request_uuid=opt_request_uuid, data=data, data_prefix='', leg='a', hangup_cause=opt_hangup_cause, from_plivo=from_plivo, to_plivo=to_plivo) object_list = [{'result': 'OK'}] logger.debug('Hangupcall API : Result 200!') obj = CustomXmlEmitter() #We will manage the retry directly from the API if opt_hangup_cause != 'NORMAL_CLEARING'\ and callrequest.call_type == 1: # Allow retry #Update to Retry Done callrequest.call_type = 3 callrequest.save() dialer_set = user_dialer_setting(callrequest.user) if callrequest.num_attempt >= callrequest.campaign.maxretry\ or callrequest.num_attempt >= dialer_set.maxretry: logger.error("Not allowed retry - Maxretry (%d)" %\ callrequest.campaign.maxretry) else: #Allowed Retry # TODO : Review Logic # Create new callrequest, Assign parent_callrequest, # Change callrequest_type & num_attempt new_callrequest = Callrequest( request_uuid=uuid1(), parent_callrequest_id=callrequest.id, call_type=1, num_attempt=callrequest.num_attempt + 1, user=callrequest.user, campaign_id=callrequest.campaign_id, aleg_gateway_id=callrequest.aleg_gateway_id, content_type=callrequest.content_type, object_id=callrequest.object_id, phone_number=callrequest.phone_number) new_callrequest.save() #Todo Check if it's a good practice #implement a PID algorithm second_towait = callrequest.campaign.intervalretry launch_date = datetime.now() + \ timedelta(seconds=second_towait) logger.info("Init Retry CallRequest at %s" %\ (launch_date.strftime("%b %d %Y %I:%M:%S"))) init_callrequest.apply_async( args=[new_callrequest.id, callrequest.campaign.id], eta=launch_date) return self.create_response(request, obj.render(request, object_list)) else: if len(errors): if request: desired_format = self.determine_format(request) else: desired_format = self._meta.default_format serialized = self.serialize(request, errors, desired_format) response = http.HttpBadRequest(content=serialized, content_type=desired_format) raise ImmediateHttpResponse(response=response)
def run(self, campaign_id): """ This will execute the outbound calls in the campaign **Attributes**: * ``campaign_id`` - Campaign ID """ logger = self.get_logger() logger.info("TASK :: spool_pending_call = %d" % campaign_id) debug_query(0) try: obj_campaign = Campaign.objects.select_related('user__userprofile__dialersetting', 'aleg_gateway', 'content_type').get(id=campaign_id) except: logger.error("Can't find this campaign") return False # TODO : Control the Speed # if there is many task pending we should slow down frequency = obj_campaign.frequency # default 10 calls per minutes debug_query(1) # Default call_type call_type = CALLREQUEST_TYPE.ALLOW_RETRY # Check campaign's maxretry if obj_campaign.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY # Check user's dialer setting maxretry if obj_campaign.user.userprofile.dialersetting: if obj_campaign.user.userprofile.dialersetting.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY debug_query(2) # Speed # Check if the other tasks send for this campaign finished to be ran # Get the subscriber of this campaign # get_pending_subscriber get Max 1000 records if frequency >= 10: callfrequency = int(frequency / DIV_MIN) + 1 # 1000 per minutes 101 #callfrequency = int(frequency) + 1 # 1000 per minutes 101 else: callfrequency = frequency (list_subscriber, no_subscriber) = obj_campaign.get_pending_subscriber_update(callfrequency, SUBSCRIBER_STATUS.IN_PROCESS) logger.info("##subscriber=%d campaign_id=%d callfrequency=%d frequency=%d" % (no_subscriber, campaign_id, callfrequency, frequency)) debug_query(3) if no_subscriber == 0: return False # Set time to wait for balanced dispatching of calls #time_to_wait = int(60 / DIV_MIN) / no_subscriber time_to_wait = 6.0 / no_subscriber count = 0 for elem_camp_subscriber in list_subscriber: """Loop on Subscriber and start the initcall task""" count = count + 1 second_towait = floor(count * time_to_wait) ms_addtowait = (count * time_to_wait) - second_towait logger.info("Init CallRequest in %d seconds (cmpg:%d,subscriber:%d)" % (second_towait, campaign_id, elem_camp_subscriber.id)) phone_number = elem_camp_subscriber.duplicate_contact debug_query(4) #Verify that the contact is authorized if not obj_campaign.is_authorized_contact(obj_campaign.user.userprofile.dialersetting, phone_number): logger.error("Error : Contact not authorized") elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() return True #Verify that the contact is not in the DNC list if obj_campaign.dnc: res_dnc = DNCContact.objects.filter(dnc_id=obj_campaign.dnc_id, phone_number=phone_number) if res_dnc: logger.error("Contact (%s) in DNC list" % phone_number) elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() return True else: logger.debug("Contact (%s) not in DNC list" % phone_number) debug_query(5) #TODO: idea to speed up, create bluck of 10(Y) and then send a list of callrequest_id to init_callrequest # Create a Callrequest Instance to track the call task new_callrequest = Callrequest( status=CALLREQUEST_STATUS.PENDING, call_type=call_type, call_time=datetime.now(), timeout=obj_campaign.calltimeout, callerid=obj_campaign.callerid, phone_number=phone_number, campaign=obj_campaign, aleg_gateway=obj_campaign.aleg_gateway, content_type=obj_campaign.content_type, object_id=obj_campaign.object_id, user=obj_campaign.user, extra_data=obj_campaign.extra_data, timelimit=obj_campaign.callmaxduration, subscriber=elem_camp_subscriber) new_callrequest.save() debug_query(6) init_callrequest.apply_async( args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait], countdown=second_towait) # Shell_plus # from dialer_cdr.tasks import init_callrequest # from datetime import datetime # new_callrequest_id = 112 # obj_campaign_id = 3 # countdown = 1 # init_callrequest.apply_async(args=[new_callrequest_id, obj_campaign_id], countdown=1) debug_query(7) return True
def check_campaign_pendingcall(campaign_id): """This will execute the outbound calls in the campaign **Attributes**: * ``campaign_id`` - Campaign ID """ logger = check_campaign_pendingcall.get_logger() logger.info("TASK :: check_campaign_pendingcall = %s" % str(campaign_id)) try: obj_campaign = Campaign.objects.get(id=campaign_id) except: logger.error('Can\'t find this campaign') return False #TODO: Control the Speed #if there is many task pending we should slow down frequency = obj_campaign.frequency # default 10 calls per minutes dialer_set = user_dialer_setting(obj_campaign.user) # default call_type call_type = 1 # Check campaign's maxretry if obj_campaign.maxretry == 0: call_type = 2 # Check user's dialer setting maxretry if dialer_set: if dialer_set.maxretry == 0: call_type = 2 # check frequency to control the Speed #if dialer_set.frequency: # frequency = 20 #Speed #check if the other tasks send for this campaign finished to be ran #Get the subscriber of this campaign # get_pending_subscriber get Max 1000 records list_subscriber = obj_campaign.get_pending_subscriber_update( frequency, 6 # Update to In Process ) if list_subscriber: logger.debug("Number of subscriber found : %d" % len(list_subscriber)) try: no_subscriber = list_subscriber.count() except AttributeError: no_subscriber = 0 if no_subscriber == 0: logger.info("No Subscriber to proceed on this campaign") return False #find how to dispatch them in the current minutes time_to_wait = 60.0 / no_subscriber count = 0 for elem_camp_subscriber in list_subscriber: """Loop on Subscriber and start the initcall task""" count = count + 1 logger.info("Add CallRequest for Subscriber (%s) & wait (%s) " % (str(elem_camp_subscriber.id), str(time_to_wait))) #Check if the contact is authorized if not obj_campaign.is_authorized_contact( elem_camp_subscriber.contact.contact): logger.error("Error : Contact not authorized") elem_camp_subscriber.status = 7 # Update to Not Authorized elem_camp_subscriber.save() return True #Create a Callrequest Instance to track the call task new_callrequest = Callrequest( status=1, # PENDING call_type=call_type, call_time=datetime.now(), timeout=obj_campaign.calltimeout, callerid=obj_campaign.callerid, phone_number=elem_camp_subscriber.contact.contact, campaign=obj_campaign, aleg_gateway=obj_campaign.aleg_gateway, content_type=obj_campaign.content_type, object_id=obj_campaign.object_id, user=obj_campaign.user, extra_data=obj_campaign.extra_data, timelimit=obj_campaign.callmaxduration, campaign_subscriber=elem_camp_subscriber) new_callrequest.save() #Todo Check if it's a good practice / implement a PID algorithm second_towait = ceil(count * time_to_wait) launch_date = datetime.now() + timedelta(seconds=second_towait) logger.info("Init CallRequest at %s" % \ (launch_date.strftime("%b %d %Y %I:%M:%S"))) init_callrequest.apply_async( args=[new_callrequest.id, obj_campaign.id], eta=launch_date)
def run(self, campaign_id): """ This task retrieves the next outbound call to be made for a given campaign, and will create a new callrequest and schedule a task to process those calls **Attributes**: * ``campaign_id`` - Campaign ID """ logger = self.get_logger() logger.info("TASK :: pending_call_processing = %d" % campaign_id) debug_query(0) try: obj_campaign = Campaign.objects\ .select_related('user__userprofile__dialersetting', 'aleg_gateway', 'content_type')\ .get(id=campaign_id) except: logger.error("Can't find this campaign") return False # Ensure the content_type become "survey" when campagin starts if not obj_campaign.has_been_started: # change has_been_started flag obj_campaign.has_been_started = True obj_campaign.save() if obj_campaign.content_type.model == 'survey_template': # Copy survey survey_template = Survey_template.objects.get( user=obj_campaign.user, pk=obj_campaign.object_id) survey_template.copy_survey_template(obj_campaign.id) collect_subscriber.delay(obj_campaign.id) # TODO : Control the Speed # if there is many task pending we should slow down frequency = obj_campaign.frequency # default 10 calls per minutes debug_query(1) # TODO: move this logic of setting call_type after CallRequest post_save # Default call_type call_type = CALLREQUEST_TYPE.ALLOW_RETRY # Check campaign's maxretry if obj_campaign.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY # Check user's dialer setting maxretry try: obj_campaign.user.userprofile.dialersetting if obj_campaign.user.userprofile.dialersetting.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY except ObjectDoesNotExist: logger.error("Can't find user's dialersetting") return False debug_query(2) # Speed # Check if the other tasks send for this campaign finished to be ran # Get the subscriber of this campaign # get_pending_subscriber get Max 1000 records if settings.HEARTBEAT_MIN == 1: # 1 task per minute callfrequency = frequency # task run only once per minute, so we can assign frequency else: callfrequency = int( frequency / settings.HEARTBEAT_MIN) + 1 # 1000 per minutes # callfrequency = int(frequency) + 1 # 1000 per minutes (list_subscriber, no_subscriber) = obj_campaign\ .get_pending_subscriber_update(callfrequency, SUBSCRIBER_STATUS.IN_PROCESS) logger.info("##subscriber=%d campaign_id=%d callfreq=%d freq=%d" % (no_subscriber, campaign_id, callfrequency, frequency)) debug_query(3) if no_subscriber == 0: return False list_cr = [] bulk_record = [] # this is used to tag and retrieve the id that are inserted bulk_uuid = str(uuid1()) for elem_camp_subscriber in list_subscriber: phone_number = elem_camp_subscriber.duplicate_contact debug_query(4) # Verify that the contact is authorized if not obj_campaign.is_authorized_contact( obj_campaign.user.userprofile.dialersetting, phone_number): logger.error("Error : Contact not authorized") elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() continue # Verify that the contact is not in the DNC list if obj_campaign.dnc: res_dnc = DNCContact.objects.filter(dnc_id=obj_campaign.dnc_id, phone_number=phone_number) if res_dnc: logger.error("Contact (%s) in DNC list" % phone_number) elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() continue else: logger.debug("Contact (%s) not in DNC list" % phone_number) debug_query(5) bulk_record.append( Callrequest(status=CALLREQUEST_STATUS.PENDING, call_type=call_type, call_time=datetime.utcnow().replace(tzinfo=utc), timeout=obj_campaign.calltimeout, callerid=obj_campaign.callerid, caller_name=obj_campaign.caller_name, phone_number=phone_number, campaign=obj_campaign, aleg_gateway=obj_campaign.aleg_gateway, content_type=obj_campaign.content_type, object_id=obj_campaign.object_id, user=obj_campaign.user, extra_data=obj_campaign.extra_data, timelimit=obj_campaign.callmaxduration, subscriber=elem_camp_subscriber, request_uuid=bulk_uuid)) debug_query(6) # Create Callrequests in Bulk logger.info("Bulk Create CallRequest => %d" % (len(bulk_record))) Callrequest.objects.bulk_create(bulk_record) # Set time to wait for balanced dispatching of calls time_to_wait = (60.0 / settings.HEARTBEAT_MIN) / no_subscriber count = 0 loopnow = datetime.utcnow() loopnow + timedelta(seconds=1.55) # Retrienve the one we just created list_cr = Callrequest.objects.filter(request_uuid=bulk_uuid).all() for cr in list_cr: # Loop on Subscriber and start the initcall's task count = count + 1 second_towait = floor(count * time_to_wait) # ms_addtowait now used anymore, replaced by async eta ms_addtowait = (count * time_to_wait) - second_towait eta_delta = loopnow + timedelta(seconds=(count * time_to_wait)) # as we use eta_delta ms_addtowait is set to 0 ms_addtowait = 0 logger.info( "Init CallRequest in %d seconds (cmpg:%d,subscr:%d:eta_delta:%s)" % (second_towait, campaign_id, elem_camp_subscriber.id, eta_delta)) init_callrequest.apply_async( args=[ cr.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait ], # countdown=second_towait) eta=eta_delta) second_towait = second_towait + settings.DELAY_OUTBOUND # Shell_plus # from dialer_cdr.tasks import init_callrequest # from datetime import datetime # new_callrequest_id = 112 # obj_campaign_id = 3 # countdown = 1 # init_callrequest.apply_async( # args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait], # countdown=1) debug_query(7) return True
def run(self, campaign_id): """ This will execute the outbound calls in the campaign **Attributes**: * ``campaign_id`` - Campaign ID """ logger = self.get_logger() logger.info("TASK :: CheckPendingcall = %d" % campaign_id) debug_query(0) try: obj_campaign = Campaign.objects.select_related('user__userprofile__dialersetting', 'aleg_gateway', 'content_type').get(id=campaign_id) except: logger.error('Can\'t find this campaign') return False # TODO : Control the Speed # if there is many task pending we should slow down frequency = obj_campaign.frequency # default 10 calls per minutes debug_query(1) # Default call_type call_type = CALLREQUEST_TYPE.ALLOW_RETRY # Check campaign's maxretry if obj_campaign.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY # Check user's dialer setting maxretry if obj_campaign.user.userprofile.dialersetting: if obj_campaign.user.userprofile.dialersetting.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY debug_query(2) # Speed # Check if the other tasks send for this campaign finished to be ran # Get the subscriber of this campaign # get_pending_subscriber get Max 1000 records list_subscriber = obj_campaign.get_pending_subscriber_update( frequency, SUBSCRIBER_STATUS.IN_PROCESS ) if list_subscriber: no_subscriber = list_subscriber.count() else: no_subscriber = 0 logger.info("campaign_id=%d #Subscriber: %d" % (campaign_id, no_subscriber)) debug_query(3) if no_subscriber == 0: return False if no_subscriber == 1: # Not many subscriber do a fast dial time_to_wait = 1.0 elif no_subscriber <= 10: # Not many subscriber do a fast dial time_to_wait = 6.0 else: # Set time to wait for balanced dispatching of calls time_to_wait = 60.0 / no_subscriber count = 0 for elem_camp_subscriber in list_subscriber: """Loop on Subscriber and start the initcall task""" count = count + 1 logger.info("Add CallRequest for Subscriber (%d) & wait (%s) " % (elem_camp_subscriber.id, str(time_to_wait))) phone_number = elem_camp_subscriber.duplicate_contact debug_query(4) #Verify that the contact is authorized if not obj_campaign.is_authorized_contact(obj_campaign.user.userprofile.dialersetting, phone_number): logger.error("Error : Contact not authorized") elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() return True #Verify that the contact is not in the DNC list if obj_campaign.dnc: try: DNCContact.objects.get(dnc_id=obj_campaign.dnc_id, phone_number=phone_number) logger.error("Contact (%s) in DNC list" % phone_number) elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() return True except DNCContact.DoesNotExist: logger.debug("Contact (%s) not in DNC list" % phone_number) debug_query(5) # Create a Callrequest Instance to track the call task new_callrequest = Callrequest( status=CALLREQUEST_STATUS.PENDING, call_type=call_type, call_time=datetime.now(), timeout=obj_campaign.calltimeout, callerid=obj_campaign.callerid, phone_number=phone_number, campaign=obj_campaign, aleg_gateway=obj_campaign.aleg_gateway, content_type=obj_campaign.content_type, object_id=obj_campaign.object_id, user=obj_campaign.user, extra_data=obj_campaign.extra_data, timelimit=obj_campaign.callmaxduration, subscriber=elem_camp_subscriber) new_callrequest.save() debug_query(6) second_towait = ceil(count * time_to_wait) logger.info("Init CallRequest in %d seconds (cmpg:%d)" % (second_towait, campaign_id)) init_callrequest.apply_async( args=[new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration], countdown=second_towait) # Shell_plus # from dialer_cdr.tasks import init_callrequest # from datetime import datetime # new_callrequest_id = 112 # obj_campaign_id = 3 # countdown = 1 # init_callrequest.apply_async(args=[new_callrequest_id, obj_campaign_id], countdown=1) debug_query(7) return True
def check_campaign_pendingcall(campaign_id): """This will execute the outbound calls in the campaign **Attributes**: * ``campaign_id`` - Campaign ID """ logger = check_campaign_pendingcall.get_logger() logger.info("TASK :: check_campaign_pendingcall = %s" % str(campaign_id)) try: obj_campaign = Campaign.objects.get(id=campaign_id) except: logger.error('Can\'t find this campaign') return False #TODO: Control the Speed #if there is many task pending we should slow down frequency = obj_campaign.frequency # default 10 calls per minutes dialer_set = user_dialer_setting(obj_campaign.user) # default call_type call_type = 1 # Check campaign's maxretry if obj_campaign.maxretry == 0: call_type = 2 # Check user's dialer setting maxretry if dialer_set: if dialer_set.maxretry == 0: call_type = 2 # check frequency to control the Speed #if dialer_set.frequency: # frequency = 20 #Speed #check if the other tasks send for this campaign finished to be ran #Get the subscriber of this campaign # get_pending_subscriber get Max 1000 records list_subscriber = obj_campaign.get_pending_subscriber_update( frequency, 6 # Update to In Process ) if list_subscriber: logger.debug("Number of subscriber found : %d" % len(list_subscriber)) try: no_subscriber = list_subscriber.count() except AttributeError: no_subscriber = 0 if no_subscriber == 0: logger.info("No Subscriber to proceed on this campaign") return False #find how to dispatch them in the current minutes time_to_wait = 60.0 / no_subscriber count = 0 for elem_camp_subscriber in list_subscriber: """Loop on Subscriber and start the initcall task""" count = count + 1 logger.info("Add CallRequest for Subscriber (%s) & wait (%s) " % (str(elem_camp_subscriber.id), str(time_to_wait))) #Check if the contact is authorized if not obj_campaign.is_authorized_contact( elem_camp_subscriber.contact.contact): logger.error("Error : Contact not authorized") elem_camp_subscriber.status = 7 # Update to Not Authorized elem_camp_subscriber.save() return True #Create a Callrequest Instance to track the call task new_callrequest = Callrequest(status=1, # PENDING call_type=call_type, call_time=datetime.now(), timeout=obj_campaign.calltimeout, callerid=obj_campaign.callerid, phone_number=elem_camp_subscriber.contact.contact, campaign=obj_campaign, aleg_gateway=obj_campaign.aleg_gateway, content_type=obj_campaign.content_type, object_id=obj_campaign.object_id, user=obj_campaign.user, extra_data=obj_campaign.extra_data, timelimit=obj_campaign.callmaxduration, campaign_subscriber=elem_camp_subscriber) new_callrequest.save() #Todo Check if it's a good practice / implement a PID algorithm second_towait = ceil(count * time_to_wait) launch_date = datetime.now() + timedelta(seconds=second_towait) logger.info("Init CallRequest at %s" % \ (launch_date.strftime("%b %d %Y %I:%M:%S"))) init_callrequest.apply_async( args=[new_callrequest.id, obj_campaign.id], eta=launch_date)
def run(self, campaign_id): """ This will execute the outbound calls in the campaign **Attributes**: * ``campaign_id`` - Campaign ID """ logger = self.get_logger() logger.info("TASK :: spool_pending_call = %d" % campaign_id) debug_query(0) try: obj_campaign = Campaign.objects.select_related( 'user__userprofile__dialersetting', 'aleg_gateway', 'content_type').get(id=campaign_id) except: logger.error("Can't find this campaign") return False # TODO : Control the Speed # if there is many task pending we should slow down frequency = obj_campaign.frequency # default 10 calls per minutes debug_query(1) # Default call_type call_type = CALLREQUEST_TYPE.ALLOW_RETRY # Check campaign's maxretry if obj_campaign.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY # Check user's dialer setting maxretry if obj_campaign.user.userprofile.dialersetting: if obj_campaign.user.userprofile.dialersetting.maxretry == 0: call_type = CALLREQUEST_TYPE.CANNOT_RETRY debug_query(2) # Speed # Check if the other tasks send for this campaign finished to be ran # Get the subscriber of this campaign # get_pending_subscriber get Max 1000 records if frequency >= 10: callfrequency = int( frequency / DIV_MIN) + 1 # 1000 per minutes 101 #callfrequency = int(frequency) + 1 # 1000 per minutes 101 else: callfrequency = frequency (list_subscriber, no_subscriber) = obj_campaign.get_pending_subscriber_update( callfrequency, SUBSCRIBER_STATUS.IN_PROCESS) logger.info( "##subscriber=%d campaign_id=%d callfrequency=%d frequency=%d" % (no_subscriber, campaign_id, callfrequency, frequency)) debug_query(3) if no_subscriber == 0: return False # Set time to wait for balanced dispatching of calls #time_to_wait = int(60 / DIV_MIN) / no_subscriber time_to_wait = 6.0 / no_subscriber count = 0 for elem_camp_subscriber in list_subscriber: """Loop on Subscriber and start the initcall task""" count = count + 1 second_towait = floor(count * time_to_wait) ms_addtowait = (count * time_to_wait) - second_towait logger.info( "Init CallRequest in %d seconds (cmpg:%d,subscriber:%d)" % (second_towait, campaign_id, elem_camp_subscriber.id)) phone_number = elem_camp_subscriber.duplicate_contact debug_query(4) #Verify that the contact is authorized if not obj_campaign.is_authorized_contact( obj_campaign.user.userprofile.dialersetting, phone_number): logger.error("Error : Contact not authorized") elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() return True #Verify that the contact is not in the DNC list if obj_campaign.dnc: res_dnc = DNCContact.objects.filter(dnc_id=obj_campaign.dnc_id, phone_number=phone_number) if res_dnc: logger.error("Contact (%s) in DNC list" % phone_number) elem_camp_subscriber.status = SUBSCRIBER_STATUS.NOT_AUTHORIZED elem_camp_subscriber.save() return True else: logger.debug("Contact (%s) not in DNC list" % phone_number) debug_query(5) #TODO: idea to speed up, create bluck of 10(Y) and then send a list of callrequest_id to init_callrequest # Create a Callrequest Instance to track the call task new_callrequest = Callrequest( status=CALLREQUEST_STATUS.PENDING, call_type=call_type, call_time=datetime.now(), timeout=obj_campaign.calltimeout, callerid=obj_campaign.callerid, phone_number=phone_number, campaign=obj_campaign, aleg_gateway=obj_campaign.aleg_gateway, content_type=obj_campaign.content_type, object_id=obj_campaign.object_id, user=obj_campaign.user, extra_data=obj_campaign.extra_data, timelimit=obj_campaign.callmaxduration, subscriber=elem_camp_subscriber) new_callrequest.save() debug_query(6) init_callrequest.apply_async(args=[ new_callrequest.id, obj_campaign.id, obj_campaign.callmaxduration, ms_addtowait ], countdown=second_towait) # Shell_plus # from dialer_cdr.tasks import init_callrequest # from datetime import datetime # new_callrequest_id = 112 # obj_campaign_id = 3 # countdown = 1 # init_callrequest.apply_async(args=[new_callrequest_id, obj_campaign_id], countdown=1) debug_query(7) return True
def create(self, request=None, **kwargs): """POST method of Hangupcall API""" logger.debug('Hangupcall API authentication called!') auth_result = self._meta.authentication.is_authenticated(request) if not auth_result is True: raise ImmediateHttpResponse(response=http.HttpUnauthorized()) auth_result = self._meta.authorization.is_authorized(request, object) errors = self._meta.validation.is_valid(request) if not errors: opt_request_uuid = request.POST.get('RequestUUID') opt_hangup_cause = request.POST.get('HangupCause') try: callrequest = Callrequest.objects.get( request_uuid=opt_request_uuid) except: logger.debug('Hangupcall Error cannot find the Callrequest!') try: obj_subscriber = CampaignSubscriber.objects.get( id=callrequest.campaign_subscriber.id) if opt_hangup_cause == 'NORMAL_CLEARING': obj_subscriber.status = 5 # Complete else: obj_subscriber.status = 4 # Fail obj_subscriber.save() except: logger.debug('Hangupcall Error cannot find the ' 'Campaignsubscriber!') # 2 / FAILURE ; 3 / RETRY ; 4 / SUCCESS if opt_hangup_cause == 'NORMAL_CLEARING': callrequest.status = 4 # Success else: callrequest.status = 2 # Failure callrequest.hangup_cause = opt_hangup_cause #save callrequest & campaignsubscriber callrequest.save() data = {} for element in CDR_VARIABLES: if not request.POST.get('variable_%s' % element): data[element] = None else: data[element] = request.POST.get('variable_%s' % element) from_plivo = request.POST.get('From') to_plivo = request.POST.get('To') create_voipcall(obj_callrequest=callrequest, plivo_request_uuid=opt_request_uuid, data=data, data_prefix='', leg='a', hangup_cause=opt_hangup_cause, from_plivo=from_plivo, to_plivo=to_plivo) object_list = [{'result': 'OK'}] logger.debug('Hangupcall API : Result 200!') obj = CustomXmlEmitter() #We will manage the retry directly from the API if opt_hangup_cause != 'NORMAL_CLEARING'\ and callrequest.call_type == 1: # Allow retry #Update to Retry Done callrequest.call_type = 3 callrequest.save() dialer_set = user_dialer_setting(callrequest.user) if callrequest.num_attempt >= callrequest.campaign.maxretry\ or callrequest.num_attempt >= dialer_set.maxretry: logger.error("Not allowed retry - Maxretry (%d)" %\ callrequest.campaign.maxretry) else: #Allowed Retry # TODO : Review Logic # Create new callrequest, Assign parent_callrequest, # Change callrequest_type & num_attempt new_callrequest = Callrequest( request_uuid=uuid1(), parent_callrequest_id=callrequest.id, call_type=1, num_attempt=callrequest.num_attempt + 1, user=callrequest.user, campaign_id=callrequest.campaign_id, aleg_gateway_id=callrequest.aleg_gateway_id, content_type=callrequest.content_type, object_id=callrequest.object_id, phone_number=callrequest.phone_number) new_callrequest.save() #Todo Check if it's a good practice #implement a PID algorithm second_towait = callrequest.campaign.intervalretry launch_date = datetime.now() + \ timedelta(seconds=second_towait) logger.info("Init Retry CallRequest at %s" %\ (launch_date.strftime("%b %d %Y %I:%M:%S"))) init_callrequest.apply_async( args=[new_callrequest.id, callrequest.campaign.id], eta=launch_date) return self.create_response(request, obj.render(request, object_list)) else: if len(errors): if request: desired_format = self.determine_format(request) else: desired_format = self._meta.default_format serialized = self.serialize(request, errors, desired_format) response = http.HttpBadRequest( content=serialized, content_type=desired_format) raise ImmediateHttpResponse(response=response)