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.

162 lines
6.8 KiB

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