Emanuel Cino
8 years ago
15 changed files with 659 additions and 0 deletions
-
61mail_sendgrid_mass_mailing/README.rst
-
13mail_sendgrid_mass_mailing/__init__.py
-
47mail_sendgrid_mass_mailing/__openerp__.py
-
14mail_sendgrid_mass_mailing/models/__init__.py
-
39mail_sendgrid_mass_mailing/models/email_tracking.py
-
66mail_sendgrid_mass_mailing/models/mail_mail.py
-
135mail_sendgrid_mass_mailing/models/mass_mailing.py
-
BINmail_sendgrid_mass_mailing/static/description/icon.png
-
10mail_sendgrid_mass_mailing/static/description/icon.svg
-
12mail_sendgrid_mass_mailing/tests/__init__.py
-
123mail_sendgrid_mass_mailing/tests/test_mass_mailing.py
-
31mail_sendgrid_mass_mailing/views/mass_mailing_view.xml
-
13mail_sendgrid_mass_mailing/wizards/__init__.py
-
40mail_sendgrid_mass_mailing/wizards/mail_compose_message.py
-
55mail_sendgrid_mass_mailing/wizards/test_mailing.py
@ -0,0 +1,61 @@ |
|||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
|||
:alt: License: AGPL-3 |
|||
|
|||
========================= |
|||
SendGrid for mass mailing |
|||
========================= |
|||
|
|||
Links mass mailing and mail statistics objects with Sendgrid. |
|||
Note that the mass mailing campaign will be sent with Sendgrid transactional |
|||
e-emails (not to mix up with Sendgrid marketing campaigns) |
|||
|
|||
Installation |
|||
============ |
|||
This addon will be automatically installed when 'mail_sendgrid' and |
|||
'mass_mailing' are both installed. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
From mass mailing, you can use Sendgrid templates. |
|||
|
|||
- If you select a Sendgrid template, the campaign will be sent through |
|||
Sendgrid. Otherwise it will use what you set in your system preference |
|||
(see module sendgrid). |
|||
- You can force usage of a language for the template. |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* Use Sendgrid marketing campaigns API |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/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 <https://github.com/OCA/social/issues/new?body=module:%20mail_sendgrid_mass_mailing%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Emanuel Cino <ecino@compassion.ch> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
@ -0,0 +1,13 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
|
|||
from . import models |
|||
from . import wizards |
@ -0,0 +1,47 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# ______ Releasing children from poverty _ |
|||
# / ____/___ ____ ___ ____ ____ ___________(_)___ ____ |
|||
# / / / __ \/ __ `__ \/ __ \/ __ `/ ___/ ___/ / __ \/ __ \ |
|||
# / /___/ /_/ / / / / / / /_/ / /_/ (__ |__ ) / /_/ / / / / |
|||
# \____/\____/_/ /_/ /_/ .___/\__,_/____/____/_/\____/_/ /_/ |
|||
# /_/ |
|||
# in Jesus' name |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# @author: Emanuel Cino <ecino@compassion.ch> |
|||
# |
|||
# 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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
|
|||
{ |
|||
'name': 'Mass Mailing with SendGrid', |
|||
'version': '9.0.1.0.0', |
|||
'category': 'Social Network', |
|||
'author': 'Compassion CH', |
|||
'website': 'http://www.compassion.ch', |
|||
'depends': ['mail_sendgrid', 'mail_tracking_mass_mailing'], |
|||
'data': [ |
|||
'views/mass_mailing_view.xml' |
|||
], |
|||
'demo': [], |
|||
'installable': True, |
|||
'auto_install': True, |
|||
'external_dependencies': { |
|||
'python': ['sendgrid'], |
|||
}, |
|||
} |
@ -0,0 +1,14 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
|
|||
from . import mass_mailing |
|||
from . import mail_mail |
|||
from . import email_tracking |
@ -0,0 +1,39 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino <ecino@compassion.ch> |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
from openerp import models, fields, api |
|||
|
|||
|
|||
class MailTrackingEvent(models.Model): |
|||
""" Push events to campaign_statistics |
|||
""" |
|||
_inherit = 'mail.tracking.event' |
|||
|
|||
@api.model |
|||
def process_delivered(self, tracking_email, metadata): |
|||
res = super(MailTrackingEvent, self).process_delivered( |
|||
tracking_email, metadata) |
|||
mail_mail_stats = self.sudo().env['mail.mail.statistics'].search([ |
|||
('mail_mail_id_int', '=', tracking_email.mail_id_int)]) |
|||
mail_mail_stats.write({ |
|||
'sent': fields.Datetime.now() |
|||
}) |
|||
return res |
|||
|
|||
@api.model |
|||
def process_reject(self, tracking_email, metadata): |
|||
res = super(MailTrackingEvent, self).process_reject( |
|||
tracking_email, metadata) |
|||
mail_mail_stats = self.sudo().env['mail.mail.statistics'].search([ |
|||
('mail_mail_id_int', '=', tracking_email.mail_id_int)]) |
|||
mail_mail_stats.write({ |
|||
'exception': fields.Datetime.now() |
|||
}) |
|||
return res |
@ -0,0 +1,66 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino <ecino@compassion.ch> |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
from openerp import models |
|||
import logging |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from sendgrid.helpers.mail.mail import TrackingSettings, \ |
|||
SubscriptionTracking |
|||
except ImportError: |
|||
_logger.error("ImportError raised while loading module.") |
|||
_logger.debug("ImportError details:", exc_info=True) |
|||
|
|||
|
|||
class MailMail(models.Model): |
|||
_inherit = "mail.mail" |
|||
|
|||
def _prepare_sendgrid_tracking(self): |
|||
track_vals = super(MailMail, self)._prepare_sendgrid_tracking() |
|||
track_vals.update({ |
|||
'mail_id_int': self.id, |
|||
'mass_mailing_id': self.mailing_id.id, |
|||
'mail_stats_id': self.statistics_ids[:1].id |
|||
if self.statistics_ids else False |
|||
}) |
|||
return track_vals |
|||
|
|||
def _track_sendgrid_emails(self): |
|||
""" Push tracking_email in mass_mail_statistic """ |
|||
tracking_emails = super(MailMail, self)._track_sendgrid_emails() |
|||
for tracking in tracking_emails.filtered('mail_stats_id'): |
|||
tracking.mail_stats_id.mail_tracking_id = tracking.id |
|||
return tracking_emails |
|||
|
|||
def _prepare_sendgrid_data(self): |
|||
""" |
|||
Add unsubscribe options in mass mailings |
|||
:return: Sendgrid Email |
|||
""" |
|||
s_mail = super(MailMail, self)._prepare_sendgrid_data() |
|||
tracking_settings = TrackingSettings() |
|||
if self.mailing_id.enable_unsubscribe: |
|||
sub_settings = SubscriptionTracking( |
|||
enable=True, |
|||
text=self.mailing_id.unsubscribe_text, |
|||
html=self.mailing_id.unsubscribe_text, |
|||
) |
|||
if self.mailing_id.unsubscribe_tag: |
|||
sub_settings.substitution_tag = \ |
|||
self.mailing_id.unsubscribe_tag |
|||
tracking_settings.subscription_tracking = sub_settings |
|||
else: |
|||
tracking_settings.subscription_tracking = SubscriptionTracking( |
|||
enable=False) |
|||
|
|||
s_mail.tracking_settings = tracking_settings |
|||
return s_mail |
@ -0,0 +1,135 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp import api, models, fields, _ |
|||
from openerp.exceptions import Warning as UserError |
|||
from openerp.tools.safe_eval import safe_eval |
|||
|
|||
|
|||
class MassMailing(models.Model): |
|||
""" Add a direct link to an e-mail template in order to retrieve all |
|||
Sendgrid configuration into the e-mails. Add ability to force a |
|||
template language. |
|||
""" |
|||
_inherit = 'mail.mass_mailing' |
|||
|
|||
email_template_id = fields.Many2one( |
|||
'mail.template', 'Sengdrid Template', |
|||
) |
|||
lang = fields.Many2one( |
|||
comodel_name="res.lang", string="Force language") |
|||
body_sendgrid = fields.Html(compute='_compute_sendgrid_view') |
|||
# Trick to save html when taken from the e-mail template |
|||
html_copy = fields.Html( |
|||
compute='_compute_sendgrid_view', inverse='_inverse_html_copy') |
|||
enable_unsubscribe = fields.Boolean() |
|||
unsubscribe_text = fields.Char( |
|||
default='If you would like to unsubscribe and stop receiving these ' |
|||
'emails <% clickhere %>.') |
|||
unsubscribe_tag = fields.Char() |
|||
|
|||
@api.depends('body_html') |
|||
def _compute_sendgrid_view(self): |
|||
for wizard in self: |
|||
template = wizard.email_template_id.with_context( |
|||
lang=self.lang.code or self.env.context['lang']) |
|||
sendgrid_template = template.sendgrid_localized_template |
|||
if sendgrid_template and wizard.body_html: |
|||
res_id = self.env[wizard.mailing_model].search(safe_eval( |
|||
wizard.mailing_domain), limit=1).id |
|||
if res_id: |
|||
body = template.render_template( |
|||
wizard.body_html, template.model, [res_id], |
|||
post_process=True)[res_id] |
|||
wizard.body_sendgrid = \ |
|||
sendgrid_template.html_content.replace('<%body%>', |
|||
body) |
|||
else: |
|||
wizard.body_sendgrid = wizard.body_html |
|||
wizard.html_copy = wizard.body_html |
|||
|
|||
def _inverse_html_copy(self): |
|||
for wizard in self: |
|||
wizard.body_html = wizard.html_copy |
|||
|
|||
@api.onchange('email_template_id') |
|||
def onchange_email_template_id(self): |
|||
if self.email_template_id: |
|||
template = self.email_template_id.with_context( |
|||
lang=self.lang.code or self.env.context['lang']) |
|||
if template.email_from: |
|||
self.email_from = template.email_from |
|||
self.name = template.subject |
|||
self.body_html = template.body_html |
|||
|
|||
@api.onchange('lang') |
|||
def onchange_lang(self): |
|||
if self.lang and self.mailing_model == 'res.partner': |
|||
domain = safe_eval(self.mailing_domain) |
|||
lang_tuple = False |
|||
for tuple in domain: |
|||
if tuple[0] == 'lang': |
|||
lang_tuple = tuple |
|||
break |
|||
if lang_tuple: |
|||
domain.remove(lang_tuple) |
|||
domain.append(('lang', '=', self.lang.code)) |
|||
self.mailing_domain = str(domain) |
|||
self.onchange_email_template_id() |
|||
|
|||
@api.multi |
|||
def action_test_mailing(self): |
|||
wizard = self |
|||
if self.email_template_id: |
|||
wizard = self.with_context( |
|||
lang=self.lang.code or self.env.context['lang']) |
|||
return super(MassMailing, wizard).action_test_mailing() |
|||
|
|||
@api.multi |
|||
def send_mail(self): |
|||
self.ensure_one() |
|||
if self.email_template_id: |
|||
# use E-mail Template |
|||
res_ids = self.get_recipients(self) |
|||
if not res_ids: |
|||
raise UserError(_('Please select recipients.')) |
|||
template = self.email_template_id |
|||
composer_values = { |
|||
'template_id': template.id, |
|||
'composition_mode': 'mass_mail', |
|||
'model': template.model, |
|||
'author_id': self.env.user.partner_id.id, |
|||
'res_id': res_ids[0], |
|||
'attachment_ids': [(4, attachment.id) for attachment in |
|||
self.attachment_ids], |
|||
'email_from': self.email_from, |
|||
'body': self.body_html, |
|||
'subject': self.name, |
|||
'record_name': False, |
|||
'mass_mailing_id': self.id, |
|||
'mailing_list_ids': [(4, l.id) for l in |
|||
self.contact_list_ids], |
|||
'no_auto_thread': self.reply_to_mode != 'thread', |
|||
} |
|||
if self.reply_to_mode == 'email': |
|||
composer_values['reply_to'] = self.reply_to |
|||
composer = self.env['mail.compose.message'].with_context( |
|||
lang=self.lang.code or self.env.context.get('lang', 'en_US'), |
|||
active_ids=res_ids) |
|||
emails = composer.mass_mailing_sendgrid(res_ids, composer_values) |
|||
self.write({ |
|||
'state': 'done', |
|||
'sent_date': fields.Datetime.now(), |
|||
}) |
|||
return emails |
|||
else: |
|||
# Traditional sending |
|||
return super(MassMailing, self).send_mail() |
After Width: 128 | Height: 128 | Size: 3.1 KiB |
@ -0,0 +1,10 @@ |
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
|||
<svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid"> |
|||
<g> |
|||
<polygon fill="#9DE1F3" points="85.3335 85.333 0.0005 85.333 0.0005 170.666 0.0005 256 85.3335 256 170.6665 256 170.6665 170.666 170.6665 85.333"></polygon> |
|||
<polygon fill="#27B4E1" points="85.3335 0.0004 85.3335 85.3334 85.3335 170.6664 170.6665 170.6664 255.9995 170.6664 255.9995 0.0004"></polygon> |
|||
<polygon fill="#1A82E2" points="0 256 85.333 256 85.333 170.667 0 170.667"></polygon> |
|||
<polygon fill="#1A82E2" points="170.667 85.333 256 85.333 256 0 170.667 0"></polygon> |
|||
<polygon fill="#239FD7" points="85.334 170.667 170.667 170.667 170.667 85.334 85.334 85.334"></polygon> |
|||
</g> |
|||
</svg> |
@ -0,0 +1,12 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2017 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
|
|||
from . import test_mass_mailing |
@ -0,0 +1,123 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2017 Emanuel Cino - <ecino@compassion.ch> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
import mock |
|||
from openerp.tests.common import TransactionCase |
|||
|
|||
mock_sendgrid_api_client = ('openerp.addons.mail_sendgrid.models.mail_mail' |
|||
'.SendGridAPIClient') |
|||
mock_config = ('openerp.addons.mail_sendgrid.models.mail_mail.' |
|||
'config') |
|||
|
|||
|
|||
class FakeClient(object): |
|||
""" Mock Sendgrid APIClient """ |
|||
status_code = 202 |
|||
body = 'ok' |
|||
|
|||
def __init__(self): |
|||
self.client = self |
|||
self.mail = self |
|||
self.send = self |
|||
|
|||
def post(self, **kwargs): |
|||
return self |
|||
|
|||
|
|||
class FakeRequest(object): |
|||
""" Simulate a Sendgrid JSON request """ |
|||
def __init__(self, data): |
|||
self.jsonrequest = [data] |
|||
|
|||
|
|||
class TestMailSendgrid(TransactionCase): |
|||
def setUp(self): |
|||
super(TestMailSendgrid, self).setUp() |
|||
self.sendgrid_template = self.env['sendgrid.template'].create({ |
|||
'name': 'Test Template', |
|||
'remote_id': 'a74795d7-f926-4bad-8e7a-ae95fabd70fc', |
|||
'html_content': u'<h1>Test Sendgrid</h1><%body%>{footer}' |
|||
}) |
|||
self.mail_template = self.env['mail.template'].create({ |
|||
'name': 'Test Template', |
|||
'model_id': self.env.ref('base.model_res_partner').id, |
|||
'subject': 'Test e-mail', |
|||
'body_html': u'Dear ${object.name}, hello!', |
|||
'sendgrid_template_ids': [ |
|||
(0, 0, {'lang': 'en_US', 'sendgrid_template_id': |
|||
self.sendgrid_template.id})] |
|||
}) |
|||
self.recipient = self.env.ref('base.partner_demo') |
|||
self.mass_mailing = self.env['mail.mass_mailing'].create({ |
|||
'email_from': 'admin@yourcompany.example.com', |
|||
'name': 'Test Mass Mailing Sendgrid', |
|||
'mailing_model': 'res.partner', |
|||
'mailing_domain': "[('id', '=', %d)]" % self.recipient.id, |
|||
'email_template_id': self.mail_template.id, |
|||
'body_html': u'Dear ${object.name}, hello!', |
|||
'reply_to_mode': 'thread', |
|||
}) |
|||
self.timestamp = u'1471021089' |
|||
self.event = { |
|||
'timestamp': self.timestamp, |
|||
'sg_event_id': u"f_JoKtrLQaOXUc4thXgROg", |
|||
'email': self.recipient.email, |
|||
'odoo_db': self.env.cr.dbname, |
|||
'odoo_id': u'<xxx.xxx.xxx-openerp-xxx-res.partner@test_db>' |
|||
} |
|||
self.metadata = { |
|||
'ip': '127.0.0.1', |
|||
'user_agent': False, |
|||
'os_family': False, |
|||
'ua_family': False, |
|||
} |
|||
self.request = FakeRequest(self.event) |
|||
|
|||
@mock.patch(mock_sendgrid_api_client) |
|||
@mock.patch(mock_config) |
|||
def test_send_campaign(self, m_config, mock_sendgrid): |
|||
""" |
|||
Test sending mass campaign with Sendgrid template |
|||
and statistics update |
|||
""" |
|||
self.env['ir.config_parameter'].set_param( |
|||
'mail_sendgrid.send_method', 'sendgrid') |
|||
mock_sendgrid.return_value = FakeClient() |
|||
m_config.get.return_value = 'we4iorujeriu' |
|||
emails = self.mass_mailing.send_mail() |
|||
self.assertEqual(len(emails), 1) |
|||
self.assertEqual(emails.state, 'outgoing') |
|||
self.assertEqual(emails.sendgrid_template_id.id, |
|||
self.sendgrid_template.id) |
|||
|
|||
emails.send() |
|||
self.assertTrue(mock_sendgrid.called) |
|||
self.assertEqual(emails.state, 'sent') |
|||
mail_tracking = emails.tracking_email_ids |
|||
self.assertEqual(len(mail_tracking), 1) |
|||
self.assertFalse(mail_tracking.state) |
|||
stats = self.mass_mailing.statistics_ids |
|||
self.assertEqual(len(stats), 1) |
|||
self.assertFalse(stats.sent) |
|||
|
|||
# Test delivered |
|||
self.event.update({ |
|||
'event': 'delivered', |
|||
'odoo_id': emails.message_id |
|||
}) |
|||
self.env['mail.tracking.email'].event_process( |
|||
self.request, self.event, self.metadata) |
|||
self.assertTrue(stats.sent) |
|||
|
|||
# Test click e-mail |
|||
self.event.update({ |
|||
'event': 'click', |
|||
}) |
|||
self.env['mail.tracking.email'].event_process( |
|||
self.request, self.event, self.metadata) |
|||
self.assertEqual(emails.click_count, 1) |
|||
events = stats.tracking_event_ids |
|||
self.assertEqual(len(events), 2) |
|||
self.assertEqual(events[0].event_type, 'delivered') |
|||
self.assertEqual(events[1].event_type, 'click') |
|||
self.assertEqual(stats.state, 'sent') |
@ -0,0 +1,31 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<!-- Form view --> |
|||
<record id="view_email_template_sendgrid_form" model="ir.ui.view"> |
|||
<field name="name">mass.mailing.sendgrid.form</field> |
|||
<field name="model">mail.mass_mailing</field> |
|||
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='mailing_model']/.." position="after"> |
|||
<field name="email_template_id" domain="[('model', '=', mailing_model), ('sendgrid_template_ids', '!=', False)]"/> |
|||
<field name="lang" attrs="{'invisible': [('email_template_id', '=', False)]}"/> |
|||
</xpath> |
|||
<xpath expr="//notebook/page[1]" position="after"> |
|||
<page string="Sendgrid Preview" attrs="{'invisible': [('email_template_id', '=', False)]}"> |
|||
<field name="html_copy" invisible="1"/> |
|||
<field name="body_sendgrid" widget="html"/> |
|||
</page> |
|||
</xpath> |
|||
<xpath expr="//notebook/page/group[1]"> |
|||
<group string="Sendgrid Unsubscribe"> |
|||
<field name="enable_unsubscribe"/> |
|||
<field name="unsubscribe_text" attrs="{'invisible': [('enable_unsubscribe', '=', False)]}"/> |
|||
<field name="unsubscribe_tag" attrs="{'invisible': [('enable_unsubscribe', '=', False)]}"/> |
|||
</group> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
@ -0,0 +1,13 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
|
|||
from . import mail_compose_message |
|||
from . import test_mailing |
@ -0,0 +1,40 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino <ecino@compassion.ch> |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp import models, api |
|||
|
|||
|
|||
class EmailComposeMessage(models.TransientModel): |
|||
_inherit = 'mail.compose.message' |
|||
|
|||
@api.model |
|||
def mass_mailing_sendgrid(self, res_ids, composer_values): |
|||
""" Helper to generate a new e-mail given a template and objects. |
|||
|
|||
:param res_ids: ids of the resource objects |
|||
:param composer_values: values for the composer wizard |
|||
:return: browse records of created e-mails (one per resource object) |
|||
""" |
|||
if not isinstance(res_ids, list): |
|||
res_ids = [res_ids] |
|||
wizard = self.create(composer_values) |
|||
all_mail_values = wizard.get_mail_values(res_ids) |
|||
email_obj = self.env['mail.mail'] |
|||
emails = email_obj |
|||
for res_id in res_ids: |
|||
mail_values = all_mail_values[res_id] |
|||
obj = self.env[wizard.model].browse(res_id) |
|||
if wizard.model == 'res.partner': |
|||
mail_values['recipient_ids'] = [(6, 0, obj.ids)] |
|||
else: |
|||
mail_values['email_to'] = obj.email |
|||
emails += email_obj.create(mail_values) |
|||
return emails |
@ -0,0 +1,55 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch) |
|||
# Releasing children from poverty in Jesus' name |
|||
# @author: Emanuel Cino <ecino@compassion.ch> |
|||
# |
|||
# The licence is in the file __openerp__.py |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp import models, api, tools |
|||
|
|||
|
|||
class TestMassMailing(models.TransientModel): |
|||
_inherit = 'mail.mass_mailing.test' |
|||
|
|||
@api.multi |
|||
def send_mail_test(self): |
|||
""" Send with Sendgrid if needed. |
|||
""" |
|||
self.ensure_one() |
|||
mailing = self.mass_mailing_id |
|||
template = mailing.email_template_id.with_context( |
|||
lang=mailing.lang.code or self.env.context['lang']) |
|||
if template: |
|||
# Send with SendGrid (and use E-mail Template) |
|||
sendgrid_template = template.sendgrid_localized_template |
|||
res_id = self.env.user.partner_id.id |
|||
body = template.render_template( |
|||
mailing.body_html, template.model, [res_id], |
|||
post_process=True)[res_id] |
|||
test_emails = tools.email_split(self.email_to) |
|||
emails = self.env['mail.mail'] |
|||
for test_mail in test_emails: |
|||
email_vals = { |
|||
'email_from': mailing.email_from, |
|||
'reply_to': mailing.reply_to, |
|||
'email_to': test_mail, |
|||
'subject': mailing.name, |
|||
'body_html': body, |
|||
'sendgrid_template_id': sendgrid_template.id, |
|||
'substitution_ids': template.render_substitutions( |
|||
res_id)[res_id], |
|||
'notification': True, |
|||
'mailing_id': mailing.id, |
|||
'attachment_ids': [(4, attachment.id) for attachment in |
|||
mailing.attachment_ids], |
|||
} |
|||
emails += emails.create(email_vals) |
|||
emails.send_sendgrid() |
|||
else: |
|||
super(TestMassMailing, self).send_mail_test() |
|||
|
|||
return True |
Write
Preview
Loading…
Cancel
Save
Reference in new issue