You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
6.8 KiB

  1. # Copyright 2016 Tecnativa - Antonio Espinosa
  2. # Copyright 2016 Tecnativa - Carlos Dauden
  3. # Copyright 2017 Tecnativa - Pedro M. Baeza
  4. # Copyright 2017 Tecnativa - David Vidal
  5. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  6. import requests
  7. from odoo import _, api, models
  8. from odoo.exceptions import UserError
  9. class ResPartner(models.Model):
  10. _inherit = 'res.partner'
  11. @api.multi
  12. def email_bounced_set(self, tracking_emails, reason, event=None):
  13. res = super(ResPartner, self).email_bounced_set(
  14. tracking_emails, reason, event=event)
  15. self._email_bounced_set(reason, event)
  16. return res
  17. @api.multi
  18. def _email_bounced_set(self, reason, event):
  19. for partner in self:
  20. if not partner.email:
  21. continue
  22. body = _('Email has been bounced: %s\n'
  23. 'Reason: %s\n'
  24. 'Event: %s') % (partner.email, reason,
  25. event and event.id or _('unknown'))
  26. partner.message_post(body=body)
  27. @api.multi
  28. def check_email_validity(self):
  29. """
  30. Checks mailbox validity with Mailgun's API
  31. API documentation:
  32. https://documentation.mailgun.com/en/latest/api-email-validation.html
  33. """
  34. api_key, api_url, domain, validation_key = self.env[
  35. 'mail.tracking.email']._mailgun_values()
  36. if not validation_key:
  37. raise UserError(_('You need to configure mailgun.validation_key'
  38. ' in order to be able to check mails validity'))
  39. for partner in self.filtered('email'):
  40. res = requests.get(
  41. # Validation API url is always the same
  42. 'https://api.mailgun.net/v3/address/validate',
  43. auth=("api", validation_key), params={
  44. "address": partner.email,
  45. "mailbox_verification": True,
  46. })
  47. if not res or res.status_code != 200 and not self.env.context.get(
  48. 'mailgun_auto_check'):
  49. raise UserError(_(
  50. 'Error %s trying to '
  51. 'check mail' % res.status_code or 'of connection'))
  52. content = res.json()
  53. if 'mailbox_verification' not in content:
  54. if not self.env.context.get('mailgun_auto_check'):
  55. raise UserError(
  56. _("Mailgun Error. Mailbox verification value wasn't"
  57. " returned"))
  58. # Not a valid address: API sets 'is_valid' as False
  59. # and 'mailbox_verification' as None
  60. if not content['is_valid']:
  61. partner.email_bounced = True
  62. body = _('%s is not a valid email address. Please check it'
  63. ' in order to avoid sending issues') % partner.email
  64. if not self.env.context.get('mailgun_auto_check'):
  65. raise UserError(body)
  66. partner.message_post(body=body)
  67. # If the mailbox is not valid API returns 'mailbox_verification'
  68. # as a string with value 'false'
  69. if content['mailbox_verification'] == 'false':
  70. partner.email_bounced = True
  71. body = _('%s failed the mailbox verification. Please check it'
  72. ' in order to avoid sending issues') % partner.email
  73. if not self.env.context.get('mailgun_auto_check'):
  74. raise UserError(body)
  75. partner.message_post(body=body)
  76. # If Mailgun can't complete the validation request the API returns
  77. # 'mailbox_verification' as a string set to 'unknown'
  78. if content['mailbox_verification'] == 'unknown':
  79. if not self.env.context.get('mailgun_auto_check'):
  80. raise UserError(
  81. _("%s couldn't be verified. Either the request couln't"
  82. " be completed or the mailbox provider doesn't "
  83. "support email verification") % (partner.email))
  84. @api.multi
  85. def check_email_bounced(self):
  86. """
  87. Checks if the partner's email is in Mailgun's bounces list
  88. API documentation:
  89. https://documentation.mailgun.com/en/latest/api-suppressions.html
  90. """
  91. api_key, api_url, domain, validation_key = self.env[
  92. 'mail.tracking.email']._mailgun_values()
  93. for partner in self:
  94. res = requests.get(
  95. '%s/%s/bounces/%s' % (api_url, domain, partner.email),
  96. auth=("api", api_key))
  97. if res.status_code == 200 and not partner.email_bounced:
  98. partner.email_bounced = True
  99. elif res.status_code == 404 and partner.email_bounced:
  100. partner.email_bounced = False
  101. @api.multi
  102. def force_set_bounced(self):
  103. """
  104. Forces partner's email into Mailgun's bounces list
  105. API documentation:
  106. https://documentation.mailgun.com/en/latest/api-suppressions.html
  107. """
  108. api_key, api_url, domain, validation_key = self.env[
  109. 'mail.tracking.email']._mailgun_values()
  110. for partner in self:
  111. res = requests.post(
  112. '%s/%s/bounces' % (api_url, domain),
  113. auth=("api", api_key),
  114. data={'address': partner.email})
  115. partner.email_bounced = (
  116. res.status_code == 200 and not partner.email_bounced)
  117. @api.multi
  118. def force_unset_bounced(self):
  119. """
  120. Forces partner's email deletion from Mailgun's bounces list
  121. API documentation:
  122. https://documentation.mailgun.com/en/latest/api-suppressions.html
  123. """
  124. api_key, api_url, domain, validation_key = self.env[
  125. 'mail.tracking.email']._mailgun_values()
  126. for partner in self:
  127. res = requests.delete(
  128. '%s/%s/bounces/%s' % (api_url, domain, partner.email),
  129. auth=("api", api_key))
  130. if res.status_code in (200, 404) and partner.email_bounced:
  131. partner.email_bounced = False
  132. def _autocheck_partner_email(self):
  133. for partner in self:
  134. partner.with_context(
  135. mailgun_auto_check=True).check_email_validity()
  136. @api.model
  137. def create(self, vals):
  138. if ('email' in vals and
  139. self.env['ir.config_parameter'].sudo().get_param(
  140. 'mailgun.auto_check_partner_email')):
  141. self._autocheck_partner_email()
  142. return super(ResPartner, self).create(vals)
  143. def write(self, vals):
  144. if ('email' in vals and
  145. self.env['ir.config_parameter'].sudo().get_param(
  146. 'mailgun.auto_check_partner_email')):
  147. self._autocheck_partner_email()
  148. return super(ResPartner, self).write(vals)