mirror of https://github.com/OCA/social.git
parent
e1b1ff2ff5
commit
9301a732fe
|
@ -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)",
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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 > Settings > 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 > Settings > 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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue