Files
odoo_source/addons/mass_mailing_sms/models/sms_sms.py
T
Florian Charlier b0f233ba86 [FIX] link_tracker,mass_mailing_sms: fix shorten links
Purpose
Fix bugs in link replacement (html and text version)

1/ The replacement of urls in text (not html) was buggy when
* a string includes multiple urls, and
* `base_url` is one of them and not the first
* Also in SMS marketing when adding the sms `id`

When it came to base_url's turn, the replace function for the content would
replace the `base_url` part of a previously shortened url instead of the
distinct `base_url` link.

2/ Ampersand character
A) The ampersand character prevented replacement of an url inside a `Markup`.
Previous tests passed as the tracker was created but the url was not replaced.

B) The ampersand character was not recognized as part of an url for simple
strings.

3/ Replacement of already short links
A faulty logic made it possible to replace "/r/" urls when no "blacklist" was
passed.

Commit
* Ensures that only the base_url link would be replaced instead in this case.
* Adds support for urls with "&"
* Does prevent shortening short urls
* Improves link conversion performance (regex + avoid duplication when there
  are several occurrences of the same url)
* Adds multiple unit tests

Task-2783844

closes odoo/odoo#91164

X-original-commit: 61026806d831b49a7cf5c44ffef3d762986781ce
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2022-05-12 13:43:17 +02:00

47 lines
1.9 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
from odoo import fields, models, tools
class SmsSms(models.Model):
_inherit = ['sms.sms']
mailing_id = fields.Many2one('mailing.mailing', string='Mass Mailing')
mailing_trace_ids = fields.One2many('mailing.trace', 'sms_sms_id', string='Statistics')
def _update_body_short_links(self):
""" Override to tweak shortened URLs by adding statistics ids, allowing to
find customer back once clicked. """
res = dict.fromkeys(self.ids, False)
for sms in self:
if not sms.mailing_id or not sms.body:
res[sms.id] = sms.body
continue
body = sms.body
for url in set(re.findall(tools.TEXT_URL_REGEX, body)):
if url.startswith(sms.get_base_url() + '/r/'):
body = re.sub(re.escape(url) + r'(?![\w@:%.+&~#=/-])', url + f'/s/{sms.id}', body)
res[sms.id] = body
return res
def _postprocess_iap_sent_sms(self, iap_results, failure_reason=None, unlink_failed=False, unlink_sent=True):
all_sms_ids = [item['res_id'] for item in iap_results]
if any(sms.mailing_id for sms in self.env['sms.sms'].sudo().browse(all_sms_ids)):
for state in self.IAP_TO_SMS_STATE.keys():
sms_ids = [item['res_id'] for item in iap_results if item['state'] == state]
traces = self.env['mailing.trace'].sudo().search([
('sms_sms_id_int', 'in', sms_ids)
])
if traces and state == 'success':
traces.set_sent()
elif traces:
traces.set_failed(failure_type=self.IAP_TO_SMS_STATE[state])
return super(SmsSms, self)._postprocess_iap_sent_sms(
iap_results, failure_reason=failure_reason,
unlink_failed=unlink_failed, unlink_sent=unlink_sent
)