def publish_message(self, message): """ Method uses Daktela API for sending dialer message :param message: dialer message """ client_url = self._get_dialer_api_url() try: payload = { 'queue': (self.config.AUTODIALER_QUEUE if message.is_autodialer else self.config.PREDICTIVE_QUEUE), 'number': re.sub(r'^\+', '00', message.recipient), 'customFields': { 'mall_pay_text': [ message.content, ], 'ttsprocessed': [ 0, ], }, } if message.is_autodialer: payload['action'] = 5 custom_fields = message.extra_data.get('custom_fields') if custom_fields: payload['customFields'].update(**custom_fields) response = generate_session(slug=self.SESSION_SLUG, related_objects=(message, ), timeout=self.config.TIMEOUT).post( client_url, json=payload, ) resp_json = response.json() message.extra_data.update({ 'name': resp_json['result']['name'], 'daktela_action': resp_json['result']['action'], 'daktela_statuses': resp_json['result']['statuses'], }) error_message = resp_json.get('error') if error_message: self._update_message_after_sending_error( message, error=', '.join(error_message) if isinstance( error_message, list) else str(error_message), state=DialerMessage.STATE.ERROR) else: self._update_message_after_sending( message, state=DialerMessage.STATE.READY, sent_at=tz.now(), extra_data=message.extra_data, ) except Exception as ex: self._update_message_after_sending_error(message, error=str(ex))
def _send_requests(self, messages, request_type, is_sending=False, **change_sms_kwargs): """ Performs the actual POST request for input messages and request type. :param messages: list of SMS messages :param request_type: type of the request :param is_sending: True if method is called after sending message :param change_sms_kwargs: extra kwargs that will be stored to the message object """ requests_xml = self._serialize_messages(messages, request_type) try: resp = generate_session(slug='pymess - ATS SMS', related_objects=list(messages)).post( self.config.URL, data=requests_xml, headers={'Content-Type': 'text/xml'}, timeout=self.config.TIMEOUT) if resp.status_code != 200: raise self.ATSSendingError( 'ATS operator returned invalid response status code: {}'. format(resp.status_code)) self._update_sms_states_from_response( messages, self._parse_response_codes(resp.text), is_sending, **change_sms_kwargs) except requests.exceptions.RequestException as ex: raise self.ATSSendingError( 'ATS operator returned returned exception: {}'.format(str(ex)))
def _create_client(self, message): mandrill_client = mandrill.Mandrill(settings.EMAIL_MANDRILL.KEY) mandrill_client.session = generate_session( slug='pymess - Mandrill', related_objects=(message,), timeout=settings.EMAIL_MANDRILL.TIMEOUT ) return mandrill_client
def publish_message(self, message): mandrill_client = mandrill.Mandrill(settings.EMAIL_MANDRILL.KEY) mandrill_client.session = generate_session( slug='pymess - Mandrill', related_objects=(message, ), timeout=settings.EMAIL_MANDRILL.TIMEOUT) try: result = mandrill_client.messages.send(message={ 'to': [{ 'email': message.recipient }], 'from_email': message.sender, 'from_name': message.sender_name, 'html': message.content, 'subject': message.subject, 'headers': settings.EMAIL_MANDRILL.HEADERS, 'track_opens': settings.EMAIL_MANDRILL.TRACK_OPENS, 'auto_text': settings.EMAIL_MANDRILL.AUTO_TEXT, 'inline_css': settings.EMAIL_MANDRILL.INLINE_CSS, 'url_strip_qs': settings.EMAIL_MANDRILL.URL_STRIP_QS, 'preserve_recipients': settings.EMAIL_MANDRILL.PRESERVE_RECIPIENTS, 'view_content_link': settings.EMAIL_MANDRILL.VIEW_CONTENT_LINK, 'async': settings.EMAIL_MANDRILL.ASYNC, 'attachments': self._serialize_attachments(message) }, )[0] mandrill_state = result['status'].upper() state = self.MANDRILL_STATES_MAPPING.get(mandrill_state) error = self.MANDRILL_STATES.get_label( mandrill_state) if state == EmailMessage.STATE.ERROR else None if mandrill_state == self.MANDRILL_STATES.REJECTED: error += ', mandrill message: "{}"'.format( result['reject_reason']) extra_sender_data = message.extra_sender_data or {} extra_sender_data['result'] = result self.update_message(message, state=state, sent_at=timezone.now(), extra_sender_data=extra_sender_data, error=error) except (mandrill.Error, JSONDecodeError, requests.exceptions.RequestException) as ex: self.update_message(message, state=EmailMessage.STATE.ERROR, error=force_text(ex))
def _update_dialer_states(self, messages): """ Method uses Daktela API to get info about autodialer call status :param messages: list of dialer messages to update """ for message in messages: name = message.extra_data['name'] client_url = self._get_dialer_api_url(name) response = generate_session( slug=self.SESSION_SLUG, related_objects=(message, ), timeout=settings.DIALER_DAKTELA.TIMEOUT).get(client_url) resp_json = response.json() message.extra_data.update({ 'name': name, 'daktela_action': resp_json['result']['action'], 'daktela_statuses': resp_json['result']['statuses'], }) resp_message_state = resp_json['result']['statuses'][0][ 'name'] if len(resp_json['result'] ['statuses']) else resp_json['result']['action'] custom_fields = resp_json['result']['customFields'] tts_processed = custom_fields['ttsprocessed'][0] whole_message_heard = ('whole_message_heard' in custom_fields and custom_fields['whole_message_heard'] and custom_fields['whole_message_heard'][0] == 'Yes') state_mapped = settings.DIALER_DAKTELA.STATES_MAPPING[ resp_message_state] if state_mapped == DialerMessage.STATE.ANSWERED_PARTIAL and whole_message_heard: resp_message_state = str(DialerMessage.STATE.ANSWERED_COMPLETE) if state_mapped == DialerMessage.STATE.DONE and tts_processed == '0': resp_message_state = str(DialerMessage.STATE.NOT_ASSIGNED) message_state = settings.DIALER_DAKTELA.STATES_MAPPING[ resp_message_state] message_error = resp_json['error'] if len( resp_json['error']) else None tts_processed = resp_json['result']['customFields'][ 'ttsprocessed'][0] try: self.update_message( message, state=message_state, error=message_error, extra_data=message.extra_data, is_final_state=resp_json['result']['action'] == '5' and tts_processed == '1', ) except Exception as ex: self.update_message(message, state=DialerMessage.STATE.ERROR, error=force_text(ex), is_final_state=True)
def publish_message(self, message): """ Method uses Daktela API for sending dialer message :param message: dialer message """ client_url = self._get_dialer_api_url() try: payload = { 'queue': settings.DIALER_DAKTELA.QUEUE, 'number': message.recipient, 'customFields': { 'mall_pay_text': [ message.content, ], 'ttsprocessed': [ 0, ], }, 'action': 5, } response = generate_session( slug=self.SESSION_SLUG, related_objects=(message, ), timeout=settings.DIALER_DAKTELA.TIMEOUT).post( client_url, json=payload, ) resp_json = response.json() message.extra_data.update({ 'name': resp_json['result']['name'], 'daktela_action': resp_json['result']['action'], 'daktela_statuses': resp_json['result']['statuses'], }) self.update_message( message, state=DialerMessage.STATE.READY, error=resp_json['error'] if len(resp_json['error']) else None, sent_at=tz.now(), extra_data=message.extra_data, ) except Exception as ex: self.update_message(message, state=DialerMessage.STATE.ERROR, error=force_text(ex), is_final_state=True)
def _update_dialer_states(self, messages): """ Method uses Daktela API to get info about autodialer call status :param messages: list of dialer messages to update """ for message in messages: name = message.extra_data['name'] client_url = self._get_dialer_api_url(name) response = generate_session( slug=self.SESSION_SLUG, related_objects=(message, ), timeout=self.config.TIMEOUT).get(client_url) resp_json = response.json() if response.status_code != 200 and resp_json.get('error'): self._update_message_state_with_error( message, error_message=resp_json.get('error')) continue message.extra_data.update({ 'name': name, 'daktela_action': resp_json['result']['action'], 'daktela_statuses': resp_json['result']['statuses'], }) resp_message_state = resp_json['result']['statuses'][0][ 'name'] if len(resp_json['result'] ['statuses']) else resp_json['result']['action'] state_mapped = self.config.STATES_MAPPING[resp_message_state] message_error = resp_json['error'] if len( resp_json['error']) else None if message.is_autodialer: is_final_state, message_state = self._get_autodialer_message_states( resp_json, state_mapped, resp_message_state) else: message_state = state_mapped is_final_state = resp_json['result']['action'] == '5' try: self._update_message( message, state=message_state, error=message_error, extra_data=message.extra_data, is_final_state=is_final_state, ) except Exception as ex: self._update_message_state_with_error(message, error_message=ex)
def publish_message(self, message): onesignal_client = OneSignalClient(self.config.APP_ID, self.config.API_KEY) onesignal_client.session = generate_session( slug='pymess - OneSignal', related_objects=(message, ), timeout=self.config.TIMEOUT) languages = {'en'} if self.config.LANGUAGE is not None: languages.add(self.config.LANGUAGE) notification = DeviceNotification( include_external_user_ids=(message.recipient, ), contents={language: message.content for language in languages}, headings={language: message.heading for language in languages}, data=message.extra_data, url=message.url, ios_badge_type=DeviceNotification.IOS_BADGE_TYPE_INCREASE, ios_badge_count=1, ) try: result = onesignal_client.send(notification) extra_sender_data = message.extra_sender_data or {} extra_sender_data['result'] = result.body if self._is_invalid_result(result): self._update_message_after_sending_error( message, state=PushNotificationMessage.STATE.ERROR, error=str(result.errors), extra_sender_data=extra_sender_data, ) else: self._update_message_after_sending( message, state=PushNotificationMessage.STATE.SENT, sent_at=timezone.now(), extra_sender_data=extra_sender_data, ) except (JSONDecodeError, requests.exceptions.RequestException, OneSignalAPIError) as ex: self._update_message_after_sending_error(message, error=str(ex))
def publish_message(self, message): onesignal_client = OneSignalClient( settings.PUSH_NOTIFICATION_ONESIGNAL.APP_ID, settings.PUSH_NOTIFICATION_ONESIGNAL.API_KEY) onesignal_client.session = generate_session( slug='pymess - OneSignal', related_objects=(message, ), timeout=settings.PUSH_NOTIFICATION_ONESIGNAL.TIMEOUT) languages = {'en'} if settings.PUSH_NOTIFICATION_ONESIGNAL.LANGUAGE is not None: languages.add(settings.PUSH_NOTIFICATION_ONESIGNAL.LANGUAGE) notification = DeviceNotification( include_external_user_ids=(message.recipient, ), contents={language: message.content for language in languages}, headings={language: message.heading for language in languages}, data=message.extra_data, url=message.url, ) try: result = onesignal_client.send(notification) extra_sender_data = message.extra_sender_data or {} extra_sender_data['result'] = result.body error_state, sent_state = PushNotificationMessage.STATE.ERROR, PushNotificationMessage.STATE.SENT self.update_message( message, state=error_state if self._is_invalid_result(result) else sent_state, error=result.errors, sent_at=timezone.now(), extra_sender_data=extra_sender_data) except (JSONDecodeError, requests.exceptions.RequestException) as ex: self.update_message(message, state=PushNotificationMessage.STATE.ERROR, error=force_text(ex))
def _create_client(self, message): mandrill_client = mandrill.Mandrill(self.config.KEY) mandrill_client.session = generate_session(slug='pymess - Mandrill', related_objects=(message, ), timeout=self.config.TIMEOUT) return mandrill_client