def put(self): """ Send an email with Amazon SES. First parse the given arguments to check it is a valid email. !!!Remember that whilst still in AWS "Sandbox" we can only send to verified emails. Arguments are passed in the request data. Args: subject (str): Required. The e-mail subject.\n message (str): Required. The e-mail message.\n email (str): The destination address/es for the e-mail.\n subscriber_id (str): The destination subscriber/s for the e-mail.\n html (str): The html version of the message, will default to the same as 'message'.\n from (str): The sender's address. Defaults to the config value SENDER. Returns: The amazon SES response. """ #Define an argument parser for creating a valid email message. parser = reqparse.RequestParser() parser.add_argument('subject', required=True, type=str, help='The email subject') parser.add_argument('message', required=True, type=str, help='The message to be sent') parser.add_argument('email', required=False, action='append', type=str, help='The destination address') parser.add_argument('subscriber_id', required=False, action='append', type=str, help='The destination subscriber id') parser.add_argument('html', required=False, type=str, help='If applicable, the message in html') parser.add_argument('from', required=False, type=str, help='The address from which to send the message') args = parser.parse_args() #If no email is given, look at the subscriber ids and find their emails. if args['email'] is None: #If the caller has made a mistake and not provided any destination, throw an error. if args['subscriber_id'] is None: return Response( "{'message':'404 Bad Request: No destination specified.'}", status=404, mimetype='application/json' ) else: args['email'] = [] for subscriber_id in args['subscriber_id']: response = self.subscribers.get_item( Key={ 'id':subscriber_id } ) args['email'].append( response['Item']['email'] ) #Set the from field to the config SENDER value if no from field is supplied. if not args['from']: args['from'] = current_app.config['SENDER'] response = util.send_email( args['email'], args['subject'], args['message'], args['html'], sender=args['from'] ) message_id = 'G'+uuid.uuid4().hex util.log_message( message_id, { 'destination': args['email'], 'medium': ['email'], 'time': util.get_date(), 'message': args['message'] }) response['log_id'] = message_id return Response( json.dumps( response ), status=response['ResponseMetadata']['HTTPStatusCode'], mimetype='application/json' )
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' )