def process_pending_callback(callback, mtt_response_result_struct=None, call_description=None, callback_status=None, condition=None): print 'process_pending_callback', callback.id, mtt_response_result_struct is not None, callback_status, call_description, condition if mtt_response_result_struct: record_url_a = mtt_response_result_struct.get('call_back_record_URL_A', '') record_url_a = mtt_response_result_struct.get('downloadURL', '') record_url_b = mtt_response_result_struct.get('call_back_record_URL_B', '') record_url_b = mtt_response_result_struct.get('downloadURL', '') callback_info = CallbackInfo( widget = callback.widget, call_description = mtt_response_result_struct.get('callDescription', ''), phone_number_side_a = mtt_response_result_struct.get('destination_A', ''), phone_number_side_b = mtt_response_result_struct.get('destination_B', ''), charged_length_a_sec = int(mtt_response_result_struct.get('call_back_charged_length_A', '0')), charged_length_b_sec = int(mtt_response_result_struct.get('call_back_charged_length_B', '0')), real_length_a_sec = int(mtt_response_result_struct.get('call_back_real_length_A', '0')), real_length_b_sec = int(mtt_response_result_struct.get('call_back_real_length_B', '0')), record_url_a = record_url_a, record_url_b=record_url_b, waiting_period_a_sec = mtt_response_result_struct.get('waiting_period_A', '0'), waiting_period_b_sec = mtt_response_result_struct.get('waiting_period_B', '0'), callback_status = tracking_history_to_callback_status(callback.tracking_history, condition), cost = mtt_response_result_struct.get('call_back_cost', 0.0), currency = mtt_response_result_struct.get('call_back_currency', 'RUB'), ip_side_b = callback.ip_side_b, geodata_side_b = callback.geodata_side_b, mtt_callback_call_id = callback.mtt_callback_call_id, referer = callback.referer, search_request=callback.search_request, when = callback.when, tracking_history = callback.tracking_history) callback_info.save() print ' new CallbackInfo created from MTT response:', callback_info try: charged_a = int(mtt_response_result_struct.get('call_back_charged_length_A', '0')) charged_b = int(mtt_response_result_struct.get('call_back_charged_length_B', '0')) delta = int((float(charged_a) + float(charged_b)) / 60.0) callback.widget.client.balance_minutes -= delta callback.widget.client.save() print ' BALANCE:', callback.widget.client.name, callback.widget.client.email, callback.widget.client.balance_minutes, delta except Exception as e: traceback.print_exc() if callback.widget.client.balance_minutes < 1: if callback.widget.is_email_notification_on: try: # notify manager via email mail.send_email_zero_balance( str(callback.widget.out_of_balance_notifications_email),) except: traceback.print_exc() if callback.widget.is_sms_notification_on: try: sms.send(callback.widget.sms_notification_number, u'CallFeed.NET: на вашем балансе недостаточно средств для совершения звонков') except: traceback.print_exc() print ' %s processed and removed' % callback callback.delete() return if not callback.mtt_callback_call_id: print ' WARNING!!! unknown mtt_callback_call_id, nothing to process, %s not removed' % callback return new_callback_status = callback.callback_status if callback_status is None: new_callback_status = tracking_history_to_callback_status(callback.tracking_history, condition) else: new_callback_status = callback_status callback_info = None try: callback_info = CallbackInfo.objects.get(mtt_callback_call_id=callback.mtt_callback_call_id) print ' found existing CallbackInfo in the DB:', callback_info except: if call_description is None: call_description = 'ОШИБКА! Неизвестный статус звонка' callback_info = CallbackInfo( widget = callback.widget, call_description = call_description, phone_number_side_b = callback.phone_number_side_b, mtt_callback_call_id = callback.mtt_callback_call_id, when = callback.when, callback_status = new_callback_status, referer = callback.referer, search_request = callback.search_request, tracking_history = callback.tracking_history, ip_side_b = callback.ip_side_b, geodata_side_b = callback.geodata_side_b, planned_for_datetime = callback.planned_for_datetime) callback_info.save() print ' new CallbackInfo created from PendingCallback:', callback_info callback.delete() print ' %s processed and removed' % callback
def get(self, request): try: if 'callback' not in request.GET: return HttpResponse(json.dumps({ 'response': 'error', 'message': 'callback argument not specified'}, ensure_ascii=False), 'application/json') if 'token' not in request.GET: return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps({ 'response': 'error', 'message': 'token argument not specified'}, ensure_ascii=False)), 'text/javascript') #--- read from DB by token ID token = request.GET.get('token', None) widget = None try: widget = Widget.objects.get(id=int(token)) except: import traceback return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps({ 'response': 'error', 'message': 'no widget found, token=%s, error=%s' % ( token, traceback.format_exc())}, ensure_ascii=False)), 'text/javascript') client_ip_addr = request.META.get('REMOTE_ADDR', '') jdata = { 'callback': request.GET['callback'].replace('CallbackRegistry.', ''), 'ip': client_ip_addr, 'token': request.GET['token'], 'referrer': urllib2.unquote(request.GET.get('referrer', '')), 'search_request': urllib2.unquote(request.GET.get('search_request', '')), 'hostname': urllib2.unquote(request.GET.get('hostname', '')), } widget.last_executed = timezone.now() widget.save() #--- check ip in black list if self.is_ip_in_blacklist(jdata['ip'], widget.blacklist_ip.split(',')): jdata.update({'response': 'refused', 'message': '%s were found in the black list' % jdata['ip'], }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') try: operators = widget.client.operator_set.all() if widget.related_operators.count() < 1 \ else widget.related_operators.all() except: import traceback return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps({ 'response': 'error', 'message': 'no operators found, token=%s, error=%s' % ( token, traceback.format_exc())}, ensure_ascii=False)), 'text/javascript') #--- is_active try: is_on = widget.is_active is_active = widget.client.balance_minutes > 1 except: return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps({ 'response': 'error', 'message': 'unable to read the data from DB'}, ensure_ascii=False)), 'text/javascript') #--- check paid status # if MTT balance is too low or widget is not active - set to false jdata['mode'] = 'paid' if is_active else 'free' if not is_on: jdata['mode'] = 'off' #--- managers manager = {} managers_wo_phones = [] for i, operator in enumerate(operators, 1): if operator == widget.default_operator: managers_wo_phones.insert(0, { # 'name': operator.name.encode('utf8').decode('utf8'), # 'role': operator.position.encode('utf8').decode('utf8'), 'name': unicode(operator.name).encode('unicode-escape'), 'role': unicode(operator.position).encode('unicode-escape'), 'photo_url': operator.photo_url, }) manager = { # 'name': operator.name.encode('utf8').decode('utf8'), # 'role': operator.position.encode('utf8').decode('utf8'), 'name': unicode(operator.name).encode('unicode-escape'), 'role': unicode(operator.position).encode('unicode-escape'), 'photo_url': operator.photo_url, } else: managers_wo_phones.append({ # 'name': operator.name.encode('utf8').decode('utf8'), # 'role': operator.position.encode('utf8').decode('utf8'), 'name': unicode(operator.name).encode('unicode-escape'), 'role': unicode(operator.position).encode('unicode-escape'), 'photo_url': operator.photo_url, }) if not len(managers_wo_phones): jdata.update({ 'response': 'error', 'message': 'no managers found for this widget'}) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') if len(manager) == 0: manager = managers_wo_phones[0] # return managers to the widget - to show pictures and names # but without phone number jdata['managers'] = managers_wo_phones # provide client schedule jdata['schedule'] = widget.schedule.asList() #--- REQUEST OPTIONS # retrieve widget settings from DB when widget loads if 'request_options' in request.GET: hostname = request.GET.get('hostname', None) valid_host = False print 'request_options', unicode(widget.site_url).encode(locale.getpreferredencoding()) if hostname: # print 'hostname', type(hostname) hostname = unicode(hostname) hostname = hostname.replace('www.', '') try: print hostname.encode(locale.getpreferredencoding()) except: print 'FAIL: hostname.encode(locale.getpreferredencoding())' if widget.site_url.count(hostname): valid_host = True if not valid_host: try: hostname_uq = urllib2.unquote(hostname) if widget.site_url.count(hostname_uq): valid_host = True # print 'hostname_uq', type(hostname_uq) print hostname_uq.encode(locale.getpreferredencoding()) except: print 'FAIL: hostname_uq = urllib2.unquote(hostname)' if not valid_host: try: hostname_idna = hostname.decode('idna') if widget.site_url.count(hostname_idna): valid_host = True # print 'hostname_idna', type(hostname_idna) print hostname_idna.encode(locale.getpreferredencoding()) except: print 'FAIL: hostname_idna = hostname.decode("idna")' if not valid_host: try: hostname_utf8 = hostname_uq.decode('utf8') if widget.site_url.count(hostname_utf8): valid_host = True # print 'hostname_utf8', type(hostname_utf8) print hostname_utf8.encode(locale.getpreferredencoding()) except: print 'FAIL: hostname_utf8 = hostname_uq.decode("utf8")' if not valid_host: try: hostname_win1251 = hostname_uq.decode('windows-1251') if widget.site_url.count(hostname_win1251): valid_host = True # print 'hostname_win1251', type(hostname_win1251) print hostname_win1251.encode(locale.getpreferredencoding()) except: print 'FAIL: hostname_win1251 = hostname_uq.decode("windows-1251")' print 'valid_host:', valid_host if not valid_host: jdata.update({'response': 'refused', 'message': 'incorrect host name', }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') s = widget.settings s = json.loads(s) try: for k in s.keys(): if isinstance(s[k], unicode): s[k] = (s[k].encode('unicode-escape')) elif isinstance(s[k], str): s[k] = (unicode(s[k]).encode('unicode-escape')) except: import traceback traceback.print_exc() # BE SURE TO CHECK FOR DEFAULT VALUES FOR ALL NEW OPTIONS !!! if 'cookie_ttl_seconds' not in s: s['cookie_ttl_seconds'] = 1 * 60 * 60 if 'submit_button_line_height' not in s: s['submit_button_line_height'] = 42 if 'encoding' not in s: s['encoding'] = 'utf-8' # TODO s['position'] = 'fixed' s['flag_is_operator_shown_in_widget'] = widget.is_operator_shown_in_widget s['flag_disable_on_mobiles'] = widget.disable_on_mobiles jdata['options'] = s jdata.update({ 'response': 'ok', 'message': 'connected'}) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') #--- REQUEST STATUS if 'request_status' in request.GET: hostname = request.GET.get('hostname', None) call_id = request.GET.get('callback_id', None) valid_host = False # print 'request_options', widget.site_url, hostname, unicode(hostname).decode('idna'), type(unicode(hostname).decode('idna')) if hostname: if widget.site_url.count(hostname): valid_host = True if widget.site_url.count(unicode(hostname).decode('idna')): valid_host = True if not valid_host: jdata.update({'response': 'refused', 'message': 'incorrect host name', }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') try: callback = PendingCallback.objects.get(id=call_id) except ObjectDoesNotExist: random_delay(finishing_with=0.6) # to prevent time attacks jdata.update({'response': 'failed', 'message': 'call id %s not found' % call_id, }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') jdata['status'] = { 'tracking_history': callback.tracking_history, 'callback_status': callback.callback_status, } jdata.update({ 'response': 'ok', 'message': 'connected'}) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') #--- ORDER CALL if 'order_time' in request.GET and 'order_day' in request.GET and 'order_delta_day' in request.GET and 'order_phone' in request.GET: jdata['notify_by_email'] = widget.callback_notifications_email jdata['order_time'] = request.GET['order_time'] jdata['order_day'] = request.GET['order_day'] jdata['order_delta_day'] = request.GET['order_delta_day'] jdata['order_phone'] = request.GET['order_phone'] if self.is_number_in_blacklist(jdata['order_phone'], widget.blacklist_phones.split(',')): jdata.update({'response': 'refused', 'message': '%s were found in the black list' % jdata['order_phone'], }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') try: if widget.is_email_notification_on: # notify manager via email mail.send_email_order_call( widget.callback_notifications_email, jdata['order_phone'], jdata['order_day'], jdata['order_time'], widget.site_url) if widget.is_sms_notification_on: # notify manager via SMS sms.send(widget.sms_notification_number, u"CallFeed.NET: обратный звонок на %s, телефон: %s, время для связи: %s в %s" % ( widget.site_url, jdata['order_phone'], widget.callback_notifications_email, jdata['order_time'])) response = 'ok' except: traceback.print_exc() response = 'exception: ' + traceback.format_exc() jdata.update({'response': response, 'message': 'sending email to manager on %s' % widget.callback_notifications_email, }) try: order_time = jdata['order_time'].split(':') order_date = datetime.datetime.combine( datetime.datetime.now() + datetime.timedelta(days=int(jdata['order_delta_day'])), datetime.time(hour=int(order_time[0]), minute=int(order_time[1]))) self.order_deferred_callback(widget, jdata['ip'], jdata['referrer'], jdata['search_request'], order_date, jdata['order_phone']) except: import traceback print traceback.format_exc() print ' ORDER call on %s' % (widget.site_url,) # temporary save data to the local file filename = '/home/callfeed/incomings/%s_%s.txt' % ( jdata['ip'].replace('.', '_'), jdata['callback']) open(filename, 'wb').write(pprint.pformat(jdata)) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') #--- TIME OFF if 'timeoff_time' in request.GET and 'timeoff_day' in request.GET and 'timeoff_phone' in request.GET: jdata['notify_by_email'] = widget.callback_notifications_email jdata['timeoff_time'] = request.GET['timeoff_time'] jdata['timeoff_day'] = request.GET['timeoff_day'] jdata['timeoff_phone'] = request.GET['timeoff_phone'] if self.is_number_in_blacklist(jdata['timeoff_phone'], widget.blacklist_phones.split(',')): jdata.update({'response': 'refused', 'message': '%s were found in the black list' % jdata['timeoff_phone'], }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') try: if widget.is_email_notification_on: # notify manager via email mail.send_email_timeoff_order_call( widget.callback_notifications_email, jdata['timeoff_phone'], jdata['timeoff_day'], jdata['timeoff_time'], widget.site_url) if widget.is_sms_notification_on: # notify manager via SMS sms.send(widget.sms_notification_number, u"CallFeed.NET: заказ звонка с %s в нерабочее время, телефон: %s, время для связи: %s в %s" % ( widget.site_url, jdata['timeoff_phone'], jdata['timeoff_day'], jdata['timeoff_time'])) response = 'ok' except: traceback.print_exc() response = 'exception: ' + traceback.format_exc() jdata.update({'response': response, 'message': 'sending email to manager, email=%s' % widget.callback_notifications_email, }) print ' visitor made a TIME OFF call on %s' % widget.site_url # temporary save data to the local file filename = '/home/callfeed/incomings/%s_%s.txt' % ( jdata['ip'].replace('.', '_'), jdata['callback']) open(filename, 'wb').write(pprint.pformat(jdata)) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') #--- SEND MESSAGE if 'message_text' in request.GET and 'message_email' in request.GET and 'message_phone' in request.GET: jdata['notify_by_email'] = widget.callback_notifications_email jdata['message_text'] = request.GET['message_text'] jdata['message_email'] = request.GET['message_email'] jdata['message_phone'] = request.GET['message_phone'] if self.is_number_in_blacklist(jdata['message_phone'], widget.blacklist_phones.split(',')): jdata.update({'response': 'refused', 'message': '%s were found in the black list' % jdata['message_phone'], }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') try: # notify manager via email mail.send_email_message( str(widget.offline_message_notifications_email), jdata['message_phone'], str(jdata['message_email']), jdata['message_text'], widget.site_url) if widget.is_sms_notification_on: # notify manager via SMS sms.send(widget.sms_notification_number, u"CallFeed.NET: новое входящее сообщение на %s, проверьте почту" % (widget.site_url)) response = 'ok' except: traceback.print_exc() response = 'exception: ' + traceback.format_exc() jdata.update({'response': response, 'message': 'sending email to manager', }) print " incomming MESSAGE on %s" % widget.site_url # temporary save data to the local file filename = '/home/callfeed/incomings/%s_%s.txt' % ( jdata['ip'].replace('.', '_'), jdata['callback']) open(filename, 'wb').write(pprint.pformat(jdata)) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') #--- FREE VERSION if 'free_time' in request.GET and 'free_day' in request.GET and 'free_phone' in request.GET: jdata['notify_by_email'] = widget.callback_notifications_email jdata['free_time'] = request.GET['free_time'] jdata['free_day'] = request.GET['free_day'] jdata['free_phone'] = request.GET['free_phone'] if self.is_number_in_blacklist(jdata['free_phone'], widget.blacklist_phones.split(',')): jdata.update({'response': 'refused', 'message': '%s were found in the black list' % jdata['free_phone'], }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') try: mail.send_email_free_version_notification( widget.callback_notifications_email, jdata['free_phone'], jdata['free_day'], jdata['free_time'], widget.site_url) # notify manager via email response = 'ok' except: traceback.print_exc() response = 'exception: ' + traceback.format_exc() jdata.update({'response': response, 'message': 'sending email to manager, email=%s' % widget.callback_notifications_email, }) print ' FREE call from visitor on %s' % (widget.site_url,) # temporary save data to the local file filename = '/home/callfeed/incomings/%s_%s.txt' % ( jdata['ip'].replace('.', '_'), jdata['callback']) open(filename, 'wb').write(pprint.pformat(jdata)) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') #--- PAID VERSION CHECK if 'phone' not in request.GET: jdata.update({ 'response': 'ok', 'message': 'connected'}) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') jdata['phone'] = request.GET['phone'] if self.is_number_in_blacklist(jdata['phone'], widget.blacklist_phones.split(',')): jdata.update({'response': 'refused', 'message': '%s were found in the black list' % jdata['phone'], }) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') #--- INITIATE CALLBACK callback_result = JSONPEntryPoint.initiate_callback(jdata['phone'], widget, '', '', jdata['ip']) if callback_result[0] == 'exception': jdata.update({'response': 'error', 'message': callback_result[1], }) # temporary save data to the local file filename = '/home/callfeed/incomings/%s_%s.txt' % ( jdata['ip'].replace('.', '_'), jdata['callback']) open(filename, 'wb').write(pprint.pformat(jdata)) return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascript') jdata['mtt_response'] = callback_result[0] jdata['callback_id'] = callback_result[0]['callback_id'] jdata.update({'response': 'ok', 'message': callback_result[1], }) mtt_response = jdata.get('mtt_response', {}) mtt_response_result = mtt_response.get('result', None) # temporary save data to the local file filename = '/home/callfeed/incomings/%s_%s.txt' % ( jdata['ip'].replace('.', '_'), jdata['callback']) open(filename, 'wb').write(pprint.pformat(jdata)) print ('MTT CALL!!!', jdata['token'], jdata['hostname'], jdata['phone'], client_ip_addr, jdata['callback_id'], mtt_response_result) except Exception as e: import traceback traceback.print_exc() return HttpResponse('%s(%s);' % ( request.GET['callback'], json.dumps(jdata, ensure_ascii=False)), 'text/javascrit') # new_pending_info.mtt_callback_call_id = mtt_response_result_callback_id # new_pending_info.save() # if new_pending_info.mtt_callback_call_id != mtt_response_result_callback_id: # print (' WARNING: %s != %s' % (mtt_response_result_callback_id, new_pending_info.mtt_callback_call_id)) # return ('error', '%s != %s' % (mtt_response_result_callback_id, new_pending_info.mtt_callback_call_id)) # mtt_response_check = mttproxy.getCallBackFollowmeCallInfo(mtt.CUSTOMER_NAME, mtt_response_result_callback_id) # mtt_response_check_result = mtt_response_check.get('result', None) # # if mtt_response_check_result is None: # print (' ERROR: getCallBackFollowmeCallInfo returned None') # return ('error', 'getCallBackFollowmeCallInfo returned None',) # # call_info_struct = mtt_response_check_result.get('callBackFollowmeCallInfoStruct', None) # # if call_info_struct is None: # print (' ERROR: callBackFollowmeCallInfoStruct is None') # return ('error', 'callBackFollowmeCallInfoStruct is None',) # # record_url_a = call_info_struct.get('call_back_record_URL_A', '') # record_url_a = call_info_struct.get('downloadURL', '') # record_url_b = call_info_struct.get('call_back_record_URL_B', '') # record_url_b = call_info_struct.get('downloadURL', '') # # new_pending_info.call_description = call_info_struct.get('callDescription', '') # new_pending_info.phone_number_side_a = call_info_struct.get('destination_A', '') # new_pending_info.phone_number_side_b = call_info_struct.get('destination_B', '') # new_pending_info.charged_length_a_sec=int(call_info_struct.get('call_back_charged_length_A', '0')) # new_pending_info.charged_length_b_sec=int(call_info_struct.get('call_back_charged_length_B', '0')) # new_pending_info.real_length_a_sec=int(call_info_struct.get('call_back_real_length_A', '0')) # new_pending_info.real_length_b_sec=int(call_info_struct.get('call_back_real_length_B', '0')) # new_pending_info.record_url_a = record_url_a # new_pending_info.record_url_b = record_url_b # new_pending_info.waiting_period_a_sec = call_info_struct.get('waiting_period_A', '0') # new_pending_info.waiting_period_b_sec = call_info_struct.get('waiting_period_B', '0') # new_pending_info.callback_status = CallbackInfo.CALLBACK_STATUS_SUCCEED # new_pending_info.cost = call_info_struct.get('call_back_cost', 0.0) # new_pending_info.currency = call_info_struct.get('call_back_currency', 'RUB') # # new_pending_info.ip_side_b = callback.ip_side_b # # new_pending_info.geodata_side_b='-' # # mtt_callback_call_id=callback.mtt_callback_call_id, # # new_pending_info.referer = callback.referer, search_request=callback.search_request, # # new_pending_info.when = callback.when, # # new_pending_info.tracking_history=callback.tracking_history # new_pending_info.save() # # try: # charged_a = int(call_info_struct.get('call_back_charged_length_A', '0')) # charged_b = int(call_info_struct.get('call_back_charged_length_B', '0')) # widget.client.balance_minutes -= int((float(charged_a) + float(charged_b)) / 60.0) # widget.client.save() # print (' BALANCE:', widget.client.name, widget.client.email, widget.client.balance_minutes) # except: # traceback.print_exc() # if mtt_response_result_callback_id is not None: # new_pending_callback = PendingCallback(widget=widget, # mtt_callback_call_id=mtt_response_result_callback_id, # ip_side_b=ip_address, # geodata_side_b=ip_to_location(ip_address), # referer=rferrer_str, # search_request=search_str, # when=datetime.datetime.now(), # tracking_history='') # new_pending_callback.save()