Example #1
0
 def test_util_replace_keywords(self):
     """Test the replace keywords utility function that enables mail merge in our messages."""
     for key in self.subscriber:
         message = "<<" + key + ">>"
         value = str(self.subscriber[key])
         if( key == 'topics' ):
             value = "Test1, Test2 and Test3"
         self.assertEquals( value, util.replace_keywords(message, self.subscriber) )
Example #2
0
    def put(self):
        """
        Publish a message to a given topic set. All subscribers with subscriptions to any of those
        topics are to receive the message. First parse the given arguments to check it is a valid email.

        Arguments are passed in the request data.

        Args:
            id (str): Required. If another message with the same ID has been logged, this one won't send.
                      Returns a 400 Bad Request error if this is the case.\n
            message (str): Required. The message.\n
            topics ([str]): Required. The topics the message fits into (determines destination address/es).
                            Accepts array of multiple topics.\n
            medium ([str]): The medium by which to publish the message ('email', 'sms', etc...)
                            Defaults to email. Accepts array of multiple mediums.\n
            sms-message (str): The sms version of the message. Defaults to the same as 'message'\n
            html-message (str): The html version of the message. Defaults to the same as 'message'\n
            subject (str): The e-mail subject. Defaults to "".\n
            from (str): The address from which to send the message. \n
                        Deafults to an emro address stored in the config.
    
        Returns:
            An array of amazon SES and nexmo responses for each message sent.
        """
        #Define an argument parser for creating a valid email message.
        parser = reqparse.RequestParser()
        parser.add_argument('id', required=True, type=str, help='The message Id - must be unique.')
        parser.add_argument('message', required=True, type=str, help='The message to be sent')
        parser.add_argument('topics', required=True, action='append', type=str, 
                            help='The topics to publish to.')
        parser.add_argument('medium', required=False, action='append', type=str, 
                            help='The mediums by which to send the message.')
        parser.add_argument('html-message', required=False, type=str, 
                            help='If applicable, the message in html')
        parser.add_argument('sms-message', required=False, type=str, 
                            help='If applicable, the seperate sms message')
        parser.add_argument('subject', required=False, type=str, help='The email subject')
        parser.add_argument('from', required=False, type=str, 
                            help='The address from which to send the message')
        args = parser.parse_args()

        #Check that the message hasn't already been sent.
        if util.id_valid( args['id'] ):

            #Set the default values for the non-required fields.
            if not args['medium']: 
                args['medium'] = ['email']
            if not args['html-message']:
                args['html-message'] = args['message']
            if not args['sms-message']:
                args['sms-message'] = args['message']
            if not args['from']: 
                args['from'] = current_app.config['SENDER']

            #Collect the subscriber IDs for all subscriptions to the given topics.
            subscribers = []

            for topic in args['topics']:
                query_response = self.subscriptions.query(
                    IndexName='topicID-index',
                    KeyConditionExpression=Key('topicID').eq(topic)
                )
                for item in query_response['Items']:
                    
                    subscribers.append( item['subscriberID'] )
            
            #Record details about the sent messages.
            responses = []
            destinations = []
            s = []

            #Send the messages to each subscriber.     
            for subscriber_id in subscribers:      
                #Get subscriber's details.        
                subscriber = self.subscribers.get_item(
                    Key={ 'id':subscriber_id }
                )

                #Occasionally subscriptions get left in the database without a subscriber.
                #This can happen when someone mannually edits the database.
                #If so, no subscriber will be returned above, so we delete subscriber properly.
                if( subscriber['ResponseMetadata']['HTTPStatusCode'] == 200 
                    and 'Item' not in subscriber ):  

                    util.delete_subscriber( subscriber_id )
                    message ={
                        "message":"500 Internal Server Error: subscriber id " + subscriber_id + 
                                  " doesn't exist. The subscriber has been deleted properly."
                    }
                    current_app.logger.warning( message["message"] );
                    responses.append( message )

                else:

                    subscriber = subscriber['Item']   

                    #Create some variables to hold the mailmerged messages.
                    message = args['message']
                    sms_message = args['sms-message']
                    html_message = args['html-message']

                    #Enable mail merging on subscriber attributes.
                    message = util.replace_keywords( message, subscriber )
                    if args['sms-message']: 
                        sms_message = util.replace_keywords( sms_message, subscriber )
                    if args['html-message']:
                        html_message = util.replace_keywords( html_message, subscriber )

                    #Assemble and send the messages for each medium.
                    for medium in args['medium']: 
                        
                        if medium == 'email':
                            temp = util.send_email(
                                [subscriber['email']],
                                args['subject'],
                                message,
                                html_message,
                                sender=args['from']
                            )
                            temp['type'] = 'email'
                            temp['message']=message
                            responses.append(temp)
                            destinations.append( subscriber['email'] )  

                        elif medium == 'sms' and 'sms' in subscriber:
                            temp = util.send_sms(
                                subscriber['sms'],
                                sms_message
                            )
                            temp['type'] = 'sms'
                            temp['message'] = sms_message
                            responses.append( temp )  
                            destinations.append( subscriber['sms'] )                             

            util.log_message( args['id'], {
                'destination': destinations, 
                'medium': args['medium'], 
                'time': util.get_date(),
                'message': args['message'],
                'topics': 'Published to: ' + str(args['topics'])
            })

            return Response( json.dumps( responses ), 
                             status=200,
                             mimetype='application/json' )
          

        else:
            #If the message Id already exists, return with a 400 bad request response.
            message = {"message":"400 Bad Request: id " + args['id'] + " already exists"}
            return Response( json.dumps( message ), 
                             status=400,
                             mimetype='application/json' )