Files
odoo_source/addons/mass_mailing_sms/controllers/main.py
T
Florian Charlier e8878a8b4c [IMP] {mass_mailing_,}sms: delay sms deletion
Also impacts test_mail_sms.

Purpose: let a cron do delete records to end the
sending transaction sooner.

Removing the foreign key between sms_sms and mailing_trace
is necessary as traces may have to be updated due to
delivery reports.
This is why we do it here and not with notifications
because only traces will trigger updates of a possibly
massive number of records and repeated concurrent updates.

We also replace the now obsolete "sms_sms_X" prefix as there
are not many "sms_id" to distinguish from.

Task-2560666

Part-of: odoo/odoo#133392
2023-10-24 12:38:13 +00:00

109 lines
4.6 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from werkzeug.exceptions import NotFound
from odoo import http, _
from odoo.addons.phone_validation.tools import phone_validation
from odoo.http import request
class MailingSMSController(http.Controller):
def _check_trace(self, mailing_id, trace_code):
try:
mailing = request.env['mailing.mailing'].sudo().search([('id', '=', mailing_id)])
except:
mailing = False
if not mailing:
return {'error': 'mailing_error'}
trace = request.env['mailing.trace'].sudo().search([
('trace_type', '=', 'sms'),
('sms_code', '=', trace_code),
('mass_mailing_id', '=', mailing.id)
])
if not trace:
return {'error': 'trace_error'}
return {'trace': trace}
@http.route(['/sms/<int:mailing_id>/<string:trace_code>'], type='http', website=True, auth='public')
def blacklist_page(self, mailing_id, trace_code, **post):
check_res = self._check_trace(mailing_id, trace_code)
if not check_res.get('trace'):
return request.redirect('/web')
return request.render('mass_mailing_sms.blacklist_main', {
'mailing_id': mailing_id,
'trace_code': trace_code,
})
@http.route(['/sms/<int:mailing_id>/unsubscribe/<string:trace_code>'], type='http', website=True, auth='public')
def blacklist_number(self, mailing_id, trace_code, **post):
check_res = self._check_trace(mailing_id, trace_code)
if not check_res.get('trace'):
return request.redirect('/web')
# parse and validate number
sms_number = post.get('sms_number', '').strip(' ')
sanitized = phone_validation.phone_format(
sms_number,
request.geoip.country_code,
force_format='E164',
raise_exception=False,
)
tocheck_number = sanitized or sms_number
trace = check_res['trace'].filtered(lambda r: r.sms_number == tocheck_number)[:1] if tocheck_number else False
# compute opt-out / blacklist information
lists_optout = request.env['mailing.list'].sudo()
lists_optin = request.env['mailing.list'].sudo()
unsubscribe_error = False
if tocheck_number and trace:
mailing_list_ids = trace.mass_mailing_id.contact_list_ids
if mailing_list_ids:
subscriptions = request.env['mailing.subscription'].sudo().search([
('list_id', 'in', mailing_list_ids.ids),
('contact_id.phone_sanitized', '=', tocheck_number),
])
subscriptions.write({'opt_out': True})
lists_optout = subscriptions.mapped('list_id')
else:
blacklist_rec = request.env['phone.blacklist'].sudo().add(tocheck_number)
blacklist_rec._message_log(
body=_('Blacklist through SMS Marketing unsubscribe (mailing ID: %s - model: %s)',
trace.mass_mailing_id.id, trace.mass_mailing_id.mailing_model_id.display_name))
lists_optin = request.env['mailing.subscription'].sudo().search([
('contact_id.phone_sanitized', '=', tocheck_number),
('list_id', 'not in', mailing_list_ids.ids),
('opt_out', '=', False),
]).mapped('list_id')
elif tocheck_number:
unsubscribe_error = _('Number %s not found', tocheck_number)
else:
unsubscribe_error = _('Invalid number %s', post.get('sms_number', ''))
return request.render('mass_mailing_sms.blacklist_number', {
'mailing_id': mailing_id,
'trace_code': trace_code,
'sms_number': sms_number,
'lists_optin': lists_optin,
'lists_optout': lists_optout,
'unsubscribe_error': unsubscribe_error,
})
@http.route('/r/<string:code>/s/<int:sms_id_int>', type='http', auth="public")
def sms_short_link_redirect(self, code, sms_id_int, **post):
if sms_id_int:
trace_id = request.env['mailing.trace'].sudo().search([('sms_id_int', '=', int(sms_id_int))]).id
else:
trace_id = False
request.env['link.tracker.click'].sudo().add_click(
code,
ip=request.httprequest.remote_addr,
country_code=request.geoip.country_code,
mailing_trace_id=trace_id
)
redirect_url = request.env['link.tracker'].get_url_from_code(code)
if not redirect_url:
raise NotFound()
return request.redirect(redirect_url, code=301, local=False)