[MIG] mail_tracking_mailgun: Migration to 17.0

TT49914
pull/1410/head
David 2024-07-05 11:23:06 +02:00
parent e1b1ff2ff5
commit 9301a732fe
8 changed files with 143 additions and 150 deletions

View File

@ -1,12 +1,12 @@
# Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2016 Tecnativa - Carlos Dauden
# Copyright 2017 Tecnativa - Pedro M. Baeza
# Copyright 2017-18 Tecnativa - David Vidal
# Copyright 2017 Tecnativa - David Vidal
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Mail tracking for Mailgun",
"summary": "Mail tracking and Mailgun webhooks integration",
"version": "16.0.1.0.0",
"version": "17.0.1.0.0",
"category": "Social Network",
"website": "https://github.com/OCA/social",
"author": "Tecnativa, Odoo Community Association (OCA)",

View File

@ -78,8 +78,8 @@ class MailTrackingEmail(models.Model):
if not api_key:
raise ValidationError(_("There is no Mailgun API key!"))
api_url = icp.get_param("mailgun.api_url", "https://api.mailgun.net/v3")
catchall_domain = icp.get_param("mail.catchall.domain")
domain = icp.get_param("mailgun.domain", catchall_domain)
catchall_domain = self.env["mail.alias.domain"].sudo().search([], limit=1).name
domain = icp.get_param("mailgun.domain", catchall_domain or "")
if not domain:
raise ValidationError(_("A Mailgun domain value is needed!"))
validation_key = icp.get_param("mailgun.validation_key")

View File

@ -27,16 +27,17 @@ class ResPartner(models.Model):
if not partner.email:
continue
event = event or self.env["mail.tracking.event"]
event_str = """
<a href="#"
data-oe-model="mail.tracking.event" data-oe-id="%d">%s</a>
""" % (
event.id or 0,
event.id or _("unknown"),
event_str = (
f'<a href="#" data-oe-model="mail.tracking.event"'
f'data-oe-id="{event.id or 0}">{event.id or _("unknown")}</a>'
)
body = _(
"Email has been bounced: %(email)s\nReason: %(reason)s\nEvent: %(event_str)s"
) % ({"email": partner.email, "reason": reason, "event_str": event_str})
"Email has been bounced: %(email)s\nReason: "
"%(reason)s\nEvent: %(event_str)s",
email=partner.email,
reason=reason,
event_str=event_str,
)
# This function can be called by the non user via the callback_method set in
# /mail/tracking/mailgun/all/. A sudo() is not enough to succesfully send
# the bounce message in this circumstances.
@ -147,7 +148,7 @@ class ResPartner(models.Model):
)
for partner in self:
res = requests.get(
urljoin(api_url, "/v3/%s/bounces/%s" % (domain, partner.email)),
urljoin(api_url, f"/v3/{domain}/bounces/{partner.email}"),
auth=("api", api_key),
timeout=timeout,
)
@ -172,7 +173,7 @@ class ResPartner(models.Model):
)
for partner in self:
res = requests.post(
urljoin(api_url, "/v3/%s/bounces" % domain),
urljoin(api_url, "/v3/{domain}/bounces"),
auth=("api", api_key),
data={"address": partner.email},
timeout=timeout,
@ -195,7 +196,7 @@ class ResPartner(models.Model):
)
for partner in self:
res = requests.delete(
urljoin(api_url, "/v3/%s/bounces/%s" % (domain, partner.email)),
urljoin(api_url, f"/v3/{domain}/bounces/{partner.email}"),
auth=("api", api_key),
timeout=timeout,
)

View File

@ -44,13 +44,14 @@ class TestMailgun(TransactionCase):
)
return mail, tracking_email
def setUp(self):
super().setUp()
self.recipient = "to@example.com"
self.mail, self.tracking_email = self.mail_send()
self.domain = "example.com"
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.recipient = "to@example.com"
cls.mail, cls.tracking_email = cls.mail_send(cls)
cls.domain = "example.com"
# Configure Mailgun through GUI
cf = Form(self.env["res.config.settings"])
cf = Form(cls.env["res.config.settings"])
cf.mail_tracking_mailgun_enabled = True
cf.mail_tracking_mailgun_api_key = (
cf.mail_tracking_mailgun_webhook_signing_key
@ -61,14 +62,17 @@ class TestMailgun(TransactionCase):
config = cf.save()
# Done this way as `hr_expense` adds this field again as readonly, and thus Form
# doesn't process it correctly
config.alias_domain = self.domain
# Catchall + Alias
cls.alias_domain = cls.env["mail.alias.domain"].create(
{"catchall_alias": "TheCatchall", "name": cls.domain}
)
config.execute()
self.token = "f1349299097a51b9a7d886fcb5c2735b426ba200ada6e9e149"
self.timestamp = "1471021089"
self.signature = (
cls.token = "f1349299097a51b9a7d886fcb5c2735b426ba200ada6e9e149"
cls.timestamp = "1471021089"
cls.signature = (
"4fb6d4dbbe10ce5d620265dcd7a3c0b8" "ca0dede1433103891bc1ae4086e9d5b2"
)
self.event = {
cls.event = {
"log-level": "info",
"id": "oXAVv5URCF-dKv8c6Sa7T",
"timestamp": 1471021089.0,
@ -83,21 +87,21 @@ class TestMailgun(TransactionCase):
"event": "delivered",
"recipient": "to@example.com",
"user-variables": {
"odoo_db": self.env.cr.dbname,
"tracking_email_id": self.tracking_email.id,
"odoo_db": cls.env.cr.dbname,
"tracking_email_id": cls.tracking_email.id,
},
}
self.metadata = {
cls.metadata = {
"ip": "127.0.0.1",
"user_agent": False,
"os_family": False,
"ua_family": False,
}
self.partner = self.env["res.partner"].create(
cls.partner = cls.env["res.partner"].create(
{"name": "Mr. Odoo", "email": "mrodoo@example.com"}
)
self.response = {"items": [self.event]}
self.MailTrackingController = MailTrackingController()
cls.response = {"items": [cls.event]}
cls.MailTrackingController = MailTrackingController()
@contextmanager
def _request_mock(self, reset_replay_cache=True):
@ -138,10 +142,14 @@ class TestMailgun(TransactionCase):
self.env["mail.tracking.email"]._mailgun_values()
def test_no_domain(self):
self.env["ir.config_parameter"].set_param("mail.catchall.domain", "")
# Avoid pre-existing domains
self.env["mail.alias"].search(
[("alias_domain_id", "!=", False)]
).alias_domain_id = False
self.env["mail.alias.domain"].search([]).unlink()
with self.assertRaises(ValidationError):
self.env["mail.tracking.email"]._mailgun_values()
# now we set an specific domain for Mailgun:
# Now we set an specific domain for Mailgun:
# i.e: we configure new EU zone without loosing old domain statistics
self.env["ir.config_parameter"].set_param("mailgun.domain", "eu.example.com")
self.test_event_delivered()
@ -295,7 +303,7 @@ class TestMailgun(TransactionCase):
ua_type = "browser"
self.event.update(
{
"event": "unsubscribed",
"event": "unsub",
"city": "Mountain View",
"country": "US",
"region": "CA",

View File

@ -12,7 +12,7 @@
name="action_manual_check_mailgun"
type="object"
string="Re-sync Mailgun"
attrs="{'invisible': [('message_id', '=', False)]}"
invisible="not message_id"
/>
</field>
</field>

View File

@ -14,12 +14,9 @@
<label
for="check_email_bounced"
string="Mailgun"
attrs="{'invisible': [('email', '=', False)]}"
invisible="not email"
/>
<div
name="mailgun_buttons"
attrs="{'invisible': [('email', '=', False)]}"
>
<div name="mailgun_buttons" invisible="not email">
<button
name="check_email_bounced"
type="object"
@ -37,14 +34,14 @@
type="object"
string="Set Bounced"
class="oe_link"
attrs="{'invisible': [('email_bounced', '=', True)]}"
invisible="email_bounced"
/>
<button
name="force_unset_bounced"
type="object"
string="Unset Bounced"
class="oe_link"
attrs="{'invisible': [('email_bounced', '=', False)]}"
invisible="not email_bounced"
/>
</div>
</field>

View File

@ -96,8 +96,7 @@ class ResConfigSettings(models.TransientModel):
)
response = requests.delete(
urljoin(
params.api_url,
"/v3/domains/%s/webhooks/%s" % (params.domain, event),
params.api_url, f"/v3/domains/{params.domain}/webhooks/{event}"
),
auth=("api", params.api_key),
timeout=self.env["ir.config_parameter"]

View File

@ -8,12 +8,10 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="mail.res_config_settings_view_form" />
<field name="arch" type="xml">
<div id="emails" position="inside">
<div id="mail_tracking_mailgun" class="col-12 o_setting_box">
<div class="o_setting_left_pane">
<field name="mail_tracking_mailgun_enabled" />
</div>
<div class="o_setting_right_pane">
<block id="emails" position="inside">
<setting id="mail_tracking_mailgun" string="Mailgun">
<field name="mail_tracking_mailgun_enabled" />
<div class="content-group">
<label for="mail_tracking_mailgun_enabled" />
<div class="text-muted">
Connecting Odoo with <a
@ -23,111 +21,101 @@
</div>
<div
class="content-group"
attrs="{'invisible': [('mail_tracking_mailgun_enabled', '=', False)]}"
invisible="not mail_tracking_mailgun_enabled"
>
<div class="row">
<div class="col-12 col-lg-6">
<div class="text-muted mt16 mb4">
Obtain keys in <a
href="https://app.mailgun.com/app/account/security/api_keys"
target="_blank"
>Mailgun &gt; Settings &gt; API keys</a>:
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_api_key"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_api_key"
password="True"
placeholder="key-abcde0123456789abcde0123456789ab"
attrs="{'required': [('mail_tracking_mailgun_enabled', '=', True)]}"
/>
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_webhook_signing_key"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_webhook_signing_key"
password="True"
placeholder="abcde0123456789abcde0123456789ab"
/>
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_validation_key"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_validation_key"
password="True"
placeholder="pubkey-abcde0123456789abcde0123456789ab"
/>
</div>
<div class="mt16 text-warning">Obtain keys in <a
href="https://app.mailgun.com/app/account/security/api_keys"
target="_blank"
>Mailgun &gt; Settings &gt; API keys</a>:</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_api_key"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_api_key"
password="True"
placeholder="key-abcde0123456789abcde0123456789ab"
required="mail_tracking_mailgun_enabled"
/>
</div>
<div class="col-12 col-lg-6">
<div class="text-muted mt16 mb4">
Other settings:
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_domain"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_domain"
placeholder="odoo.example.com"
/>
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_api_url"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_api_url"
placeholder="https://api.mailgun.net"
/>
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_webhooks_domain"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_webhooks_domain"
placeholder="https://odoo.example.com"
/>
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_webhook_signing_key"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_webhook_signing_key"
password="True"
placeholder="abcde0123456789abcde0123456789ab"
/>
</div>
<div class="col-12">
<div class="text-muted mt16 mb4">
If you change Mailgun settings, your Odoo URL or your sending domain, unregister webhooks and register them again to get automatic updates about sent emails:
</div>
<button
type="object"
name="mail_tracking_mailgun_unregister_webhooks"
string="Unregister Mailgun webhooks"
icon="fa-arrow-right"
class="btn-link"
confirm="This will unregister ALL webhooks from Mailgun, which can include webhooks for other apps."
/>
<button
type="object"
name="mail_tracking_mailgun_register_webhooks"
string="Register Mailgun webhooks"
icon="fa-arrow-right"
class="btn-link"
/>
<div class="row mt16">
<label
for="mail_tracking_mailgun_validation_key"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_validation_key"
password="True"
placeholder="pubkey-abcde0123456789abcde0123456789ab"
/>
</div>
</div>
<div class="text-muted mt16 mb4">
Other settings:
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_domain"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_domain"
placeholder="odoo.example.com"
/>
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_api_url"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_api_url"
placeholder="https://api.mailgun.net"
/>
</div>
<div class="row mt16">
<label
for="mail_tracking_mailgun_webhooks_domain"
class="col-lg-3 o_light_label"
/>
<field
name="mail_tracking_mailgun_webhooks_domain"
placeholder="https://odoo.example.com"
/>
</div>
<div class="text-muted mt16 mb4">
If you change Mailgun settings, your Odoo URL or your sending domain, unregister webhooks and register them again to get automatic updates about sent emails:
</div>
<button
type="object"
name="mail_tracking_mailgun_unregister_webhooks"
string="Unregister Mailgun webhooks"
icon="fa-arrow-right"
class="btn-link"
confirm="This will unregister ALL webhooks from Mailgun, which can include webhooks for other apps."
/>
<button
type="object"
name="mail_tracking_mailgun_register_webhooks"
string="Register Mailgun webhooks"
icon="fa-arrow-right"
class="btn-link"
/>
</div>
</div>
</div>
</div>
</setting>
</block>
</field>
</record>