[MERGE] [FIX] mail_gateway: better algorithm to find the partner of an incoming email when having multiple matching partners for a given email address.
The mailgateway tries to find a partner that is also an user with the email_from. If none is found, it takes the first partner with matching email. In message_post, it tries to find the author based on the document's followers. Indeed it is very likely that an answer comes from a follower of a document. The whole process is not done inside the mailgateway because document and followers related stuff belong to message_post, not to the mail gateway. Tests have been added in mail. bzr revid: tde@openerp.com-20130321120451-qk524qayq28sw3th
This commit is contained in:
commit
88b39119b8
|
@ -416,9 +416,15 @@ class mail_thread(osv.AbstractModel):
|
|||
|
||||
def _message_find_partners(self, cr, uid, message, header_fields=['From'], context=None):
|
||||
""" Find partners related to some header fields of the message. """
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
partner_ids = []
|
||||
s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)])
|
||||
return [partner_id for email in tools.email_split(s)
|
||||
for partner_id in self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], limit=1, context=context)]
|
||||
for email_address in tools.email_split(s):
|
||||
related_partners = partner_obj.search(cr, uid, [('email', 'ilike', email_address), ('user_ids', '!=', False)], limit=1, context=context)
|
||||
if not related_partners:
|
||||
related_partners = partner_obj.search(cr, uid, [('email', 'ilike', email_address)], limit=1, context=context)
|
||||
partner_ids += related_partners
|
||||
return partner_ids
|
||||
|
||||
def _message_find_user_id(self, cr, uid, message, context=None):
|
||||
from_local_part = tools.email_split(decode(message.get('From')))[0]
|
||||
|
@ -523,6 +529,11 @@ class mail_thread(osv.AbstractModel):
|
|||
# Legacy: fallback to matching [ID] in the Subject
|
||||
match = tools.res_re.search(decode_header(message, 'Subject'))
|
||||
thread_id = match and match.group(1)
|
||||
# Convert into int (bug spotted in 7.0 because of str)
|
||||
try:
|
||||
thread_id = int(thread_id)
|
||||
except:
|
||||
thread_id = False
|
||||
assert thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new'), \
|
||||
"No possible route found for incoming message with Message-Id %s. " \
|
||||
"Create an appropriate mail.alias or force the destination model." % message_id
|
||||
|
@ -929,6 +940,19 @@ class mail_thread(osv.AbstractModel):
|
|||
del context['thread_model']
|
||||
return self.pool.get(model).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
|
||||
|
||||
# 0: Parse email-from, try to find a better author_id based on document's followers for incoming emails
|
||||
email_from = kwargs.get('email_from')
|
||||
if email_from and thread_id and type == 'email' and kwargs.get('author_id'):
|
||||
email_list = tools.email_split(email_from)
|
||||
doc = self.browse(cr, uid, thread_id, context=context)
|
||||
if email_list and doc:
|
||||
author_ids = self.pool.get('res.partner').search(cr, uid, [
|
||||
('email', 'ilike', email_list[0]),
|
||||
('id', 'in', [f.id for f in doc.message_follower_ids])
|
||||
], limit=1, context=context)
|
||||
if author_ids:
|
||||
kwargs['author_id'] = author_ids[0]
|
||||
|
||||
# 1: Handle content subtype: if plaintext, converto into HTML
|
||||
if content_subtype == 'plaintext':
|
||||
body = tools.plaintext2html(body)
|
||||
|
|
|
@ -162,7 +162,7 @@ class TestMailgateway(TestMailBase):
|
|||
'message_process: message on created group should have Sylvie as author_id')
|
||||
self.assertIn('Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>', msg.email_from,
|
||||
'message_process: message on created group should have have an email_from')
|
||||
# Test: author (not recipient and and not raoul (as alias owner)) added as follower
|
||||
# Test: author (not recipient and not raoul (as alias owner)) added as follower
|
||||
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
|
||||
self.assertEqual(frog_follower_ids, set([p1id]),
|
||||
'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
|
||||
|
@ -212,7 +212,55 @@ class TestMailgateway(TestMailBase):
|
|||
'message_process: after reply, group should have 2 followers')
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test3: misc gateway features
|
||||
# Test3: email_from and partner finding
|
||||
# --------------------------------------------------
|
||||
|
||||
# Data: extra partner with Raoul's email -> test the 'better author finding'
|
||||
extra_partner_id = self.res_partner.create(cr, uid, {'name': 'A-Raoul', 'email': 'test_raoul@email.com'})
|
||||
# extra_user_id = self.res_users.create(cr, uid, {'name': 'B-Raoul', 'email': self.user_raoul.email})
|
||||
# extra_user_pid = self.res_users.browse(cr, uid, extra_user_id).partner_id.id
|
||||
|
||||
# Do: post a new message, with a known partner -> duplicate emails -> partner
|
||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||
to='erroneous@example.com>', subject='Re: news (2)',
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: author is A-Raoul (only existing)
|
||||
self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id,
|
||||
'message_process: email_from -> author_id wrong')
|
||||
|
||||
# Do: post a new message, with a known partner -> duplicate emails -> user
|
||||
frog_group.message_unsubscribe([extra_partner_id])
|
||||
raoul_email = self.user_raoul.email
|
||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||
to='erroneous@example.com>', subject='Re: news (3)',
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: author is Raoul (user), not A-Raoul
|
||||
self.assertEqual(frog_group.message_ids[0].author_id.id, self.partner_raoul_id,
|
||||
'message_process: email_from -> author_id wrong')
|
||||
|
||||
# Do: post a new message, with a known partner -> duplicate emails -> partner because is follower
|
||||
frog_group.message_unsubscribe([self.partner_raoul_id])
|
||||
frog_group.message_subscribe([extra_partner_id])
|
||||
raoul_email = self.user_raoul.email
|
||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'})
|
||||
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
|
||||
to='erroneous@example.com>', subject='Re: news (3)',
|
||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
|
||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||
# Test: author is Raoul (user), not A-Raoul
|
||||
self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id,
|
||||
'message_process: email_from -> author_id wrong')
|
||||
|
||||
self.res_users.write(cr, uid, self.user_raoul_id, {'email': raoul_email})
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test4: misc gateway features
|
||||
# --------------------------------------------------
|
||||
|
||||
# Do: incoming email with model that does not accepts incoming emails must raise
|
||||
|
|
Loading…
Reference in New Issue