Files
public/tier_communications/controllers/send_notification.py

157 lines
5.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import re
from odoo import http
from odoo.http import request
class TierSendNotificationController(http.Controller):
"""RPC endpoint for sending a message through an external channel.
Called from JS after message_post succeeds.
Returns a status dict that JS uses to show a toast notification.
"""
@http.route(
'/tier_communications/send_via_channel',
methods=['POST'],
type='jsonrpc',
auth='user',
)
def send_via_channel(self, message_id, channel_code, thread_model=None, thread_id=None):
"""Send an already-created mail.message through the specified external channel.
Returns:
{
'status': 'success' | 'error' | 'no_data',
'message': str, # human-readable status for the toast
}
"""
message = request.env['mail.message'].browse(message_id)
if not message.exists():
return {'status': 'error', 'message': 'Сообщение не найдено'}
if channel_code == 'email':
return _send_email(request.env, message, thread_model, thread_id)
elif channel_code == 'matrix':
return _send_matrix(request.env, message)
else:
return {'status': 'error', 'message': f'Неизвестный канал: {channel_code}'}
def _send_email(env, message, thread_model, thread_id):
"""Send message via email. Returns status dict."""
recipient_email = None
# 1. Thread partner_id
if thread_model and thread_id and thread_model not in ('mail.thread', 'discuss.channel'):
thread_record = env[thread_model].browse(thread_id)
if thread_record.exists() and hasattr(thread_record, 'partner_id'):
partner = thread_record.partner_id
if partner and partner.email:
recipient_email = partner.email
# 2. Message partner_ids
if not recipient_email and message.partner_ids:
for partner in message.partner_ids:
if partner.email:
recipient_email = partner.email
break
# 3. Last incoming message email_from
if not recipient_email and message.model and message.res_id:
last_incoming = env['mail.message'].search([
('model', '=', message.model),
('res_id', '=', message.res_id),
('message_type', 'in', ['email', 'comment']),
('email_from', '!=', False),
('author_id', '!=', env.user.partner_id.id),
], order='id desc', limit=1)
if last_incoming and last_incoming.email_from:
email_match = re.search(r'<([^>]+)>', last_incoming.email_from)
recipient_email = email_match.group(1) if email_match else last_incoming.email_from
# 4. discuss.channel other member
if not recipient_email and thread_model == 'discuss.channel' and thread_id:
channel = env['discuss.channel'].browse(thread_id)
if channel.exists():
other_members = channel.channel_member_ids.filtered(
lambda m: m.partner_id and m.partner_id != env.user.partner_id
)
for member in other_members:
if member.partner_id.email:
recipient_email = member.partner_id.email
break
if not recipient_email:
return {
'status': 'no_data',
'message': 'Не заполнен email получателя',
}
try:
mail_values = {
'subject': message.subject or 'Сообщение из Odoo',
'body_html': message.body or '',
'email_to': recipient_email,
'email_from': env.company.email or env.user.email or '',
'auto_delete': True,
}
outgoing_mail = env['mail.mail'].sudo().create(mail_values)
outgoing_mail.send()
return {
'status': 'success',
'message': f'Сообщение отправлено на {recipient_email}',
}
except Exception as send_error:
return {
'status': 'error',
'message': f'Ошибка отправки email: {send_error}',
}
def _send_matrix(env, message):
"""Send message via Matrix. Returns status dict."""
current_user = env.user
if not hasattr(current_user, 'tier_matrix_homeserver'):
return {
'status': 'no_data',
'message': 'Модуль Matrix не установлен',
}
homeserver_url = current_user.tier_matrix_homeserver
access_token = current_user.tier_matrix_access_token
room_id = current_user.tier_matrix_room_id
missing_fields = []
if not homeserver_url:
missing_fields.append('Homeserver URL')
if not access_token:
missing_fields.append('Access Token')
if not room_id:
missing_fields.append('Room ID')
if missing_fields:
return {
'status': 'no_data',
'message': f'Не заполнены данные Matrix: {", ".join(missing_fields)}',
}
if 'tier.channel.matrix.helper' not in env:
return {
'status': 'no_data',
'message': 'Модуль Matrix не установлен',
}
try:
env['tier.channel.matrix.helper'].channel_send_message(message, user=current_user)
return {
'status': 'success',
'message': f'Сообщение отправлено в Matrix (room: {room_id})',
}
except Exception as send_error:
return {
'status': 'error',
'message': f'Ошибка отправки Matrix: {send_error}',
}