Esempio n. 1
0
 def assert_get_sailthru_client_raises(self, exc_class, config):
     """ Asserts an error is raised by a call to get_sailthru_client. """
     overrides = {
         self.SITE_CODE: {
             'SAILTHRU': config
         }
     }
     with mock.patch.dict(self.SITE_OVERRIDES_MODULE, overrides):
         with self.assertRaises(exc_class):
             get_sailthru_client(self.SITE_CODE)
Esempio n. 2
0
 def _get_client(self):
     """
     Return the sailthru client or None if exception raised.
     """
     sailthru_client = None
     try:
         sailthru_client = get_sailthru_client(self.site_code)
     except SailthruError:
         log.exception(
             '[{logger_prefix}] A client error occurred while attempting to send a notification.'
             ' Message: {message}'.format(
                 logger_prefix=self.logger_prefix,
                 message=self.email_vars.get('email_body')
             )
         )
     return sailthru_client
Esempio n. 3
0
 def test_get_sailthru_client(self):
     """ Verify the method returns an authenticated SailthruClient. """
     key = 'key'
     secret = 'secret'
     overrides = {
         self.SITE_CODE: {
             'SAILTHRU': {
                 'SAILTHRU_ENABLE': True,
                 'SAILTHRU_KEY': key,
                 'SAILTHRU_SECRET': secret
             }
         }
     }
     with mock.patch.dict(self.SITE_OVERRIDES_MODULE, overrides):
         client = get_sailthru_client(self.SITE_CODE)
         self.assertEqual(client.api_key, key)
         self.assertEqual(client.secret, secret)
Esempio n. 4
0
def _send_offer_assignment_notification_email(config, user_email, subject,
                                              email_body, site_code, task):
    """Handles sending offer assignment notification emails and retrying failed emails when appropriate."""
    try:
        sailthru_client = get_sailthru_client(site_code)
    except SailthruError:
        logger.exception(
            '[Offer Assignment] A client error occurred while attempting to send a offer assignment notification.'
            ' Message: {message}'.format(message=email_body))
        return None
    email_vars = {
        'subject': subject,
        'email_body': email_body,
    }
    try:
        response = sailthru_client.send(
            template=config['templates']['assignment_email'],
            email=user_email,
            _vars=email_vars)
    except SailthruClientError:
        logger.exception(
            '[Offer Assignment] A client error occurred while attempting to send a offer assignment notification.'
            ' Message: {message}'.format(message=email_body))
        return None

    if not response.is_ok():
        error = response.get_error()
        logger.error(
            '[Offer Assignment] A {token_error_code} - {token_error_message} error occurred'
            ' while attempting to send a offer assignment notification.'
            ' Message: {message}'.format(
                message=email_body,
                token_error_code=error.get_error_code(),
                token_error_message=error.get_message()))
        if can_retry_sailthru_request(error):
            logger.info(
                '[Offer Assignment] An attempt will be made to resend the offer assignment notification.'
                ' Message: {message}'.format(message=email_body))
            schedule_retry(task, config)
        else:
            logger.warning(
                '[Offer Assignment] No further attempts will be made to send the offer assignment notification.'
                ' Failed Message: {message}'.format(message=email_body))

    return response
Esempio n. 5
0
def send_course_refund_email(self,
                             email,
                             refund_id,
                             amount,
                             course_name,
                             order_number,
                             order_url,
                             site_code=None):
    """ Sends the course refund email.

    Args:
        self: Ignore.
        email (str): Recipient's email address.
        refund_id (int): ID of the refund that initiated this task.
        amount (str): Formatted amount of the refund.
        course_name (str): Name of the course for which payment was refunded.
        order_number (str): Order number of the order that was refunded.
        order_url (str): Receipt URL of the refunded order.
        site_code (str): Identifier of the site sending the email.
    """
    config = get_sailthru_configuration(site_code)

    try:
        sailthru_client = get_sailthru_client(site_code)
    except SailthruError:
        # NOTE: We rely on the function to log the error for us
        return

    email_vars = {
        'amount': amount,
        'course_name': course_name,
        'order_number': order_number,
        'order_url': order_url,
    }

    try:
        response = sailthru_client.send(
            template=config['templates']['course_refund'],
            email=email,
            _vars=email_vars)
    except SailthruClientError:
        logger.exception(
            'A client error occurred while attempting to send a course refund notification for refund [%d].',
            refund_id)
        return

    if response.is_ok():
        logger.info('Course refund notification sent for refund %d.',
                    refund_id)
    else:
        error = response.get_error()
        logger.error(
            'An error occurred while attempting to send a course refund notification for refund [%d]: %d - %s',
            refund_id, error.get_error_code(), error.get_message())

        if can_retry_sailthru_request(error):
            logger.info(
                'An attempt will be made again to send a course refund notification for refund [%d].',
                refund_id)
            schedule_retry(self, config)
        else:
            logger.warning(
                'No further attempts will be made to send a course refund notification for refund [%d].',
                refund_id)
Esempio n. 6
0
def update_course_enrollment(self,
                             email,
                             course_url,
                             purchase_incomplete,
                             mode,
                             unit_cost=None,
                             course_id=None,
                             currency=None,
                             message_id=None,
                             site_code=None,
                             sku=None):
    """Adds/updates Sailthru when a user adds to cart/purchases/upgrades a course

     Args:
        email(str): The user's email address
        course_url(str): Course home page url
        purchase_incomplete(boolean): True if adding to cart
        mode(string): enroll mode (audit, verification, ...)
        unit_cost(decimal): cost if purchase event
        course_id(CourseKey): course id
        currency(str): currency if purchase event - currently ignored since Sailthru only supports USD
        message_id(str): value from Sailthru marketing campaign cookie
        site_code(str): site code

    Returns:
        None
    """
    # Get configuration
    config = get_sailthru_configuration(site_code)

    try:
        sailthru_client = get_sailthru_client(site_code)
    except SailthruError:
        # NOTE: We rely on the function to log the error for us
        return

    # Use event type to figure out processing required
    new_enroll = False
    send_template = None

    if not purchase_incomplete:
        if mode == 'verified':
            # upgrade complete
            send_template = config.get('SAILTHRU_UPGRADE_TEMPLATE')
        elif mode == 'audit' or mode == 'honor':
            # free enroll
            new_enroll = True
            send_template = config.get('SAILTHRU_ENROLL_TEMPLATE')
        else:
            # paid course purchase complete
            new_enroll = True
            send_template = config.get('SAILTHRU_PURCHASE_TEMPLATE')

    # calc price in pennies for Sailthru
    #  https://getstarted.sailthru.com/new-for-developers-overview/advanced-features/purchase/
    cost_in_cents = int(unit_cost * 100)

    # update the "unenrolled" course array in the user record on Sailthru if new enroll or unenroll
    if new_enroll:
        if not _update_unenrolled_list(sailthru_client, email, course_url,
                                       False):
            schedule_retry(self, config)

    # Get course data from Sailthru content library or cache
    course_data = _get_course_content(course_id, course_url, sailthru_client,
                                      site_code, config)

    # build item description
    item = _build_purchase_item(course_id, course_url, cost_in_cents, mode,
                                course_data, sku)

    # build purchase api options list
    options = {}
    if purchase_incomplete and config.get('SAILTHRU_ABANDONED_CART_TEMPLATE'):
        options['reminder_template'] = config.get(
            'SAILTHRU_ABANDONED_CART_TEMPLATE')
        # Sailthru reminder time format is '+n time unit'
        options['reminder_time'] = "+{} minutes".format(
            config.get('SAILTHRU_ABANDONED_CART_DELAY'))

    # add appropriate send template
    if send_template:
        options['send_template'] = send_template

    if not _record_purchase(sailthru_client, email, item, purchase_incomplete,
                            message_id, options):
        schedule_retry(self, config)