def create(self, request=None, **kwargs): """POST method of DialCallback API""" logger.debug('DialCallback API authentication called!') auth_result = self._meta.authentication.is_authenticated(request) if not auth_result is True: raise ImmediateHttpResponse(response=http.HttpUnauthorized()) logger.debug('DialCallback API authorization called!') auth_result = self._meta.authorization.is_authorized(request, object) logger.debug('DialCallback API validation called!') errors = self._meta.validation.is_valid(request) if not errors: logger.debug('DialCallback API get called!') opt_aleg_uuid = request.POST.get('DialALegUUID') opt_dial_bleg_uuid = request.POST.get('DialBLegUUID') opt_dial_bleg_status = request.POST.get('DialBLegStatus') #We are just analyzing the hangup if opt_dial_bleg_status != 'hangup': object_list = [{'result': 'OK - Bleg status is not Hangup'}] logger.debug('DialCallback API : Result 200!') obj = CustomXmlEmitter() return self.create_response(request, obj.render(request, object_list)) callrequest = Callrequest.objects.get(aleg_uuid=opt_aleg_uuid) 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=callrequest.request_uuid, data=data, data_prefix='', leg='b', from_plivo=from_plivo, to_plivo=to_plivo) object_list = [{'result': 'OK'}] logger.debug('DialCallback API : Result 200!') obj = CustomXmlEmitter() 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 create(self, request, **kwargs): """POST method of CDR_Store API""" logger.debug('CDR API authentication called!') auth_result = self._meta.authentication.is_authenticated(request) if not auth_result is True: raise ImmediateHttpResponse(response=http.HttpUnauthorized()) logger.debug('CDR API authorization called!') auth_result = self._meta.authorization.is_authorized(request, object) errors = self._meta.validation.is_valid(request) logger.debug('CDR API get called from IP %s' % request.META.get('REMOTE_ADDR')) if not errors: opt_cdr = request.POST.get('cdr') #XML parsing doesn't work if you urldecode first #decoded_cdr = urllib.unquote(opt_cdr.decode("utf8")) decoded_cdr = opt_cdr data = {} try: import xml.etree.ElementTree as ET tree = ET.fromstring(decoded_cdr) lst = tree.find("variables") except: logger.debug('Error parse XML') raise for j in lst: if j.tag in CDR_VARIABLES: data[j.tag] = urllib.unquote(j.text.decode("utf8")) for element in CDR_VARIABLES: if element in data: data[element] = None else: logger.debug("%s not found!") #TODO: Add tag for newfies in outbound call if not 'request_uuid' in data or not data['request_uuid']: # CDR not related to plivo error_msg = 'CDR not related to Newfies/Plivo!' logger.error(error_msg) raise BadRequest(error_msg) #TODO : delay if not find callrequest try: # plivo add "a_" in front of the uuid # for the aleg so we remove the "a_" if data['request_uuid'][1:2] == 'a_': request_uuid = data['request_uuid'][2:] else: request_uuid = data['request_uuid'] obj_callrequest = Callrequest.objects.get( request_uuid=request_uuid) except: # Send notification to admin from dialer_campaign.views import common_send_notification from django.contrib.auth.models import User recipient_list = User.objects.filter( is_superuser=1, is_active=1) # send to all admin user for recipient in recipient_list: # callrequest_not_found - notification id 8 common_send_notification(request, 8, recipient) error_msg = "Error, there is no callrequest for "\ "this uuid %s " % data['request_uuid'] logger.error(error_msg, extra={'stack': True}) raise BadRequest(error_msg) # CREATE CDR - VOIP CALL create_voipcall( obj_callrequest, request_uuid, data, data_prefix='', leg='a') # List of HttpResponse : # https://github.com/toastdriven/django-tastypie/blob/master/tastypie/http.py logger.debug('CDR API : Result 200') object_list = [{'result': 'OK'}] obj = CustomXmlEmitter() 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 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 create(self, request=None, **kwargs): """POST method of Answercall API""" logger.debug('Answercall API authentication called!') auth_result = self._meta.authentication.is_authenticated(request) if not auth_result is True: raise ImmediateHttpResponse(response=http.HttpUnauthorized()) logger.debug('Answercall API authorization called!') auth_result = self._meta.authorization.is_authorized(request, object) logger.debug('Answercall API validation called!') errors = self._meta.validation.is_valid(request) if not errors: logger.debug('Answercall API get called!') opt_ALegRequestUUID = request.POST.get('ALegRequestUUID') opt_CallUUID = request.POST.get('CallUUID') #TODO: If we update the Call to success here we should # not do it in hangup url obj_callrequest = Callrequest.objects\ .get(request_uuid=opt_ALegRequestUUID) #TODO : use constant obj_callrequest.status = 8 # IN-PROGRESS obj_callrequest.aleg_uuid = opt_CallUUID obj_callrequest.save() # check if Voice App if obj_callrequest.content_object.__class__.__name__ != 'VoiceApp': object_list = [] logger.error('Error with App type, not a VoiceApp!') else: data = obj_callrequest.content_object.data tts_language = obj_callrequest.content_object.tts_language extra_data = obj_callrequest.campaign.extra_data if extra_data and len(extra_data) > 1: #check if we have a voice_app_data tag to replace voice_app_data = search_tag_string(extra_data, 'voice_app_data') if voice_app_data: data = voice_app_data if obj_callrequest.content_object.type == 1: #Dial timelimit = obj_callrequest.timelimit callerid = obj_callrequest.callerid gatewaytimeouts = obj_callrequest.timeout gateways = obj_callrequest.content_object.gateway.gateways dial_command = 'Dial timeLimit="%s" ' \ 'callerId="%s" ' \ 'callbackUrl="%s"' % \ (timelimit, callerid, PLIVO_DEFAULT_DIALCALLBACK_URL) number_command = 'Number gateways="%s" ' \ 'gatewayTimeouts="%s"' % \ (gateways, gatewaytimeouts) object_list = [{dial_command: {number_command: data}}] logger.debug('Dial command') elif obj_callrequest.content_object.type == 2: #PlayAudio object_list = [{'Play': data}] logger.debug('PlayAudio') elif obj_callrequest.content_object.type == 3: #Conference object_list = [{'Conference': data}] logger.debug('Conference') elif obj_callrequest.content_object.type == 4: #Speak if settings.TTS_ENGINE != 'ACAPELA': object_list = [{'Speak': data}] logger.debug('Speak') else: import acapela DIRECTORY = settings.MEDIA_ROOT + '/tts/' domain = Site.objects.get_current().domain tts_acapela = acapela.Acapela( settings.TTS_ENGINE, settings.ACCOUNT_LOGIN, settings.APPLICATION_LOGIN, settings.APPLICATION_PASSWORD, settings.SERVICE_URL, settings.QUALITY, DIRECTORY) tts_acapela.prepare(data, tts_language, settings.ACAPELA_GENDER, settings.ACAPELA_INTONATION) output_filename = tts_acapela.run() audiofile_url = domain + settings.MEDIA_URL +\ 'tts/' + output_filename object_list = [{'Play': audiofile_url}] logger.debug('PlayAudio-TTS') else: logger.error('Error with Voice App type!') obj = CustomXmlEmitter() return self.create_response(request, obj.render(request, object_list)) else: logger.debug('ERROR : ' + str(errors)) 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)