[IMP] mass_mailing: improved send_mail method (WIP). Also added

first fradt of adding an unsubscribe link in the sent emails. Added a controller
managing this unsubscription. It is based on model, res_id and mailing_id, allowing
to find the customer / lead / contact; but the email is added in the link to 
avoid allowing people unsubscribing random people using res_id generation.

bzr revid: tde@openerp.com-20140321172139-sak10zs2g31xj0t4
This commit is contained in:
Thibault Delavallée 2014-03-21 18:21:39 +01:00
parent 1ce1468cea
commit b9cbb48ca3
2 changed files with 55 additions and 6 deletions

View File

@ -2,10 +2,36 @@
from openerp import http, SUPERUSER_ID
from openerp.http import request
class MassMailController(http.Controller):
@http.route('/mail/track/<int:mail_id>/blank.gif', type='http', auth='none')
def track_mail_open(self, mail_id):
print 'tracking', mail_id
""" Email tracking. """
mail_mail_stats = request.registry.get('mail.mail.statistics')
mail_mail_stats.set_opened(request.cr, SUPERUSER_ID, mail_mail_ids=[mail_id])
return "data:image/gif;base64,R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
@http.route(['/mail/mailing/<int:mailing_id>/unsubscribe'], type='http', auth='none')
def mailing(self, mailing_id, email=None, model=None, res_id=None, **post):
cr, uid, context = request.cr, request.uid, request.context
print 'unsubscribing from', mailing_id, email, model, res_id
MassMailing = request.registry['mail.mass_mailing']
# check model is valid
# ...
mailing_ids = MassMailing.exists(cr, SUPERUSER_ID, [mailing_id], context=context)
if not mailing_ids:
print 'wrroooooong'
return ''
if model == 'res.partner':
partner_ids = request.registry[model].search(cr, SUPERUSER_ID, [('id', '=', res_id), ('email', 'ilike', email)], context=context)
print 'Setting partner_ids', partner_ids, 'as opt out'
# request.registry[model].write(cr, SUPERUSER_ID, partner_ids, {'opt_out': True}, context=context)
else:
mailing = MassMailing.browse(cr, SUPERUSER_ID, mailing_ids[0], context=context)
list_ids = [l.id for l in mailing.contact_list_ids]
res_ids = request.registry[model].search(cr, SUPERUSER_ID, [('list_id', 'in', list_ids), ('id', '=', res_id), ('email', 'ilike', email)], context=context)
print 'Setting contacts', res_ids, 'as opt out'
# request.registry[model].write(cr, SUPERUSER_ID, res_ids, {'opt_out': True}, context=context)
return ''

View File

@ -21,6 +21,8 @@
from datetime import datetime
from dateutil import relativedelta
import urllib
import urlparse
from openerp import tools
from openerp.tools.safe_eval import safe_eval as eval
@ -627,30 +629,51 @@ class MassMailing(osv.Model):
# Email Sending
#------------------------------------------------------
def _get_mail_recipients(self, cr, uid, mailing, res_ids, context=None):
def _get_recipients_data(self, cr, uid, mailing, res_ids, context=None):
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
if mailing.mailing_model == 'mail.mass_mailing.contact':
contacts = self.pool['mail.mass_mailing.contact'].browse(cr, uid, res_ids, context=context)
return dict((contact.id, {'email_to': '"%s" <%s>' % (contact.name, contact.email)}) for contact in contacts)
return dict((contact.id, {
'email_to': '"%s" <%s>' % (contact.name, contact.email),
'unsubscribe_url': '<a href="%s">Click to unsubscribe</a>' % urlparse.urljoin(
base_url, 'mail/mailing/%d/unsubscribe?%s' %
(mailing.id, urllib.urlencode({'model': mailing.mailing_model, 'res_id': contact.id, 'email': contact.email}))),
}) for contact in contacts)
else:
return dict((res_id, {'recipient_ids': [(4, res_id)]}) for res_id in res_ids)
partners = self.pool['res.partner'].browse(cr, uid, res_ids, context=context)
return dict((partner.id, {
'email_to': '"%s" <%s>' % (partner.name, partner.email),
'unsubscribe_url': '<a href="%s">Click to unsubscribe</a>' % urlparse.urljoin(
base_url, 'mail/mailing/%d/unsubscribe?%s' %
(mailing.id, urllib.urlencode({'model': mailing.mailing_model, 'res_id': partner.id, 'email': partner.email}))),
# 'access_link': self.pool['mail.mail']._get_partner_access_link(cr, uid, mail, partner, context=context),
}) for partner in partners)
def send_mail(self, cr, uid, ids, context=None):
author_id = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id.id
Mail = self.pool['mail.mail']
for mailing in self.browse(cr, uid, ids, context=context):
domain = self.pool['mail.mass_mailing.list'].get_global_domain(
cr, uid, [l.id for l in mailing.contact_list_ids], context=context
)[mailing.mailing_model]
res_ids = self.pool[mailing.mailing_model].search(cr, uid, domain, context=context)
recipients = self._get_mail_recipients(cr, uid, mailing, res_ids, context=context)
recipients = self._get_recipients_data(cr, uid, mailing, res_ids, context=context)
all_mail_values = self.pool['mail.compose.message'].generate_email_for_composer_batch(
cr, uid, mailing.template_id.id, res_ids,
context=context, fields=['body_html', 'attachment_ids', 'mail_server_id'])
for res_id, mail_values in all_mail_values.iteritems():
body = mail_values.get('body')
recipient_data = recipients[res_id]
if recipient_data['unsubscribe_url']:
body = tools.append_content_to_html(body, recipient_data.pop('unsubscribe_url'), plaintext=False, container_tag='p')
mail_values.update({
'email_from': mailing.email_from,
'reply_to': mailing.reply_to,
'subject': mailing.name,
'body_html': mail_values.get('body'),
'record_name': False,
'author_id': author_id,
'body_html': body,
'auto_delete': True,
'notification': True,
})
@ -667,7 +690,7 @@ class MassMailing(osv.Model):
context=context)
mail_values['attachment_ids'] = m2m_attachment_ids
mail_values.update(recipients[res_id])
mail_values.update(recipient_data)
Mail.create(cr, uid, mail_values, context=context)
return True