[IMP] mail_tracking_mailgun: validation auto check
- Configurable partner email auto check.
This commit is contained in:
parent
bf01a3358d
commit
88f0f2d292
@ -40,6 +40,10 @@ parameters:
|
|||||||
validity you must config this parameter with your account Public Validation
|
validity you must config this parameter with your account Public Validation
|
||||||
Key.
|
Key.
|
||||||
|
|
||||||
|
You can also config partner email autocheck with this system parameter:
|
||||||
|
|
||||||
|
- `mailgun.auto_check_partner_email`: Set it to True.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
@ -242,10 +242,10 @@ class MailTrackingEmail(models.Model):
|
|||||||
if "items" not in content:
|
if "items" not in content:
|
||||||
raise ValidationError(_("Event information not longer stored"))
|
raise ValidationError(_("Event information not longer stored"))
|
||||||
for item in content["items"]:
|
for item in content["items"]:
|
||||||
if not self.env['mail.tracking.event'].search(
|
|
||||||
# mailgun event hasn't been synced and recipient is the same as
|
# mailgun event hasn't been synced and recipient is the same as
|
||||||
# in the evaluated tracking. We use email_split since tracking
|
# in the evaluated tracking. We use email_split since tracking
|
||||||
# recipient could come in format: "example" <to@dest.com>
|
# recipient could come in format: "example" <to@dest.com>
|
||||||
|
if not self.env['mail.tracking.event'].search(
|
||||||
[('mailgun_id', '=', item["id"])]) and (
|
[('mailgun_id', '=', item["id"])]) and (
|
||||||
item.get("recipient", "") ==
|
item.get("recipient", "") ==
|
||||||
email_split(tracking.recipient)[0]):
|
email_split(tracking.recipient)[0]):
|
||||||
@ -254,59 +254,3 @@ class MailTrackingEmail(models.Model):
|
|||||||
metadata = self._mailgun_metadata(
|
metadata = self._mailgun_metadata(
|
||||||
mapped_event_type, item, {})
|
mapped_event_type, item, {})
|
||||||
tracking.event_create(mapped_event_type, metadata)
|
tracking.event_create(mapped_event_type, metadata)
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def check_email_list_validity(self, email_list):
|
|
||||||
"""
|
|
||||||
Checks email list validity with Mailgun's API
|
|
||||||
API documentation:
|
|
||||||
https://documentation.mailgun.com/en/latest/api-email-validation.html
|
|
||||||
"""
|
|
||||||
api_key, api_url, domain, validation_key = self.env[
|
|
||||||
'mail.tracking.email']._mailgun_values()
|
|
||||||
if not validation_key:
|
|
||||||
raise UserError(_('You need to configure mailgun.validation_key'
|
|
||||||
' in order to be able to check mails validity'))
|
|
||||||
result = {}
|
|
||||||
for email in email_list:
|
|
||||||
res = requests.get(
|
|
||||||
"%s/address/validate" % api_url,
|
|
||||||
auth=("api", validation_key), params={
|
|
||||||
"address": email,
|
|
||||||
"mailbox_verification": True,
|
|
||||||
})
|
|
||||||
if not res or res.status_code != 200:
|
|
||||||
result[email] = {'result': (_(
|
|
||||||
'Error %s trying to '
|
|
||||||
'check mail' % res.status_code or 'of connection'))}
|
|
||||||
continue
|
|
||||||
content = json.loads(res.content, res.apparent_encoding)
|
|
||||||
if 'mailbox_verification' not in content:
|
|
||||||
result[email] = {'result': (
|
|
||||||
_("Mailgun Error. Mailbox verification value wasn't"
|
|
||||||
" returned"))}
|
|
||||||
continue
|
|
||||||
# Not a valid address: API sets 'is_valid' as False
|
|
||||||
# and 'mailbox_verification' as None
|
|
||||||
if not content['is_valid']:
|
|
||||||
result[email] = {'result': (
|
|
||||||
_('%s is not a valid email address. Please check it '
|
|
||||||
'in order to avoid sending issues') % (email))}
|
|
||||||
continue
|
|
||||||
# If the mailbox is not valid API returns 'mailbox_verification'
|
|
||||||
# as a string with value 'false'
|
|
||||||
if content['mailbox_verification'] == 'false':
|
|
||||||
result[email] = {'result': (
|
|
||||||
_('%s failed the mailbox verification. Please check it '
|
|
||||||
'in order to avoid sending issues') % (email))}
|
|
||||||
continue
|
|
||||||
# If Mailgun can't complete the validation request the API returns
|
|
||||||
# 'mailbox_verification' as a string set to 'unknown'
|
|
||||||
if content['mailbox_verification'] == 'unknown':
|
|
||||||
result[email] = {'result': (
|
|
||||||
_("%s couldn't be verified. Either the request couln't be "
|
|
||||||
"completed or the mailbox provider doesn't support "
|
|
||||||
"email verification") % (email))}
|
|
||||||
continue
|
|
||||||
result[email] = {'result': _("The mailbox is correct")}
|
|
||||||
return result
|
|
||||||
|
@ -45,43 +45,50 @@ class ResPartner(models.Model):
|
|||||||
if not validation_key:
|
if not validation_key:
|
||||||
raise UserError(_('You need to configure mailgun.validation_key'
|
raise UserError(_('You need to configure mailgun.validation_key'
|
||||||
' in order to be able to check mails validity'))
|
' in order to be able to check mails validity'))
|
||||||
for partner in self:
|
for partner in self.filtered('email'):
|
||||||
res = requests.get(
|
res = requests.get(
|
||||||
"%s/address/validate" % api_url,
|
"%s/address/validate" % api_url,
|
||||||
auth=("api", validation_key), params={
|
auth=("api", validation_key), params={
|
||||||
"address": partner.email,
|
"address": partner.email,
|
||||||
"mailbox_verification": True,
|
"mailbox_verification": True,
|
||||||
})
|
})
|
||||||
if not res or res.status_code != 200:
|
if not res or res.status_code != 200 and not self.env.context.get(
|
||||||
|
'mailgun_auto_check'):
|
||||||
raise UserError(_(
|
raise UserError(_(
|
||||||
'Error %s trying to '
|
'Error %s trying to '
|
||||||
'check mail' % res.status_code or 'of connection'))
|
'check mail' % res.status_code or 'of connection'))
|
||||||
content = json.loads(res.content, res.apparent_encoding)
|
content = json.loads(res.content, res.apparent_encoding)
|
||||||
if 'mailbox_verification' not in content:
|
if 'mailbox_verification' not in content:
|
||||||
raise UserError(
|
if not self.env.context.get('mailgun_auto_check'):
|
||||||
_("Mailgun Error. Mailbox verification value wasn't"
|
raise UserError(
|
||||||
" returned"))
|
_("Mailgun Error. Mailbox verification value wasn't"
|
||||||
|
" returned"))
|
||||||
# Not a valid address: API sets 'is_valid' as False
|
# Not a valid address: API sets 'is_valid' as False
|
||||||
# and 'mailbox_verification' as None
|
# and 'mailbox_verification' as None
|
||||||
if not content['is_valid']:
|
if not content['is_valid']:
|
||||||
partner.email_bounced = True
|
partner.email_bounced = True
|
||||||
raise UserError(
|
body = _('%s is not a valid email address. Please check it'
|
||||||
_('%s is not a valid email address. Please check it '
|
' in order to avoid sending issues') % partner.email
|
||||||
'in order to avoid sending issues') % (partner.email))
|
if not self.env.context.get('mailgun_auto_check'):
|
||||||
|
raise UserError(body)
|
||||||
|
partner.message_post(body=body)
|
||||||
# If the mailbox is not valid API returns 'mailbox_verification'
|
# If the mailbox is not valid API returns 'mailbox_verification'
|
||||||
# as a string with value 'false'
|
# as a string with value 'false'
|
||||||
if content['mailbox_verification'] == 'false':
|
if content['mailbox_verification'] == 'false':
|
||||||
partner.email_bounced = True
|
partner.email_bounced = True
|
||||||
raise UserError(
|
body = _('%s failed the mailbox verification. Please check it'
|
||||||
_('%s failed the mailbox verification. Please check it '
|
' in order to avoid sending issues') % partner.email
|
||||||
'in order to avoid sending issues') % (partner.email))
|
if not self.env.context.get('mailgun_auto_check'):
|
||||||
|
raise UserError(body)
|
||||||
|
partner.message_post(body=body)
|
||||||
# If Mailgun can't complete the validation request the API returns
|
# If Mailgun can't complete the validation request the API returns
|
||||||
# 'mailbox_verification' as a string set to 'unknown'
|
# 'mailbox_verification' as a string set to 'unknown'
|
||||||
if content['mailbox_verification'] == 'unknown':
|
if content['mailbox_verification'] == 'unknown':
|
||||||
raise UserError(
|
if not self.env.context.get('mailgun_auto_check'):
|
||||||
_("%s couldn't be verified. Either the request couln't be "
|
raise UserError(
|
||||||
"completed or the mailbox provider doesn't support "
|
_("%s couldn't be verified. Either the request couln't"
|
||||||
"email verification") % (partner.email))
|
" be completed or the mailbox provider doesn't "
|
||||||
|
"support email verification") % (partner.email))
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def check_email_bounced(self):
|
def check_email_bounced(self):
|
||||||
@ -133,3 +140,21 @@ class ResPartner(models.Model):
|
|||||||
auth=("api", api_key))
|
auth=("api", api_key))
|
||||||
if res.status_code in (200, 404) and partner.email_bounced:
|
if res.status_code in (200, 404) and partner.email_bounced:
|
||||||
partner.email_bounced = False
|
partner.email_bounced = False
|
||||||
|
|
||||||
|
def _autocheck_partner_email(self):
|
||||||
|
for partner in self:
|
||||||
|
partner.with_context(
|
||||||
|
mailgun_auto_check=True).check_email_validity()
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
if 'email' in vals and self.env['ir.config_parameter'].get_param(
|
||||||
|
'mailgun.auto_check_partner_email'):
|
||||||
|
self._autocheck_partner_email()
|
||||||
|
return super(ResPartner, self).create(vals)
|
||||||
|
|
||||||
|
def write(self, vals):
|
||||||
|
if 'email' in vals and self.env['ir.config_parameter'].get_param(
|
||||||
|
'mailgun.auto_check_partner_email'):
|
||||||
|
self._autocheck_partner_email()
|
||||||
|
return super(ResPartner, self).write(vals)
|
||||||
|
@ -43,6 +43,8 @@ class TestMailgun(TransactionCase):
|
|||||||
'mail.catchall.domain', self.domain)
|
'mail.catchall.domain', self.domain)
|
||||||
self.env['ir.config_parameter'].set_param(
|
self.env['ir.config_parameter'].set_param(
|
||||||
'mailgun.validation_key', self.api_key)
|
'mailgun.validation_key', self.api_key)
|
||||||
|
self.env['ir.config_parameter'].set_param(
|
||||||
|
'mailgun.auto_check_partner_email', '')
|
||||||
self.event = {
|
self.event = {
|
||||||
'Message-Id': u'<xxx.xxx.xxx-openerp-xxx-res.partner@test_db>',
|
'Message-Id': u'<xxx.xxx.xxx-openerp-xxx-res.partner@test_db>',
|
||||||
'X-Mailgun-Sid': u'WyIwNjgxZSIsICJ0b0BleGFtcGxlLmNvbSIsICI3MG'
|
'X-Mailgun-Sid': u'WyIwNjgxZSIsICJ0b0BleGFtcGxlLmNvbSIsICI3MG'
|
||||||
@ -332,14 +334,16 @@ class TestMailgun(TransactionCase):
|
|||||||
@mock.patch(_packagepath + '.models.res_partner.requests')
|
@mock.patch(_packagepath + '.models.res_partner.requests')
|
||||||
def test_email_validity(self, mock_request):
|
def test_email_validity(self, mock_request):
|
||||||
self.partner.email_bounced = False
|
self.partner.email_bounced = False
|
||||||
self.partner.email = 'info@tecnativa.com'
|
|
||||||
mock_request.get.return_value.apparent_encoding = 'ascii'
|
mock_request.get.return_value.apparent_encoding = 'ascii'
|
||||||
mock_request.get.return_value.status_code = 200
|
mock_request.get.return_value.status_code = 200
|
||||||
mock_request.get.return_value.content = json.dumps({
|
mock_request.get.return_value.content = json.dumps({
|
||||||
'is_valid': True,
|
'is_valid': True,
|
||||||
'mailbox_verification': 'true',
|
'mailbox_verification': 'true',
|
||||||
}, ensure_ascii=True)
|
}, ensure_ascii=True)
|
||||||
self.partner.check_email_validity()
|
# Trigger email auto validation in partner
|
||||||
|
self.env['ir.config_parameter'].set_param(
|
||||||
|
'mailgun.auto_check_partner_email', 'True')
|
||||||
|
self.partner.email = 'info@tecnativa.com'
|
||||||
self.assertFalse(self.partner.email_bounced)
|
self.assertFalse(self.partner.email_bounced)
|
||||||
self.partner.email = 'xoxoxoxo@tecnativa.com'
|
self.partner.email = 'xoxoxoxo@tecnativa.com'
|
||||||
# Not a valid mailbox
|
# Not a valid mailbox
|
||||||
|
Loading…
x
Reference in New Issue
Block a user