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