diff --git a/mass_mailing_custom_unsubscribe/README.rst b/mass_mailing_custom_unsubscribe/README.rst index 784b2706..14efcbcd 100644 --- a/mass_mailing_custom_unsubscribe/README.rst +++ b/mass_mailing_custom_unsubscribe/README.rst @@ -1,65 +1,71 @@ .. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :alt: License: AGPL-3 + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 -==================================================== -Customizable unsubscribe link on mass mailing emails -==================================================== +========================================================== +Customizable unsubscription process on mass mailing emails +========================================================== -With this module you can set a custom unsubscribe link append at bottom of mass -mailing emails. +This addon extends the unsubscription form to let you: +- Choose which mailing lists are not cross-unsubscriptable when unsubscribing + from a different one. +- Know why and when a contact has been unsubscribed from a mass mailing. Configuration ============= -To configure unsubscribe label go to Setting > Technical > Parameters > System parameters -and add a 'mass_mailing.unsubscribe.label' parameter with html to set at bottom -of mass emailing emails. Including '%(url)s' variable where unsubscribe link +Unsubscription Reasons +---------------------- -For example: - -.. code:: html - - You can unsubscribe here - - -Additionally, you can disable this link if you set this parameter to 'False' - -If this parameter (mass_mailing.unsubscribe.label) is not set (or set to '') -default 'Click to unsubscribe' link will appear. This default text is -translatable via Settings > Translations > Application Terms > Translated terms +You can customize what reasons will be displayed to your unsubscriptors when +they are going to unsubscribe. To do it: +#. Go to *Mass Mailing > Configuration > Unsubscription Reasons*. +#. Create / edit / remove / sort as usual. +#. If *Details required* is enabled, they will have to fill a text area to + continue. Usage ===== +Once configured: + +#. Go to *Mass Mailing > Mailings > Mass Mailings > Create*. +#. Edit your mass mailing at wish, but remember to add a snippet from + *Footers*, so people have an *Unsubscribe* link. +#. Send it. +#. If somebody gets unsubscribed, you will see logs about that under + *Mass Mailing > Mailings > Unsubscriptions*. + .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/205/8.0 - + :target: https://runbot.odoo-community.org/runbot/205/10.0 Known issues / Roadmap ====================== -* This custom html is not translatable, so as a suggestion, you can define - the same text in several languages in several lines. - -For example: - -.. code:: html - - [EN] You can unsubscribe here
- [ES] Puedes darte de baja aquí - +* This module adds a security hash for mass mailing unsubscription URLs, which + disables insecure URLs from mass mailing messages sent before its + installation. This can be a problem, but anyway you'd get that problem in + Odoo 11.0, where https://github.com/odoo/odoo/pull/12040 was merged, so at + least this addon will be forward-compatible with it. So, **this feature must + be removed from here when migrating to v11**. +* This module replaces AJAX submission core implementation from the mailing + list management form, because it is impossible to extend it. When + https://github.com/odoo/odoo/pull/14386 gets merged (which upstreams most + needed changes), this addon will need a refactoring (mostly removing + duplicated functionality and depending on it instead of replacing it). In the + mean time, there is a little chance that this introduces some + incompatibilities with other addons that depend on ``website_mass_mailing``. Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. - +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. Credits ======= @@ -67,8 +73,9 @@ Credits Contributors ------------ -* Rafael Blasco -* Antonio Espinosa +* Rafael Blasco +* Antonio Espinosa +* Jairo Llopis Maintainer ---------- @@ -83,4 +90,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. \ No newline at end of file +To contribute to this module, please visit https://odoo-community.org. diff --git a/mass_mailing_custom_unsubscribe/__init__.py b/mass_mailing_custom_unsubscribe/__init__.py index 8764d62c..434c1256 100644 --- a/mass_mailing_custom_unsubscribe/__init__.py +++ b/mass_mailing_custom_unsubscribe/__init__.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ -############################################################################## -# For copyright and license notices, see __openerp__.py file in root directory -############################################################################## +# Copyright 2016 Jairo Llopis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from . import models +from . import controllers, models diff --git a/mass_mailing_custom_unsubscribe/__manifest__.py b/mass_mailing_custom_unsubscribe/__manifest__.py index 5429b38b..c533f2c1 100644 --- a/mass_mailing_custom_unsubscribe/__manifest__.py +++ b/mass_mailing_custom_unsubscribe/__manifest__.py @@ -1,37 +1,33 @@ # -*- coding: utf-8 -*- -# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ -############################################################################## -# -# OpenERP, Odoo Source Management Solution -# Copyright (c) 2015 Antiun Ingeniería S.L. (http://www.antiun.com) -# Antonio Espinosa -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# Copyright 2016 Jairo Llopis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': "Customizable unsubscribe link on mass mailing emails", + 'name': "Customizable unsubscription process on mass mailing emails", + "summary": "Know unsubscription reasons, track them", 'category': 'Marketing', - 'version': '8.0.1.0.0', + 'version': '10.0.1.0.0', 'depends': [ - 'mass_mailing', + 'website_mass_mailing', ], 'data': [ + 'security/ir.model.access.csv', + 'data/mail_unsubscription_reason.xml', + 'templates/general_reason_form.xml', + 'templates/mass_mailing_contact_reason.xml', + 'views/assets.xml', + 'views/mail_unsubscription_reason_view.xml', + 'views/mail_mass_mailing_list_view.xml', + 'views/mail_unsubscription_view.xml', ], - 'author': 'Antiun Ingeniería S.L., ' + "demo": [ + 'demo/assets.xml', + ], + 'images': [ + 'images/form.png', + ], + 'author': 'Tecnativa,' 'Odoo Community Association (OCA)', - 'website': 'http://www.antiun.com', + 'website': 'https://www.tecnativa.com', 'license': 'AGPL-3', - 'installable': False, + 'installable': True, } diff --git a/mass_mailing_custom_unsubscribe/controllers/__init__.py b/mass_mailing_custom_unsubscribe/controllers/__init__.py new file mode 100644 index 00000000..66679113 --- /dev/null +++ b/mass_mailing_custom_unsubscribe/controllers/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Jairo Llopis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import main diff --git a/mass_mailing_custom_unsubscribe/controllers/main.py b/mass_mailing_custom_unsubscribe/controllers/main.py new file mode 100644 index 00000000..403efeb9 --- /dev/null +++ b/mass_mailing_custom_unsubscribe/controllers/main.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Antiun Ingeniería S.L. (http://www.antiun.com) +# Copyright 2016 Jairo Llopis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging + +from openerp.http import request, route +from openerp.addons.website_mass_mailing.controllers.main \ + import MassMailController + +_logger = logging.getLogger(__name__) + + +class CustomUnsubscribe(MassMailController): + def reason_form(self, mailing, email, res_id, token): + """Get the unsubscription reason form. + + :param mail.mass_mailing mailing: + Mailing where the unsubscription is being processed. + + :param str email: + Email to be unsubscribed. + + :param int res_id: + ID of the unsubscriber. + + :param str token: + Security token for unsubscriptions. + """ + reasons = request.env["mail.unsubscription.reason"].search([]) + return request.render( + "mass_mailing_custom_unsubscribe.reason_form", + { + "email": email, + "mailing": mailing, + "reasons": reasons, + "res_id": res_id, + "token": token, + }) + + @route() + def mailing(self, mailing_id, email=None, res_id=None, token="", **post): + """Ask/save unsubscription reason.""" + _logger.debug( + "Called `mailing()` with: %r", + (mailing_id, email, res_id, token, post)) + mailing = request.env["mail.mass_mailing"].sudo().browse(mailing_id) + mailing._unsubscribe_token(res_id, token) + # Mass mailing list contacts are a special case because they have a + # subscription management form + if mailing.mailing_model == 'mail.mass_mailing.contact': + result = super(CustomUnsubscribe, self).mailing( + mailing_id, email, res_id, **post) + # FIXME Remove res_id and token in version where this is merged: + # https://github.com/odoo/odoo/pull/14385 + result.qcontext.update({ + "token": token, + "res_id": res_id, + "contacts": result.qcontext["contacts"].filtered( + lambda contact: + not contact.list_id.not_cross_unsubscriptable or + contact.list_id <= mailing.contact_list_ids + ), + "reasons": + request.env["mail.unsubscription.reason"].search([]), + }) + return result + # Any other record type gets a simplified form + try: + # Check if we already have a reason for unsubscription + reason_id = int(post["reason_id"]) + except (KeyError, ValueError): + # No reasons? Ask for them + return self.reason_form(mailing, email, res_id, token) + else: + # Unsubscribe, saving reason and details by context + request.context = dict( + request.context, + default_reason_id=reason_id, + default_details=post.get("details") or False, + ) + # You could get a DetailsRequiredError here, but only if HTML5 + # validation fails, which should not happen in modern browsers + return super(CustomUnsubscribe, self).mailing( + mailing_id, email, res_id, **post) + + @route() + def unsubscribe(self, mailing_id, opt_in_ids, opt_out_ids, email, res_id, + token, reason_id=None, details=None): + """Store unsubscription reasons when unsubscribing from RPC.""" + # Update request context and reset environment + if reason_id: + request.context = dict( + request.context, + default_reason_id=int(reason_id), + default_details=details or False, + ) + # FIXME Remove token check in version where this is merged: + # https://github.com/odoo/odoo/pull/14385 + mailing = request.env['mail.mass_mailing'].sudo().browse(mailing_id) + mailing._unsubscribe_token(res_id, token) + _logger.debug( + "Called `unsubscribe()` with: %r", + (mailing_id, opt_in_ids, opt_out_ids, email, res_id, token, + reason_id, details)) + return super(CustomUnsubscribe, self).unsubscribe( + mailing_id, opt_in_ids, opt_out_ids, email) diff --git a/mass_mailing_custom_unsubscribe/data/mail_unsubscription_reason.xml b/mass_mailing_custom_unsubscribe/data/mail_unsubscription_reason.xml new file mode 100644 index 00000000..4335f9b7 --- /dev/null +++ b/mass_mailing_custom_unsubscribe/data/mail_unsubscription_reason.xml @@ -0,0 +1,41 @@ + + + + + + + + I'm not interested + 10 + + + + + I did not request this + 20 + + + + + I get too many emails + 30 + + + + + Other reason + 100 + + + + + diff --git a/mass_mailing_custom_unsubscribe/demo/assets.xml b/mass_mailing_custom_unsubscribe/demo/assets.xml new file mode 100644 index 00000000..c55f302b --- /dev/null +++ b/mass_mailing_custom_unsubscribe/demo/assets.xml @@ -0,0 +1,17 @@ + + + + + +