[FIX] mail_tracking_mailgun: Avoid errors without event
When this method is called without an event (a.k.a. `event=None`), this method produces the following error:
```
Traceback (most recent call last):
File "/opt/odoo/auto/addons/mail/models/mail_mail.py", line 278, in send
res = IrMailServer.send_email(msg, mail_server_id=mail.mail_server_id.id)
File "/opt/odoo/auto/addons/mail_tracking/models/ir_mail_server.py", line 88, in send_email
tracking_email.smtp_error(self, smtp_server_used, e)
File "/opt/odoo/auto/addons/mail_tracking/models/mail_tracking_email.py", line 213, in smtp_error
self.sudo()._partners_email_bounced_set('error')
File "/opt/odoo/auto/addons/mail_tracking/models/mail_tracking_email.py", line 203, in
_partners_email_bounced_set
]).email_bounced_set(self, reason, event=event)
File "/opt/odoo/auto/addons/mail_tracking_mailgun/models/res_partner.py", line 22, in
email_bounced_set
self._email_bounced_set(reason, event)
File "/opt/odoo/auto/addons/mail_tracking_mailgun/models/res_partner.py", line 33, in
_email_bounced_set
event['Message-Id'] or '') TypeError: 'NoneType' object has no attribute '__getitem__'
```
So, we now assume we do not always have an event.
7 years ago |
|
# -*- coding: utf-8 -*- # Copyright 2016 Tecnativa - Antonio Espinosa # Copyright 2016 Tecnativa - Carlos Dauden # Copyright 2017 Tecnativa - Pedro M. Baeza # Copyright 2017 Tecnativa - David Vidal # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import requests import json
from odoo import _, api, models from odoo.exceptions import UserError
class ResPartner(models.Model): _inherit = 'res.partner'
@api.multi def email_bounced_set(self, tracking_emails, reason, event=None): res = super(ResPartner, self).email_bounced_set( tracking_emails, reason, event=event) self._email_bounced_set(reason, event) return res
@api.multi def _email_bounced_set(self, reason, event): for partner in self: if not partner.email: continue body = _('Email has been bounced: %s\n' 'Reason: %s\n' 'Event: %s') % (partner.email, reason, event and event.get('Message-Id', _('unknown'))) partner.message_post(body=body)
@api.multi def check_email_validity(self): """
Checks mailbox 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')) for partner in self: res = requests.get( "%s/address/validate" % api_url, auth=("api", validation_key), params={ "address": partner.email, "mailbox_verification": True, }) if not res or res.status_code != 200: raise UserError(_( 'Error %s trying to ' 'check mail' % res.status_code or 'of connection')) content = json.loads(res.content, res.apparent_encoding) if 'mailbox_verification' not in content: raise UserError( _("Mailgun Error. Mailbox verification value wasn't" " returned")) # Not a valid address: API sets 'is_valid' as False # and 'mailbox_verification' as None if not content['is_valid']: partner.email_bounced = True raise UserError( _('%s is not a valid email address. Please check it ' 'in order to avoid sending issues') % (partner.email)) # If the mailbox is not valid API returns 'mailbox_verification' # as a string with value 'false' if content['mailbox_verification'] == 'false': partner.email_bounced = True raise UserError( _('%s failed the mailbox verification. Please check it ' 'in order to avoid sending issues') % (partner.email)) # If Mailgun can't complete the validation request the API returns # 'mailbox_verification' as a string set to 'unknown' if content['mailbox_verification'] == 'unknown': raise UserError( _("%s couldn't be verified. Either the request couln't be " "completed or the mailbox provider doesn't support " "email verification") % (partner.email))
@api.multi def check_email_bounced(self): """
Checks if the partner's email is in Mailgun's bounces list API documentation: https://documentation.mailgun.com/en/latest/api-suppressions.html """
api_key, api_url, domain, validation_key = self.env[ 'mail.tracking.email']._mailgun_values() for partner in self: res = requests.get( '%s/%s/bounces/%s' % (api_url, domain, partner.email), auth=("api", api_key)) if res.status_code == 200 and not partner.email_bounced: partner.email_bounced = True elif res.status_code == 404 and partner.email_bounced: partner.email_bounced = False
@api.multi def force_set_bounced(self): """
Forces partner's email into Mailgun's bounces list API documentation: https://documentation.mailgun.com/en/latest/api-suppressions.html """
api_key, api_url, domain, validation_key = self.env[ 'mail.tracking.email']._mailgun_values() for partner in self: res = requests.post( '%s/%s/bounces' % (api_url, domain), auth=("api", api_key), data={'address': partner.email}) partner.email_bounced = ( res.status_code == 200 and not partner.email_bounced)
@api.multi def force_unset_bounced(self): """
Forces partner's email deletion from Mailgun's bounces list API documentation: https://documentation.mailgun.com/en/latest/api-suppressions.html """
api_key, api_url, domain, validation_key = self.env[ 'mail.tracking.email']._mailgun_values() for partner in self: res = requests.delete( '%s/%s/bounces/%s' % (api_url, domain, partner.email), auth=("api", api_key)) if res.status_code in (200, 404) and partner.email_bounced: partner.email_bounced = False
|