def test_send(self): m = Mail() m.add_to('John, Doe <*****@*****.**>') m.set_subject('test') m.set_html('WIN') m.set_text('WIN') m.set_from('*****@*****.**') m.add_substitution('subKey', 'subValue') m.add_section('testSection', 'sectionValue') m.add_category('testCategory') m.add_unique_arg('testUnique', 'uniqueValue') m.add_filter('testFilter', 'filter', 'filterValue') m.add_attachment_stream('testFile', 'fileValue') self.sg.send(m) url = self.sg._build_body(m) url.pop('api_key', None) url.pop('api_user', None) url.pop('date', None) testUrl = json.loads('''{"to[]": ["*****@*****.**"], "toname[]": ["John Doe"], "html": "WIN", "text": "WIN", "subject": "test", "files[testFile]": "fileValue", "from": "*****@*****.**", "headers": "", "fromname": "", "replyto": ""}''') testUrl['x-smtpapi'] = json.dumps(json.loads('''{"sub":{"subKey":["subValue"]}, "section":{"testSection":"sectionValue"}, "category":["testCategory"], "unique_args":{"testUnique":"uniqueValue"}, "filters":{"testFilter":{"settings":{"filter":"filterValue"}}}}''')) self.assertEqual(url, testUrl)
def test_send(self): m = Mail() m.add_to('John, Doe <*****@*****.**>') m.set_subject('test') m.set_html('WIN') m.set_text('WIN') m.set_from('*****@*****.**') m.set_asm_group_id(42) m.add_cc('*****@*****.**') m.add_bcc('*****@*****.**') m.add_substitution('subKey', 'subValue') m.add_section('testSection', 'sectionValue') m.add_category('testCategory') m.add_unique_arg('testUnique', 'uniqueValue') m.add_filter('testFilter', 'filter', 'filterValue') m.add_attachment_stream('testFile', 'fileValue') url = self.sg._build_body(m) url.pop('api_key', None) url.pop('api_user', None) url.pop('date', None) test_url = json.loads(''' { "to[]": ["*****@*****.**"], "toname[]": ["John Doe"], "html": "WIN", "text": "WIN", "subject": "test", "files[testFile]": "fileValue", "from": "*****@*****.**", "cc[]": ["*****@*****.**"], "bcc[]": ["*****@*****.**"] } ''') test_url['x-smtpapi'] = json.dumps(json.loads(''' { "sub": { "subKey": ["subValue"] }, "section": { "testSection":"sectionValue" }, "category": ["testCategory"], "unique_args": { "testUnique":"uniqueValue" }, "filters": { "testFilter": { "settings": { "filter": "filterValue" } } }, "asm_group_id": 42 } ''')) try: self.assertItemsEqual(url, test_url) except: # Python 3+ self.assertCountEqual(url, test_url)
def test_send(self): m = Mail() m.add_to('John, Doe <*****@*****.**>') m.set_subject('test') m.set_html('WIN') m.set_text('WIN') m.set_from('*****@*****.**') m.set_asm_group_id(42) m.add_cc('*****@*****.**') m.add_bcc('*****@*****.**') m.add_substitution('subKey', 'subValue') m.add_section('testSection', 'sectionValue') m.add_category('testCategory') m.add_unique_arg('testUnique', 'uniqueValue') m.add_filter('testFilter', 'filter', 'filterValue') m.add_attachment_stream('testFile', 'fileValue') url = self.sg._build_body(m) url.pop('api_key', None) url.pop('api_user', None) url.pop('date', None) test_url = json.loads(''' { "to[]": ["*****@*****.**"], "toname[]": ["John Doe"], "html": "WIN", "text": "WIN", "subject": "test", "files[testFile]": "fileValue", "from": "*****@*****.**", "cc[]": ["*****@*****.**"], "bcc[]": ["*****@*****.**"] } ''') test_url['x-smtpapi'] = json.dumps( json.loads(''' { "sub": { "subKey": ["subValue"] }, "section": { "testSection":"sectionValue" }, "category": ["testCategory"], "unique_args": { "testUnique":"uniqueValue" }, "filters": { "testFilter": { "settings": { "filter": "filterValue" } } }, "asm_group_id": 42 } ''')) self.assertEqual(url, test_url)
def send_email_verification(user_id, resend=False): if not Configuration.PUSH_ENABLED: return sendgrid = create_sendgrid() user = User.find(user_id) verify_code = wigo_db.get_new_code({ 'type': 'verify_email', 'user_id': user_id, 'email': user.email }) verify_link = '{}://{}/c/{}'.format( 'https' if Configuration.ENVIRONMENT != 'dev' else 'http', Configuration.WEB_HOST, verify_code) logger.info('generated verify code for user "%s", "%s"' % (user.email, verify_code)) first_name = user.first_name if not first_name: first_name = user.email msg = Mail() if resend: msg.set_subject('Everyone deserves a second chance') else: msg.set_subject('Welcome to Wigo') msg.set_from('Wigo <*****@*****.**>') if user.first_name and user.last_name: msg.add_to('%s <%s>' % (user.full_name, user.email)) else: msg.add_to(user.email) msg.set_text( "Hi %s\n\nPlease click the following link to verify your email address:\n\n%s\n\n" % (first_name, verify_link)) msg.set_html( render_template('confirmation_email.html', name=first_name, confirmation_link=verify_link, resend=resend)) msg.add_unique_arg('user_id', user.id) msg.add_category('verify') msg.add_filter('opentrack', 'enable', 0) msg.add_filter('subscriptiontrack', 'enable', 1) msg.add_filter('subscriptiontrack', 'replace', '-UNSUB-') sendgrid.send(msg) logger.info('sent verification email to "%s"' % user.email)
def test_send(self): m = Mail() m.add_to("John, Doe <*****@*****.**>") m.set_subject("test") m.set_html("WIN") m.set_text("WIN") m.set_from("*****@*****.**") m.add_substitution("subKey", "subValue") m.add_section("testSection", "sectionValue") m.add_category("testCategory") m.add_unique_arg("testUnique", "uniqueValue") m.add_filter("testFilter", "filter", "filterValue") m.add_attachment_stream("testFile", "fileValue") url = self.sg._build_body(m) url.pop("api_key", None) url.pop("api_user", None) url.pop("date", None) test_url = json.loads( """ { "to[]": ["*****@*****.**"], "toname[]": ["John Doe"], "html": "WIN", "text": "WIN", "subject": "test", "files[testFile]": "fileValue", "from": "*****@*****.**" } """ ) test_url["x-smtpapi"] = json.dumps( json.loads( """ { "to" : ["John, Doe <*****@*****.**>"], "sub": { "subKey": ["subValue"] }, "section": { "testSection":"sectionValue" }, "category": ["testCategory"], "unique_args": { "testUnique":"uniqueValue" }, "filters": { "testFilter": { "settings": { "filter": "filterValue" } } } } """ ) ) self.assertEqual(url, test_url)
def send_custom_email(user, subject, category, html, text, template_params=None): sendgrid = create_sendgrid() msg = Mail() msg.set_from('Wigo <*****@*****.**>') if user.first_name and user.last_name: msg.add_to('%s <%s>' % (user.full_name, user.email)) else: msg.add_to(user.email) # subject and body are required, for some reason, with the sendgrid templates msg.set_subject(Template(subject).render(user=user)) # turn on email opens tracking msg.add_filter('opentrack', 'enable', 1) msg.add_filter('subscriptiontrack', 'enable', 1) msg.add_filter('subscriptiontrack', 'replace', '-UNSUB-') params = {'user': user} if template_params: params.update(template_params) html = render_template('custom_email_inlined.html', html=Template(html).render(**params)) msg.set_html(html) if text: text = Template(text + '\n\n\nClick here to unsubscribe: -UNSUB-\n').render( **params) msg.set_text(text) msg.add_unique_arg('user_id', user.id) if category: msg.add_category(category) sendgrid.send(msg)
def run(self, schedule, content, recipient_queues, sharding_count_name): futures = [] for recipient in json.loads(recipient_queues.data): message = Mail() message.set_subject(schedule.subject) message.set_html( replace_edm_csv_property(content, recipient, schedule.replace_edm_csv_property)) message.set_from('%s <%s>' % (schedule.sender_name, schedule.sender_email)) if schedule.reply_to: message.set_replyto(schedule.reply_to) message.add_to(recipient.get('email')) message.add_category(schedule.category) status, msg = self._send(message, schedule.is_dry_run, schedule.dry_run_fail_rate) futures.append(dict(recipient=recipient, status=status, msg=msg)) send_success = filter(lambda f: f.get('status') == 200, futures) send_fail = filter(lambda f: f.get('status') != 200, futures) # save success send log if send_success: self.to_put.extend( self.success_log(schedule, send_success, self.sender)) # save fail send log if send_fail: self.to_put.extend( self.fail_log(schedule, send_fail, self.sender, content)) recipient_queues.status = 'executed' self.to_put.append(recipient_queues) if self.to_put: ndb.put_multi(self.to_put) self.to_put = [] general_counter.increment(sharding_count_name)
def resend(self, retries): futures = [] for fail_log in ndb.get_multi([retry.failEmail for retry in retries]): if not fail_log: continue sendgrid = settings.SENDGRID[fail_log.sendgrid_account] self.set_sendgrid_client(sendgrid['USERNAME'], sendgrid['PASSWORD']) log_mail = LogEmail.query(LogEmail.fails_link.IN([fail_log.key ])).get() if log_mail: logging.info('fail mail %s-%s has been retry success.' % (fail_log.subject, fail_log.to)) else: message = Mail() message.set_subject(fail_log.subject) message.set_html(fail_log.body) message.set_from('%s <%s>' % (fail_log.sender_name, fail_log.sender_email)) if fail_log.reply_to: message.set_replyto(fail_log.reply_to) message.add_to(fail_log.to) message.add_category(fail_log.category) status, msg = self._send(message, fail_log.is_dry_run, fail_log.dry_run_fail_rate) futures.append(dict(fail_log=fail_log, status=status, msg=msg)) # split log to another task to save send_success = filter(lambda f: f.get('status') == 200, futures) send_fail = filter(lambda f: f.get('status') != 200, futures) if send_success: def clear_body(send): send.get('fail_log').body = None return send self.to_put.extend( self.success_log_retry(map(clear_body, send_success))) # retry fail log has been send succes and need to remove keys = [ r.key for r in filter( lambda r: any(s == r.failEmail for s in map( lambda s: s.get('fail_log').key, send_success)), retries) ] if keys: self.to_delete.extend(keys) if send_fail: self.to_put.extend(self.fail_log_retry(send_fail)) if self.to_put: ndb.put_multi(self.to_put) self.to_put = [] if self.to_delete: ndb.delete_multi(self.to_delete) self.to_delete = []