def testSendEmailInvalidRegion(self): with self.assertRaises(ValueError) as cm: ses_utils.sendEmail(subject="subject", body="body", toAddresses=("*****@*****.**", ), region="region", sender="*****@*****.**") self.assertIn( "Region 'region' provided does not exist in known SES region " "endpoints set.", cm.exception.message)
def sendWelcomeEmail(toAddress): subject = config.get("registration", "subject") body = open(resource_filename(htm.it.__name__, os.path.join("../conf", config.get("registration", "body")))).read() body = body.replace("\n", "\r\n") # Ensure windows newlines serverUrl = web.ctx.env['HTTP_HOST'] templated = dict(apiKey=config.get("security", "apikey"), serverUrl=serverUrl) try: ses_utils.sendEmail(subject=subject.format(**templated), body=body.format(**templated), toAddresses=[toAddress]) except BotoServerError: raise web.badrequest("Invalid email address.")
def testSendEmailAwsCredentialsNoMessageID(self, sesConnectionMock): subject = "subject" body = "body" toAddresses = ("*****@*****.**", ) region = "us-west-2" sender = "*****@*****.**" connMock = Mock(spec_set=SESConnection) sesConnectionMock.return_value = connMock connMock.send_email.return_value = {} messageID = ses_utils.sendEmail(subject=subject, body=body, toAddresses=toAddresses, region=region, sender=sender) self.assertIsNone(messageID) connMock.send_email.assert_called_once_with(source=sender, subject=subject, body=body, to_addresses=toAddresses) args = sesConnectionMock.call_args[1] self.assertEqual(args["aws_access_key_id"], "a") self.assertEqual(args["aws_secret_access_key"], "b")
def testSendEmailDefaultSenderWithMessageID(self, sesConnectionMock): subject = "subject" body = "body" toAddresses = ("*****@*****.**", ) region = "us-west-2" sender = "*****@*****.**" connMock = Mock(spec_set=SESConnection) sesConnectionMock.return_value = connMock connMock.send_email.return_value = { "SendEmailResponse": { "SendEmailResult": { "MessageId": "messageID" } } } messageID = ses_utils.sendEmail(subject=subject, body=body, toAddresses=toAddresses, region=region, sender=sender) self.assertEqual(messageID, "messageID") connMock.send_email.assert_called_once_with(source=sender, subject=subject, body=body, to_addresses=toAddresses)
def sendWelcomeEmail(toAddress): subject = config.get("registration", "subject") body = open( resource_filename( htm.it.__name__, os.path.join("../conf", config.get("registration", "body")))).read() body = body.replace("\n", "\r\n") # Ensure windows newlines serverUrl = web.ctx.env['HTTP_HOST'] templated = dict(apiKey=config.get("security", "apikey"), serverUrl=serverUrl) try: ses_utils.sendEmail(subject=subject.format(**templated), body=body.format(**templated), toAddresses=[toAddress]) except BotoServerError: raise web.badrequest("Invalid email address.")
def testSendEmailNoRegionOrSender(self, sesConnectionMock): subject = "subject" body = "body" toAddresses = ("*****@*****.**", ) connMock = Mock(spec_set=SESConnection) sesConnectionMock.return_value = connMock connMock.send_email.return_value = {} messageID = ses_utils.sendEmail(subject=subject, body=body, toAddresses=toAddresses) self.assertIsNone(messageID) connMock.send_email.assert_called_once_with(source="*****@*****.**", subject=subject, body=body, to_addresses=toAddresses) args = sesConnectionMock.call_args[1] self.assertEqual(args["aws_access_key_id"], "mockKeyId") self.assertEqual(args["aws_secret_access_key"], "mockKey")
def sendNotificationEmail(self, engine, settingObj, notificationObj): """ Send notification email through Amazon SES :param engine: SQLAlchemy engine object :type engine: sqlalchemy.engine.Engine :param settingObj: Device settings :type settingObj: NotificationSettings :param notificationObj: Notification :type notificationObj: Notification See conf/notification-body.tpl (or relevant notification body configuration value) for template value. Values are substituted using python's `str.format(**data)` function where `data` is a dict containing the following keys: ============ =========== Key Description ============ =========== notification Notification instance data MetricData row that triggered notification date Formatted date (%A, %B %d, %Y) time Formatted time (%I:%M %p (%Z)) unit Canonical unit for metric value ============ =========== """ subject = htm.it.app.config.get("notifications", "subject") bodyType = "default" with engine.connect() as conn: metricObj = repository.getMetric(conn, notificationObj.metric) if metricObj.datasource == "custom": bodyType = "custom" body = open( resource_filename( htm.it.__name__, os.path.join( "../../conf", htm.it.app.config.get("notifications", "body_" + bodyType)))).read() body = body.replace("\n", "\r\n") # Ensure windows newlines # Template variable storage (to be expanded in call to str.format()) templated = dict(notification=notificationObj) # Metric templated["metric"] = metricObj # Instance templated["instance"] = metricObj.tag_name or metricObj.server # Date/time templated["timestampUTC"] = notificationObj.timestamp.strftime( "%A, %B %d, %Y %I:%M %p") localtime = localizedTimestamp(notificationObj.timestamp) templated["timestampLocal"] = localtime.strftime( "%A, %B %d, %Y %I:%M %p") templated["timezoneLocal"] = localtime.strftime("%Z") # Region templated["region"] = _getCurrentRegion() self._log.info( "NOTIFICATION=%s SERVER=%s METRICID=%s METRIC=%s DEVICE=%s " "RECIPIENT=%s Sending email. " % (notificationObj.uid, metricObj.server, metricObj.uid, metricObj.name, settingObj.uid, settingObj.email_addr)) try: # Send through SES messageId = ses_utils.sendEmail( subject=subject.format(**templated), body=body.format(**templated), toAddresses=settingObj.email_addr) if messageId is not None: # Record AWS SES Message ID with engine.connect() as conn: repository.updateNotificationMessageId( conn, notificationObj.uid, messageId) self._log.info( "NOTIFICATION=%s SESMESSAGEID=%s Email sent. " % (notificationObj.uid, messageId)) except BotoServerError: self._log.exception("Unable to send email.")
def sendNotificationEmail(self, engine, settingObj, notificationObj): """ Send notification email through Amazon SES :param engine: SQLAlchemy engine object :type engine: sqlalchemy.engine.Engine :param settingObj: Device settings :type settingObj: NotificationSettings :param notificationObj: Notification :type notificationObj: Notification See conf/notification-body.tpl (or relevant notification body configuration value) for template value. Values are substituted using python's `str.format(**data)` function where `data` is a dict containing the following keys: ============ =========== Key Description ============ =========== notification Notification instance data MetricData row that triggered notification date Formatted date (%A, %B %d, %Y) time Formatted time (%I:%M %p (%Z)) unit Canonical unit for metric value ============ =========== """ subject = htm.it.app.config.get("notifications", "subject") bodyType = "default" with engine.connect() as conn: metricObj = repository.getMetric(conn, notificationObj.metric) if metricObj.datasource == "custom": bodyType = "custom" body = open(resource_filename(htm.it.__name__, os.path.join("../../conf", htm.it.app.config.get("notifications", "body_" + bodyType)))).read() body = body.replace("\n", "\r\n") # Ensure windows newlines # Template variable storage (to be expanded in call to str.format()) templated = dict(notification=notificationObj) # Metric templated["metric"] = metricObj # Instance templated["instance"] = metricObj.tag_name or metricObj.server # Date/time templated["timestampUTC"] = notificationObj.timestamp.strftime( "%A, %B %d, %Y %I:%M %p") localtime = localizedTimestamp(notificationObj.timestamp) templated["timestampLocal"] = localtime.strftime( "%A, %B %d, %Y %I:%M %p") templated["timezoneLocal"] = localtime.strftime("%Z") # Region templated["region"] = _getCurrentRegion() self._log.info("NOTIFICATION=%s SERVER=%s METRICID=%s METRIC=%s DEVICE=%s " "RECIPIENT=%s Sending email. " % (notificationObj.uid, metricObj.server, metricObj.uid, metricObj.name, settingObj.uid, settingObj.email_addr)) try: # Send through SES messageId = ses_utils.sendEmail(subject=subject.format(**templated), body=body.format(**templated), toAddresses=settingObj.email_addr) if messageId is not None: # Record AWS SES Message ID with engine.connect() as conn: repository.updateNotificationMessageId(conn, notificationObj.uid, messageId) self._log.info("NOTIFICATION=%s SESMESSAGEID=%s Email sent. " % ( notificationObj.uid, messageId)) except BotoServerError: self._log.exception("Unable to send email.")